Compare commits

..

80 Commits

Author SHA1 Message Date
jokob-sk
4bb87fe8df Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks failed
Code checks / check-url-paths (push) Has been cancelled
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
2025-04-13 10:29:20 +10:00
jokob-sk
71bcbbe7f9 fixes 2025-04-13 10:29:07 +10:00
Massimo Pissarello
f941133304 Translated using Weblate (Italian)
Some checks failed
Code checks / check-url-paths (push) Has been cancelled
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
Currently translated at 100.0% (743 of 743 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2025-04-11 07:07:45 +02:00
Jokob @NetAlertX
470997fcde Merge pull request #1045 from LeoRX/patch-1
Some checks are pending
Code checks / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Update DOCKER_COMPOSE.md
2025-04-11 10:43:27 +10:00
LeoRX
d6b2ac587f Update DOCKER_COMPOSE.md
Fix spelling
2025-04-11 09:47:18 +10:00
jokob-sk
e6962e0393 docs + auto lables on GH issues
Some checks failed
Code checks / check-url-paths (push) Has been cancelled
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
2025-04-06 10:48:27 +10:00
Jokob @NetAlertX
426dd48540 Update setup-help.yml 2025-04-06 10:39:58 +10:00
Jokob @NetAlertX
7da11d167d Update i-have-an-issue.yml 2025-04-06 10:38:39 +10:00
jokob-sk
40e090c5c6 docs 2025-04-06 09:38:23 +10:00
jokob-sk
3ccb165658 docs + code checks + deviceDetails delay 2025-04-06 08:40:25 +10:00
jokob-sk
a12da278c6 docs + #1042
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-04-05 08:04:31 +11:00
Jokob @NetAlertX
ffb0d0238d Merge pull request #1041 from Tlaloc-Es/patch-1
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Update manager.py
2025-04-04 19:43:15 +11:00
Joseba Fuentes
599603d9ff Update manager.py 2025-04-04 10:25:41 +02:00
Safeguard
befb58619b Translated using Weblate (Russian)
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Currently translated at 100.0% (743 of 743 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2025-04-04 02:33:44 +02:00
Safeguard
f83cdc766b Translated using Weblate (Russian)
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Currently translated at 100.0% (743 of 743 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2025-04-03 12:13:45 +02:00
jokob-sk
6fb1547fc4 wf work
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-04-03 07:52:50 +11:00
jokob-sk
ea9a07d29e Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2025-04-03 07:52:33 +11:00
jokob-sk
2889be28e4 wf work 2025-04-03 07:51:59 +11:00
Sylvain Pichon
46a8bb66e7 Translated using Weblate (French)
Some checks failed
URL Path Check / check-url-paths (push) Has been cancelled
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
Currently translated at 100.0% (743 of 743 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2025-04-01 10:18:08 +02:00
GitHub Actions
578a6d0d48 Add release tweet for v25.4.1 - 🔀 Workflows - automate device management
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-31 21:48:09 +00:00
jokob-sk
e1f9ca05b7 wf docs 2025-04-01 08:20:00 +11:00
Максим Горпиніч
4aaf86f0fc Translated using Weblate (Ukrainian)
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Currently translated at 100.0% (743 of 743 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/uk/
2025-03-31 13:27:45 +02:00
jokob-sk
9bb21ad303 wf docs 2025-03-31 18:46:55 +11:00
jokob-sk
e1197eb3f8 wf work + docs 2025-03-31 18:05:15 +11:00
jokob-sk
2c445ccaeb wf work + docs 2025-03-31 18:04:56 +11:00
jokob-sk
8a07f7067b Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-31 08:12:57 +11:00
jokob-sk
d86c2a5023 Move ObjectGUID to the end 2025-03-31 08:12:32 +11:00
Максим Горпиніч
2b51674e52 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (737 of 737 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/uk/
2025-03-30 19:39:24 +02:00
Sylvain Pichon
eb6820dd93 Translated using Weblate (French)
Currently translated at 100.0% (737 of 737 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2025-03-30 19:39:24 +02:00
Ettore Atalan
b156246cb0 Translated using Weblate (German)
Currently translated at 89.2% (658 of 737 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2025-03-30 19:39:24 +02:00
Hosted Weblate
716c6a4046 Merge branch 'origin/main' into Weblate.
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-30 08:30:09 +02:00
Massimo Pissarello
114b5a2621 Translated using Weblate (Italian)
Currently translated at 100.0% (737 of 737 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2025-03-30 08:30:09 +02:00
jokob-sk
02b19c833e Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2025-03-30 17:29:56 +11:00
jokob-sk
e0c06548ba wf work + fa upgrade + css cleanup + network tweaks 2025-03-30 17:29:22 +11:00
Anonymous
4d401f60dc Translated using Weblate (Portuguese (Brazil))
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Currently translated at 59.5% (439 of 737 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2025-03-30 07:23:31 +02:00
Hosted Weblate
391be9a49d Merge branch 'origin/main' into Weblate. 2025-03-29 23:25:54 +00:00
Sylvain Pichon
587fb6036c Translated using Weblate (French)
Currently translated at 100.0% (719 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2025-03-29 23:25:52 +00:00
jokob-sk
2d4ca7e8ae Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2025-03-30 10:25:29 +11:00
jokob-sk
3f74173245 wf work 2025-03-30 10:25:03 +11:00
Максим Горпиніч
e35a3578dd Translated using Weblate (Ukrainian)
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Currently translated at 100.0% (719 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/uk/
2025-03-29 08:51:03 +01:00
Максим Горпиніч
e957453d33 Translated using Weblate (Ukrainian)
Currently translated at 99.7% (717 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/uk/
2025-03-29 07:58:04 +01:00
Anonymous
3c31a85a68 Translated using Weblate (Catalan)
Currently translated at 99.5% (716 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ca/
2025-03-29 07:58:03 +01:00
Anonymous
7054c44976 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 86.7% (624 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/zh_Hans/
2025-03-29 07:58:03 +01:00
Anonymous
0110675806 Translated using Weblate (Polish)
Currently translated at 86.9% (625 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pl/
2025-03-29 07:58:03 +01:00
Anonymous
a4ecd7f571 Translated using Weblate (Portuguese (Brazil))
Currently translated at 61.7% (444 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2025-03-29 07:58:03 +01:00
Anonymous
b671abd93f Translated using Weblate (Italian)
Currently translated at 99.5% (716 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2025-03-29 07:58:03 +01:00
Anonymous
67db3c1582 Translated using Weblate (Russian)
Currently translated at 99.5% (716 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2025-03-29 07:58:02 +01:00
Anonymous
f25d6c18e5 Translated using Weblate (Norwegian Bokmål)
Currently translated at 86.5% (622 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/nb_NO/
2025-03-29 07:58:02 +01:00
Anonymous
e5f7698461 Translated using Weblate (French)
Currently translated at 99.5% (716 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2025-03-29 07:58:02 +01:00
Anonymous
371e996a25 Translated using Weblate (Spanish)
Currently translated at 95.8% (689 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2025-03-29 07:58:01 +01:00
Anonymous
20342ed0b5 Translated using Weblate (German)
Currently translated at 89.7% (645 of 719 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2025-03-29 07:58:01 +01:00
jokob-sk
5d01af1758 wf work 2025-03-29 17:21:29 +11:00
jokob-sk
a0561b2016 wf work 2025-03-29 17:03:59 +11:00
jokob-sk
f2e218230e SQL query fix
Some checks are pending
URL Path Check / check-url-paths (push) Waiting to run
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-29 12:55:24 +11:00
Jokob @NetAlertX
e25c471626 Merge pull request #1029 from jokob-sk/next_release
Next release - Workflow work
2025-03-29 12:47:56 +11:00
jokob-sk
76419db0e3 wf work 2025-03-29 12:46:27 +11:00
jokob-sk
929964f9e2 wf work 2025-03-29 12:31:29 +11:00
jokob-sk
7e5373b2cd wf work 2025-03-27 21:23:11 +11:00
jokob-sk
3b869f5365 stop devParentMAC overwrite if specified #1021
Some checks failed
URL Path Check / check-url-paths (push) Has been cancelled
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
2025-03-23 15:24:47 +11:00
jokob-sk
e996c9eccc stop devParentMAC overwrite if specified #1021 2025-03-23 15:24:01 +11:00
jokob-sk
393904c91f stop devParentMAC overwrite if specified #1021 2025-03-23 15:12:07 +11:00
jokob-sk
8d9a4d23d1 stop devParentMAC overwrite if specified #1021 2025-03-23 13:23:39 +11:00
jokob-sk
4092452363 wf work 2025-03-22 19:17:52 +11:00
jokob-sk
2b61665ee8 github actions
Some checks failed
URL Path Check / check-url-paths (push) Has been cancelled
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
2025-03-22 10:48:58 +11:00
jokob-sk
6c28926e39 incorrect starter app.conf LOADED_PLUGINS #1023 2025-03-22 10:47:12 +11:00
jokob-sk
af4beb9f58 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2025-03-22 10:33:02 +11:00
jokob-sk
e55c561e55 ICMP quotes #1025 2025-03-22 10:32:32 +11:00
jokob-sk
0d4185731c wf work 2025-03-22 10:30:26 +11:00
Jokob @NetAlertX
0b6de5545b Merge pull request #1024 from cvc90/cvc90-update-front-userNotifications-urls
Changing absolute path URL to relative path URL in userNotifications.php
2025-03-22 08:48:20 +11:00
Carlos V.
9d04f943bc Update userNotifications.php
Updated “absolute” URLs to “relative” URLs for correct operation through proxys.
2025-03-21 19:01:42 +01:00
jokob-sk
038a6a63eb wf work 2025-03-21 06:29:31 +11:00
Jokob @NetAlertX
6f8b2f5071 Merge pull request #1022 from cvc90/cvc90-update-front-devices-urls
Some checks are pending
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
Changing absolute path URL to relative path URL in devices.php
2025-03-21 06:24:12 +11:00
Carlos V.
fd9695c743 Update devices.php
Updated “absolute” URLs to “relative” URLs for correct operation through proxys.
2025-03-20 17:14:40 +01:00
jokob-sk
ba300f7023 stop devParentMAC overwrite if specified #1021
Some checks are pending
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-20 11:12:29 +11:00
jokob-sk
fe722a5caa MQTT #1019
Some checks failed
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
2025-03-18 06:36:18 +11:00
jokob-sk
1aaa22c178 OPENWRT/LUCI #1010
Some checks failed
docker / docker_dev (push) Has been cancelled
Deploy MkDocs / deploy (push) Has been cancelled
2025-03-16 07:54:03 +11:00
jokob-sk
60a1349be5 OPENWRT/LUCI #1010
Some checks are pending
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-15 08:52:46 +11:00
jokob-sk
b99f949363 MQTT #1019 2025-03-15 08:13:14 +11:00
Jokob @NetAlertX
8de6749ce3 Update docker_dev.yml
Some checks are pending
docker / docker_dev (push) Waiting to run
Deploy MkDocs / deploy (push) Waiting to run
2025-03-10 07:38:52 +11:00
GoldBull3t
95345518a1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 62.0% (445 of 717 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2025-03-02 17:08:53 +01:00
110 changed files with 2157 additions and 2470 deletions

View File

@@ -1,6 +1,6 @@
name: Feature Request
description: 'Suggest an idea for NetAlertX'
labels: ['Feature request']
labels: ['Feature request ']
body:
- type: checkboxes
attributes:

View File

@@ -59,12 +59,15 @@ body:
validations:
required: false
- type: dropdown
id: installation_type
attributes:
label: What installation are you running?
options:
- Production (netalertx)
- Dev (netalertx-dev)
- Home Assistant (addon)
- Home Assistant fa (full-access addon)
- Bare-metal (community only support - Check Discord)
validations:
required: true
- type: textarea

View File

@@ -44,12 +44,15 @@ body:
validations:
required: false
- type: dropdown
id: installation_type
attributes:
label: What installation are you running?
options:
- Production (netalertx)
- Dev (netalertx-dev)
- Home Assistant (addon)
- Home Assistant fa (full-access addon)
- Bare-metal (community only support - Check Discord)
validations:
required: true
- type: textarea

2
.github/tweet.md vendored Executable file
View File

@@ -0,0 +1,2 @@
🎉 New release: **v25.4.1 - 🔀 Workflows - automate device management ** is live! 🚀
Check it out here: https://github.com/jokob-sk/NetAlertX/releases/tag/v25.4.1

33
.github/workflows/code_checks.yml vendored Executable file
View File

@@ -0,0 +1,33 @@
name: Code checks
on:
push:
branches:
- main
tags:
- '*.*.*'
pull_request:
branches:
- main
jobs:
check-url-paths:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for absolute path URLs
run: |
if grep -r -E "\burl:\s*['\"]\/php" --include=\*.{js,php} .; then
echo "❌ Found absolute path URLs starting with '/php/'. Please use relative paths."
exit 1
else
echo "✅ No absolute path URLs found."
fi
- name: Check Python syntax
run: |
set -e
echo "🔍 Checking Python syntax..."
find . -name "*.py" -print0 | xargs -0 -n1 python3 -m py_compile

43
.github/workflows/label-issues.yml vendored Executable file
View File

@@ -0,0 +1,43 @@
name: Label Issues by Installation Type
on:
issues:
types: [opened]
permissions:
issues: write
jobs:
add-label:
runs-on: ubuntu-latest
steps:
- name: Get issue content
uses: actions/github-script@v7
with:
script: |
const body = context.payload.issue.body;
const lowerBody = body.toLowerCase();
let labelsToAdd = [];
if (lowerBody.includes('bare-metal')) {
labelsToAdd.push('bare-metal ❗');
}
if (lowerBody.includes('home assistant')) {
labelsToAdd.push('Home Assistant 🏠');
}
if (lowerBody.includes('production (netalertx)') || lowerBody.includes('dev (netalertx-dev)')) {
labelsToAdd.push('Docker 🐋');
}
if (labelsToAdd.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: labelsToAdd
});
}

View File

@@ -41,6 +41,10 @@ Send notifications to more than 80+ services, including Telegram via [Apprise](h
Feed your data and device changes into [Home Assistant](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HOME_ASSISTANT.md), read [API endpoints](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md), or use [Webhooks](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md) to setup custom automation flows. You can also
build your own scanners with the [Plugin system](https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md#readme) in as little as [15 minutes](https://www.youtube.com/watch?v=cdbxlwiWhv8).
### Workflows
The [workflows module](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WORKFLOWS.md) in NetAlertX allows to automate repetitive tasks, making network management more efficient. Whether you need to assign newly discovered devices to a specific Network Node, auto-group devices from a given vendor, unarchive a device if detected online, or automatically delete devices, this module provides the flexibility to tailor the automations to your needs.
## 📚 Documentation
<!--- --------------------------------------------------------------------- --->

View File

@@ -20,7 +20,7 @@
DISCOVER_PLUGINS=True
SCAN_SUBNETS=['192.168.1.0/24 --interface=eth0']
TIMEZONE='Europe/Berlin'
LOADED_PLUGINS = ['ARPSCAN','CSVBCKP','DBCLNP', 'INTRNT','MAINT','NEWDEV','NSLOOKUP','NTFPRCS', 'AVAHISCAN', 'SETPWD','SMTP', 'SYNC', 'VNDRPDT', 'WORKFLOWS', 'UI']
LOADED_PLUGINS=['ARPSCAN','CSVBCKP','DBCLNP', 'INTRNT','MAINT','NEWDEV','NSLOOKUP','NTFPRCS', 'AVAHISCAN', 'SETPWD','SMTP', 'SYNC', 'VNDRPDT', 'WORKFLOWS', 'UI']
DAYS_TO_KEEP_EVENTS=90
# Used for generating links in emails. Make sure not to add a trailing slash!

View File

@@ -1,55 +0,0 @@
[
{
"name": "Sample Device Update Workflow",
"trigger": {
"object_type": "Devices",
"event_type": "update"
},
"conditions": [
{
"logic": "AND",
"conditions": [
{
"field": "devVendor",
"operator": "contains",
"value": "Google"
},
{
"field": "devIsNew",
"operator": "equals",
"value": "1"
},
{
"logic": "OR",
"conditions": [
{
"field": "devIsNew",
"operator": "equals",
"value": "1"
},
{
"field": "devName",
"operator": "contains",
"value": "Google"
}
]
}
]
}
],
"actions": [
{
"type": "update_field",
"field": "devIsNew",
"value": "0"
},
{
"type": "run_plugin",
"plugin": "SMTP",
"params": {
"message": "New device from Google detected."
}
}
]
}
]

View File

@@ -37,7 +37,6 @@ export INSTALL_DIR=/app # Specify the installation directory here
# DO NOT CHANGE ANYTHING BELOW THIS LINE!
CONF_FILE="app.conf"
WF_FILE="workflows.json"
NGINX_CONF_FILE=netalertx.conf
DB_FILE="app.db"
FULL_FILEDB_PATH="${INSTALL_DIR}/db/${DB_FILE}"
@@ -97,9 +96,8 @@ fi
echo "[INSTALL] Copy starter ${DB_FILE} and ${CONF_FILE} if they don't exist"
# Copy starter app.db, app.conf, workflows.json if they don't exist
# Copy starter app.db, app.conf if they don't exist
cp -na "${INSTALL_DIR}/back/${CONF_FILE}" "${INSTALL_DIR}/config/${CONF_FILE}"
cp -na "${INSTALL_DIR}/back/${WF_FILE}" "${INSTALL_DIR}/config/${WF_FILE}"
cp -na "${INSTALL_DIR}/back/${DB_FILE}" "${FULL_FILEDB_PATH}"
# if custom variables not set we do not need to do anything

View File

@@ -4,20 +4,21 @@
> To backup 99% of your configuration backup at least the `/app/config` folder. Please read the whole page (or at least "Scenario 2: Corrupted database") for details.
> Note that database definitions might change over time. The safest way is to restore your older backups into the **same version** of the app they were taken from and then gradually upgarde between releases to the latest version.
There are 3 artifacts that can be used to backup the application:
There are 4 artifacts that can be used to backup the application:
| File | Description | Limitations |
|-----------------------|-------------------------------|-------------------------------|
| `/db/app.db` | Database file(s) | The database file might be in an uncommitted state or corrupted |
| `/config/app.conf` | Configuration file | Can be overridden with the [`APP_CONF_OVERRIDE` env variable](https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles#docker-environment-variables). |
| `/config/devices.csv` | CSV file containing device information | Doesn't contain historical data |
| `/config/workflows.json` | A JSON file containing your workflows | N/A |
## Backup strategies
The safest approach to backups is to backup everything, by taking regular file system backups (I use [Kopia](https://github.com/kopia/kopia)).
The safest approach to backups is to backup everything, by taking regular file system backups of the `/db` and `/config` folders (I use [Kopia](https://github.com/kopia/kopia)).
Arguably, the most time is spent setting up the device list, so if only one file is kept I'd recommend to have a latest backup of the `devices_<timestamp>.csv` or `devices.csv` file, followed by the `app.conf` file. You can also download `app.conf` and `devices.csv` file in the Maintenance section:
Arguably, the most time is spent setting up the device list, so if only one file is kept I'd recommend to have a latest backup of the `devices_<timestamp>.csv` or `devices.csv` file, followed by the `app.conf` and `workflows.json` files. You can also download `app.conf` and `devices.csv` file in the Maintenance section:
![Backup and Restore Section in Maintenance](./img/BACKUPS/Maintenance_Backup_Restore.png)
@@ -29,6 +30,7 @@ End-result: Full restore
- `/app/db/app.db` (uncorrupted)
- `/app/config/app.conf`
- `/app/config/workflows.json`
#### 📥 Recovery:
@@ -43,12 +45,13 @@ End-result: Partial restore (historical data and some plugin data will be missin
- `/app/config/app.conf`
- `/app/config/devices_<timestamp>.csv` or `/app/config/devices.csv`
- `/app/config/workflows.json`
#### 📥 Recovery:
Even with a corrupted database you can recover what I would argue is 99% of the configuration.
- upload the `app.conf` file into the mounted `/app/config/` folder as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
- upload the `app.conf` and `workflows.json` files into the mounted `/app/config/` folder as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
- rename the `devices_<timestamp>.csv` to `devices.csv` and place it in the `/app/config` folder
- Restore the `devices.csv` backup via the [Maintenance section](./DEVICES_BULK_EDITING.md)

View File

@@ -4,7 +4,7 @@
## Overview
This functionality allows you to define **custom properties** for devices, which can store and display additional information on the device listing page. By marking properties as visible, you can enhance the user interface with quick actions, notes, or external links.
This functionality allows you to define **custom properties** for devices, which can store and display additional information on the device listing page. By marking properties as "Show", you can enhance the user interface with quick actions, notes, or external links.
### Key Features:
- **Customizable Properties**: Define specific properties for each device.
@@ -63,10 +63,10 @@ Visible properties (`CUSTPROP_show: true`) are displayed as interactive icons in
---
## Example Scenarios
## Example Use Cases
1. **Device Documentation Link**:
- Add a custom property with `CUSTPROP_type` set to `link` or `link_new_tab` to allow quick navigation to the documentation.
- Add a custom property with `CUSTPROP_type` set to `link` or `link_new_tab` to allow quick navigation to the external documentation of the device.
2. **Firmware Details**:
- Use `CUSTPROP_type: show_notes` to display firmware versions or upgrade instructions in a modal.

View File

@@ -1,11 +1,53 @@
# A high-level description of the database structure
⚠ Disclaimer: As I'm not the original author, some of the information might be inaccurate. Feel free to submit a PR to correct anything within this page or documentation in general.
An overview of the most important database tables as well as an detailed overview of the Devices table. The MAC address is used as a foreign key in most cases.
The MAC address is used as a foreign key in most cases.
## Devices database table
## 🔍Tables overview
| Field Name | Description | Sample Value |
|-------------------------|-------------|--------------|
| `devMac` | MAC address of the device. | `00:1A:2B:3C:4D:5E` |
| `devName` | Name of the device. | `iPhone 12` |
| `devOwner` | Owner of the device. | `John Doe` |
| `devType` | Type of the device (e.g., phone, laptop, etc.). If set to a network type (e.g., switch), it will become selectable as a Network Parent Node. | `Laptop` |
| `devVendor` | Vendor/manufacturer of the device. | `Apple` |
| `devFavorite` | Whether the device is marked as a favorite. | `1` |
| `devGroup` | Group the device belongs to. | `Home Devices` |
| `devComments` | User comments or notes about the device. | `Used for work purposes` |
| `devFirstConnection` | Timestamp of the device's first connection. | `2025-03-22 12:07:26+11:00` |
| `devLastConnection` | Timestamp of the device's last connection. | `2025-03-22 12:07:26+11:00` |
| `devLastIP` | Last known IP address of the device. | `192.168.1.5` |
| `devStaticIP` | Whether the device has a static IP address. | `0` |
| `devScan` | Whether the device should be scanned. | `1` |
| `devLogEvents` | Whether events related to the device should be logged. | `0` |
| `devAlertEvents` | Whether alerts should be generated for events. | `1` |
| `devAlertDown` | Whether an alert should be sent when the device goes down. | `0` |
| `devSkipRepeated` | Whether to skip repeated alerts for this device. | `1` |
| `devLastNotification` | Timestamp of the last notification sent for this device. | `2025-03-22 12:07:26+11:00` |
| `devPresentLastScan` | Whether the device was present during the last scan. | `1` |
| `devIsNew` | Whether the device is marked as new. | `0` |
| `devLocation` | Physical or logical location of the device. | `Living Room` |
| `devIsArchived` | Whether the device is archived. | `0` |
| `devParentMAC` | MAC address of the parent device (if applicable) to build the [Network Tree](./NETWORK_TREE.md). | `00:1A:2B:3C:4D:5F` |
| `devParentPort` | Port of the parent device to which this device is connected. | `Port 3` |
| `devIcon` | [Icon](./ICONS.md) representing the device. The value is a base64-encoded SVG or Font Awesome HTML tag. | `PHN2ZyB...` |
| `devGUID` | Unique identifier for the device. | `a2f4b5d6-7a8c-9d10-11e1-f12345678901` |
| `devSite` | Site or location where the device is registered. | `Office` |
| `devSSID` | SSID of the Wi-Fi network the device is connected to. | `HomeNetwork` |
| `devSyncHubNode` | The NetAlertX node ID used for synchronization between NetAlertX instances. | `node_1` |
| `devSourcePlugin` | Source plugin that discovered the device. | `ARPSCAN` |
| `devCustomProps` | [Custom properties](./CUSTOM_PROPERTIES.md) related to the device. The value is a base64-encoded JSON object. | `PHN2ZyB...` |
To understand how values of these fields influuence application behavior, such as Notifications or Network topology, see also:
- [Device Management](./DEVICE_MANAGEMENT.md)
- [Network Tree Topology Setup](./NETWORK_TREE.md)
- [Notifications](./NOTIFICATIONS.md)
## Other Tables overview
| Table name | Description | Sample data |
|----------------------|----------------------| ----------------------|

View File

@@ -2,7 +2,7 @@
## High-level overview
If a Plugin supplies data to the main app it's doine either vie a SQL query or via a script that updates the `last_result.log` file in the plugin folder (`front/plugins/<plugin>`).
If a Plugin supplies data to the main app it's done either vie a SQL query or via a script that updates the `last_result.log` file in the plugin log folder (`app/log/plugins/`).
For a more in-depth overview on how plugins work check the [Plugins development docs](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md).

View File

@@ -1,35 +1,38 @@
## Development environment set up
# Development environment set up
>[!NOTE]
> Replace `/development` with the path where your code files will be stored. The default container name is `netalertx` so there might be a conflict with your running containers.
### Development Guidelines
## Development Guidelines
**Priority Order (Highest to Lowest):**
Before starting development, please scan the below development guidelines.
### Priority Order (Highest to Lowest)
1. 🔼 Fixing core bugs that lack workarounds.
2. 🔵 Adding core functionality that unlocks other features (e.g., plugins).
3. 🔵 Refactoring to enable faster development.
4. 🔽 UI improvements (PRs welcome).
💡 **Design Philosophy:**
### Design Philosophy
Focus on core functionality and integrate with existing tools rather than reinventing the wheel.
Examples:
- Using **Apprise** for notifications instead of implementing multiple separate gateways.
- Implementing **regex-based validation** instead of one-off validation for each setting.
📌 **Note on UI requests:**
> [!NOTE]
> UI changes have lower priority, however, PRs are welcome, but **keep them small & focused**.
- UI changes have lower priority due to framework limitations and mobile support constraints.
- PRs are welcome, but **keep them small & focused**.
## Development Environment Set Up
## 1. Download the code:
### 1. Download the code:
- `mkdir /development`
- `cd /development && git clone https://github.com/jokob-sk/NetAlertX.git`
## 2. Create a DEV .env_dev file
### 2. Create a DEV .env_dev file
`touch /development/.env_dev && sudo nano /development/.env_dev`
@@ -43,10 +46,12 @@ TZ=Europe/Berlin
PORT=22222 # make sure this port is unique on your whole network
DEV_LOCATION=/development/NetAlertX
APP_DATA_LOCATION=/volume/docker_appdata
# Make sure your GRAPHQL_PORT setting has a port that is unique on your whole host network
APP_CONF_OVERRIDE={"GRAPHQL_PORT":"22223"}
# ALWAYS_FRESH_INSTALL=true # uncommenting this will always delete the content of /config and /db dirs on boot to simulate a fresh install
```
## 3. Create /db and /config dirs
### 3. Create /db and /config dirs
Create a folder `netalertx` in the `APP_DATA_LOCATION` (in this example in `/volume/docker_appdata`) with 2 subfolders `db` and `config`.
@@ -54,7 +59,7 @@ Create a folder `netalertx` in the `APP_DATA_LOCATION` (in this example in `/vol
- `mkdir /volume/docker_appdata/netalertx/db`
- `mkdir /volume/docker_appdata/netalertx/config`
## 4. Run the container
### 4. Run the container
- `cd /development/NetAlertX && sudo docker-compose --env-file ../.env_dev `
@@ -63,7 +68,7 @@ You can then modify the python script without restarting/rebuilding the containe
![image](https://github.com/jokob-sk/NetAlertX/assets/96159884/3cbf2748-03c8-49e7-b801-f38c7755246b)
## 💡 Tips
## Tips
A quick cheat sheet of useful commands.
@@ -75,9 +80,9 @@ A command to stop, remove the container and the image (replace `netalertx` and `
### Restart the server backend
Most code changes can be tetsed without rebuilding the container. When working on the python server backend, you only need to restart the server.
Most code changes can be tested without rebuilding the container. When working on the python server backend, you only need to restart the server.
1. You can usually restart the backend via Maintenance > Logs > Restart server
1. You can usually restart the backend via _Maintenance > Logs > Restart_ server
![image](./img/DEV_ENV_SETUP/Maintenance_Logs_Restart_server.png)
@@ -86,11 +91,13 @@ Most code changes can be tetsed without rebuilding the container. When working o
- `sudo docker exec -it netalertx /bin/bash`
- `pkill -f "python /app/server" && python /app/server & `
3. If none of the above work, restart the docker image. This is usually the last resort as sometimes the Docker engine becomes unresponsive and the whole engine needs to be restarted.
3. If none of the above work, restart the docker caontainer.
## Contributing & Pull Requests
- This is usually the last resort as sometimes the Docker engine becomes unresponsive and the whole engine needs to be restarted.
**Before submitting a PR, please ensure:**
## Contributing & Pull Requests
### Before submitting a PR, please ensure:
✔ Changes are **backward-compatible** with existing installs.
✔ No unnecessary changes are made.

View File

@@ -1,5 +1,8 @@
# `docker-compose.yaml` Examples
> [!NOTE]
> The container needs to run in `network_mode:"host"`. This also means that not all functionality is supported on a Windows host as Docker for Windows doesn't support this networking option.
### Example 1
```yaml
@@ -100,3 +103,37 @@ DEV_LOCATION=/path/to/local/source/code
```
To run the container execute: `sudo docker-compose --env-file /path/to/.env up`
### Example 4: Docker swarm
Notice how the host network is defined in a swarm setup:
```yaml
services:
netalertx:
# Use the below line if you want to test the latest dev image
# image: "jokobsk/netalertx-dev:latest"
image: "ghcr.io/jokob-sk/netalertx:latest"
volumes:
- /mnt/MYSERVER/netalertx/config:/config:rw
- /mnt/MYSERVER/netalertx/db:/netalertx/db:rw
- /mnt/MYSERVER/netalertx/logs:/netalertx/front/log:rw
environment:
- TZ=Europe/London
- PORT=20211
networks:
- outside
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
networks:
outside:
external:
name: "host"
```

View File

@@ -3,7 +3,7 @@
NetAlertX comes with MQTT support, allowing you to show all detected devices as devices in Home Assistant. It also supplies a collection of stats, such as number of online devices.
> [!TIP]
> You can install NetAlertX also as a Home Assistant addon [![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant&style=for-the-badge&color=0aa8d2&logoColor=fff&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) via the [alexbelgium/hassio-addons](https://github.com/alexbelgium/hassio-addons/). This is only possible if you run a supervised instance of Home Assistant. If not, you can still run NetAlertX in a separate Docker container and follow this guide to configure MQTT.
> You can install NetAlertX also as a Home Assistant addon [![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant&style=for-the-badge&color=0aa8d2&logoColor=fff&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) via the [alexbelgium/hassio-addons](https://github.com/alexbelgium/hassio-addons/) repository. This is only possible if you run a supervised instance of Home Assistant. If not, you can still run NetAlertX in a separate Docker container and follow this guide to configure MQTT.
## ⚠ Note
@@ -49,3 +49,44 @@ NetAlertX comes with MQTT support, allowing you to show all detected devices as
[list]: ./img/HOME_ASISSTANT/HomeAssistant-Devices-List.png "list"
[overview]: ./img/HOME_ASISSTANT/HomeAssistant-Overview-Card.png "overview"
## Troubleshooting
If you can't see all devices detected, run `sudo arp-scan --interface=eth0 192.168.1.0/24` (change these based on your setup, read [Subnets](./SUBNETS.md) docs for details). This command has to be executed the NetAlertX container, not in the Home Assistant container.
You can access the NetAlertX container via Portainer on your host or via ssh. The container name will be something like `addon_db21ed7f_netalertx` (you can copy the `db21ed7f_netalertx` part from the browser when accessing the UI of NetAlertX).
## Accessing the NetAlertX container via SSH
1. Log into your Home Assistant host via SSH
```bash
local@local:~ $ ssh pi@192.168.1.9
```
2. Find the NetAlertX container name, in this case `addon_db21ed7f_netalertx`
```bash
pi@raspberrypi:~ $ sudo docker container ls | grep netalertx
06c540d97f67 ghcr.io/alexbelgium/netalertx-armv7:25.3.1 "/init" 6 days ago Up 6 days (healthy) addon_db21ed7f_netalertx
```
3. SSH into the NetAlertX cointainer
```bash
pi@raspberrypi:~ $ sudo docker exec -it addon_db21ed7f_netalertx /bin/sh
/ #
```
4. Execute a test `asrp-scan` scan
```bash
/ # sudo arp-scan --ignoredups --retry=6 192.168.1.0/24 --interface=eth0
Interface: eth0, type: EN10MB, MAC: dc:a6:32:73:8a:b1, IPv4: 192.168.1.9
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.1.1 74:ac:b9:54:09:fb Ubiquiti Networks Inc.
192.168.1.21 74:ac:b9:ad:c3:30 Ubiquiti Networks Inc.
192.168.1.58 1c:69:7a:a2:34:7b EliteGroup Computer Systems Co., LTD
192.168.1.57 f4:92:bf:a3:f3:56 Ubiquiti Networks Inc.
...
```
If your result doesn't contain results similar to the above, double check your subnet, interface and if you are dealing with an inaccessible network segment, read the [Remote networks documentation](./REMOTE_NETWORKS.md).

View File

@@ -2,7 +2,7 @@
## Installation options
NetAlertX can be installed several ways. The best supported option is Docker, followed by a supervised the Home Assistant instance, as an Unraid app and lastly on bare metal.
NetAlertX can be installed several ways. The best supported option is Docker, followed by a supervised Home Assistant instance, as an Unraid app, and lastly, on bare metal.
- [[Installation] Docker (recommended)](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md)
- [[Installation] Home Assistant](https://github.com/alexbelgium/hassio-addons/tree/master/netalertx)

26
docs/LOGGING.md Executable file
View File

@@ -0,0 +1,26 @@
# Logging
NetAlertX comes with several logs that help to identify application issues.
For plugin-specific log debugging, please read the [Debug Plugins](./DEBUG_PLUGINS.md) guide.
When debugging any issue, increase the `LOG_LEVEL` Setting as per the [Debug tips](./DEBUG_TIPS.md) documentation.
## Main logs
You can find most of the logs exposed in the UI under _Maintenance -> Logs_.
If the UI is inaccessible, you can access them under `/app/log`.
![Logs](./img/LOGGING/maintenance_logs.png)
In the _Maintennace -> Logs_ you can **Purge logs**, download the full log file or Filter the lines with some substring to narrow down your search.
## Plugin logging
If a Plugin supplies data to the main app it's done either vie a SQL query or via a script that updates the `last_result.log` file in the plugin log folder (`app/log/plugins/`). These files are processed at the end of the scan and deleted on successful processing.
The data is in most of the cases then displayed in the application under _Integrations -> Plugins_ (or _Device -> Plugins_ if the plugin is supplying device-specific data).
![Plugin objects](./img/LOGGING/logging_integrations_plugins.png)

View File

@@ -43,14 +43,13 @@ The application installation folder in the docker container has changed from `/h
# Examples
Exmaples of docker files with the new mount points.
Examples of docker files with the new mount points.
## Example 1: Mapping folders
### Old docker-compose.yml
```yaml
version: "3"
services:
pialert:
container_name: pialert
@@ -72,7 +71,6 @@ services:
### New docker-compose.yml
```yaml
version: "3"
services:
netalertx: # ⚠ This has changed (🟡optional)
container_name: netalertx # ⚠ This has changed (🟡optional)
@@ -100,7 +98,6 @@ services:
### Old docker-compose.yml
```yaml
version: "3"
services:
pialert:
container_name: pialert
@@ -122,7 +119,6 @@ services:
### New docker-compose.yml
```yaml
version: "3"
services:
netalertx: # ⚠ This has changed (🟡optional)
container_name: netalertx # ⚠ This has changed (🟡optional)

47
docs/NAME_RESOLUTION.md Executable file
View File

@@ -0,0 +1,47 @@
# Device Name Resolution
Name resolution in NetAlertX relies on multiple plugins to resolve device names from IP addresses. If you are seeing `(name not found)` as device names, follow these steps to diagnose and fix the issue.
## Required Plugins
For best results, ensure the following name resolution plugins are enabled:
- **AVAHISCAN** Uses mDNS/Avahi to resolve local network names.
- **NBTSCAN** Queries NetBIOS to find device names.
- **NSLOOKUP** Performs standard DNS lookups.
You can check which plugins are active in your _Settings_ section and enable any that are missing.
There are other plugins that can supply device names as well, but they rely on bespoke hardware and services. See [Plugins overview](./PLUGINS.md) for details and look for plugins with name discovery (🆎) features.
## Checking Logs
If names are not resolving, check the logs for errors or timeouts.
See how to explore logs in the [Logging guide](./LOGGING.md).
Logs will show which plugins attempted resolution and any failures encountered.
## Adjusting Timeout Settings
If resolution is slow or failing due to timeouts, increase the timeout settings in your configuration, for example.
```ini
NSLOOKUP_RUN_TIMEOUT = 30
```
Raising the timeout may help if your network has high latency or slow DNS responses.
## Checking Plugin Objects
Each plugin stores results in its respective object. You can inspect these objects to see if they contain valid name resolution data.
See [Logging guide](./LOGGING.md) and [Debug plugins](./DEBUG_PLUGINS.md) guides for details.
If the object contains no results, the issue may be with DNS settings or network access.
## Improving name resolution
For more details how to improve name resolution refer to the
[Reverse DNS Documentation](./REVERSE_DNS.md).

View File

@@ -17,10 +17,13 @@ There are 4 ways how to influence notifications:
There are 4 settings on the device for influencing notifications. You can:
1. **Alert Events** - Enables alerts of connections, disconnections, IP changes.
2. **Alert Down** - Alerts when a device goes down. This setting overrides a disabled **Alert Events** setting, so you will get a notification of a device going down even if you don't have **Alert Events** ticked.
1. **Alert Events** - Enables alerts of connections, disconnections, IP changes (down and down reconnected notifications are still sent even if this is disabled).
2. **Alert Down** - Alerts when a device goes down. This setting overrides a disabled **Alert Events** setting, so you will get a notification of a device going down even if you don't have **Alert Events** ticked. Disabling this will disable down and down reconnected notifications on the device.
3. **Skip repeated notifications**, if for example you know there is a temporary issue and want to pause the same notification for this device for a given time.
> [!NOTE]
> Please read through the [NTFPRCS plugin](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/notification_processing/README.md) documentation to understand how device and global settings influence the notification processing.
## Plugin settings 🔌
![Plugin notification settings](./img/NOTIFICATIONS/Plugin-notification-settings.png)
@@ -38,7 +41,7 @@ Click the **Read more in the docs.** Link at the top of each plugin to get more
In Notification Processing settings, you can specify blanket rules. These allow you to specify exceptions to the Plugin and Device settings and will override those.
1. Notify on (`NTFPRCS_INCLUDED_SECTIONS`) allows you to specify which events trigger notifications. Usual setups will have `new_devices`, `down_devices`, and possibly `down_reconnected` set. Including `plugin` (dependenton the Plugin `<plugin>_WATCH` and `<plugin>_REPORT_ON` settings) and `events` (dependent on the on-device **Alert Events** setting) might be too noisy for most setups. More info in the [NTFPRCS plugin](/front/plugins/notification_processing/README.md)
1. Notify on (`NTFPRCS_INCLUDED_SECTIONS`) allows you to specify which events trigger notifications. Usual setups will have `new_devices`, `down_devices`, and possibly `down_reconnected` set. Including `plugin` (dependenton the Plugin `<plugin>_WATCH` and `<plugin>_REPORT_ON` settings) and `events` (dependent on the on-device **Alert Events** setting) might be too noisy for most setups. More info in the [NTFPRCS plugin](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/notification_processing/README.md) on what events these selections include.
2. Alert down after (`NTFPRCS_alert_down_time`) is useful if you want to wait for some time before the system sends out a down notification for a device. This is related to the on-device **Alert down** setting and only devices with this checked will trigger a down notification.
3. A filter to allow you to set device-specific exceptions to New devices being added to the app.
4. A filter to allow you to set device-specific exceptions to generated Events.

View File

@@ -8,17 +8,38 @@ NetAlertX supports additional plugins to extend its functionality, each with its
## ⚡ Quick start
> [!TIP]
> You can load additional Plugins via the General -> `LOADED_PLUGINS` setting.
> You can load additional Plugins via the General -> `LOADED_PLUGINS` setting. You need to save the settings for the new plugins to load (cache/page reload may be necessary).
> ![Loaded plugins settings](./img/PLUGINS/loaded_plugins_setting.png)
1. Pick your `🔍 dev scanner` plugin (e.g. `ARPSCAN` or `NMAPDEV`), or import devices into the application with an `📥 importer` plugin. (See **Enabling plugins** below)
1. Pick your `🔍 dev scanner` plugin (e.g. `ARPSCAN` or `NMAPDEV`), or import devices into the application with an `📥 importer` plugin. (See **Enabling plugins** below)
2. Pick a `▶️ publisher` plugin, if you want to send notifications. If you don't see a publisher you'd like to use, look at the [📚_publisher_apprise](/front/plugins/_publisher_apprise/) plugin which is a proxy for over 80 notification services.
3. Setup your [Network topology diagram](./NETWORK_TREE.md)
4. Fine-tune [Notifications](./NOTIFICATIONS.md)
5. [Backup your setup](./BACKUPS.md)
6. Contribute and [Create custom plugins](./PLUGINS_DEV.md)
5. Setup [Workflows](./WORKFLOWS.md)
6. [Backup your setup](./BACKUPS.md)
7. Contribute and [Create custom plugins](./PLUGINS_DEV.md)
## 📑 Available Plugins
## Plugin types
| Plugin type | Icon | Description | When to run | Required | Data source [?](./PLUGINS_DEV.md) |
| -------------- | ---- | ---------------------------------------------------------------- | ----------------------------------- | -------- | ------------------------------------- |
| publisher | ▶️ | Sending notifications to services. | `on_notification` | ✖ | Script |
| dev scanner | 🔍 | Create devices in the app, manages online/offline device status. | `schedule` | ✖ | Script / SQLite DB |
| name discovery | 🆎 | Discovers names of devices via various protocols. | `before_name_updates`, `schedule` | ✖ | Script |
| importer | 📥 | Importing devices from another service. | `schedule` | ✖ | Script / SQLite DB |
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
| other | ♻ | Other plugins | misc | ✖ | Script / Template |
## Features
| Icon | Description |
| ---- | ------------------------------------------------------------ |
| 🖧 | Auto-imports the network topology diagram |
| 🔄 | Has the option to sync some data back into the plugin source |
## Available Plugins
Device-detecting plugins insert values into the `CurrentScan` database table. The plugins that are not required are safe to ignore, however, it makes sense to have at least some device-detecting plugins enabled, such as `ARPSCAN` or `NMAPDEV`.
@@ -36,7 +57,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| `DHCPLSS` | 🔍/📥/🆎| Import devices from DHCP leases | | | Script | [dhcp_leases](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/dhcp_leases/) |
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/dhcp_servers/) |
| `FREEBOX` | 🔍/♻/🆎| Pull data and names from Freebox/Iliadbox | | | Script | [freebox](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/freebox/) |
| `ICMP` | 🔍 | ICMP (ping) status checker | | | Script | [icmp_scan](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/icmp_scan/) |
| `ICMP` | | ICMP (ping) status checker | | | Script | [icmp_scan](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/icmp_scan/) |
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/internet_ip/) |
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/internet_speedtest/) |
| `IPNEIGH` | 🔍 | Scan ARP (IPv4) and NDP (IPv6) tables | | | Script | [ipneigh](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/ipneigh/) |
@@ -72,27 +93,9 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
> ❌ marked for removal
> ⌚It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
## Plugin types
| Plugin type | Icon | Description | When to run | Required | Data source [?](./PLUGINS_DEV.md) |
| -------------- | ---- | ---------------------------------------------------------------- | ----------------------------------- | -------- | ------------------------------------- |
| publisher | ▶️ | Sending notifications to services. | `on_notification` | ✖ | Script |
| dev scanner | 🔍 | Create devices in the app, manages online/offline device status. | `schedule` | ✖ | Script / SQLite DB |
| name discovery | 🆎 | Discovers names of devices via various protocols. | `before_name_updates`, `schedule` | ✖ | Script |
| importer | 📥 | Importing devices from another service. | `schedule` | ✖ | Script / SQLite DB |
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
| other | ♻ | Other plugins | misc | ✖ | Script / Template |
## Features
| Icon | Description |
| ---- | ------------------------------------------------------------ |
| 🖧 | Auto-imports the network topology diagram |
| 🔄 | Has the option to sync some data back into the plugin source |
## ✅Enabling plugins
## Enabling plugins
Plugins can be enabled via Settings, and can be disabled as needed.

View File

@@ -2,11 +2,14 @@
By design, local network scanners such as `arp-scan` use ARP (Address Resolution Protocol) to map IP addresses to MAC addresses on the local network. Since ARP operates at Layer 2 (Data Link Layer), it typically works only within a single broadcast domain, usually limited to a single router or network segment.
To scan multiple locally accessible network segments, add them as subnets according to the [subnets](./SUBNETS.md) documentation.
> [!NOTE]
> Ping and `ARPSCAN` use different protocols so even if you can ping devices it doesn't mean `ARPSCAN` can detect them.
To scan multiple locally accessible network segments, add them as subnets according to the [subnets](./SUBNETS.md) documentation. If `ARPSCAN` is not suitable for your setup, read on.
## Complex Use Cases
The following network setups might make some devices undetectable. Check the specific setup to understand the cause and find potential workarounds to still report on these devices.
The following network setups might make some devices undetectable with `ARPSCAN`. Check the specific setup to understand the cause and find potential workarounds to report on these devices.
### Wi-Fi Extenders
@@ -28,7 +31,7 @@ The following workarounds should work for most complex network setups.
## Supplementing Plugins
You can use supplementary plugins that employ alternate methods. Protocols used by the `SNMPDSC` or `DHCPLSS` plugins are widely supported on different routers and can be effective as workarounds. Check the [plugins list](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md) to find a plugin that works with your router and network setup.
You can use supplementary plugins that employ alternate methods. Protocols used by the `SNMPDSC` or `DHCPLSS` plugins are widely supported on different routers and can be effective as workarounds. Check the [plugins list](./PLUGINS.md) to find a plugin that works with your router and network setup.
## Multiple NetAlertX Instances

View File

@@ -2,17 +2,14 @@
You need to specify the network interface and the network mask. You can also configure multiple subnets and specify VLANs (see VLAN exceptions below).
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet. You can verify this by running the following command in the container (replace the interface and ip mask):
`ARPSCAN` can scan multiple networks if the network allows it. To scan networks directly, the subnets must be accessible from the network where NetAlertX is running. This means NetAlertX needs to have access to the interface attached to that subnet.
`sudo arp-scan --interface=eth0 192.168.1.0/24`
> [!WARNING]
> If you don't see all expected devices run the following command in the NetAlertX container (replace the interface and ip mask):
> `sudo arp-scan --interface=eth0 192.168.1.0/24`
>
> If this command returns no results, the network is not accessible due to your network or firewall restrictions (Wi-Fi Extenders, VPNs and inaccessible networks). If direct scans are not possible, check the [remote networks documentation](./REMOTE_NETWORKS.md) for workarounds.
In this example, `--interface=eth0 192.168.1.0/24` represents a neighboring subnet. If this command returns no results, the network is not accessible due to your network or firewall restrictions.
If direct scans are not possible (Wi-Fi Extenders, VPNs and inaccessible networks), check the [remote networks documentation](./REMOTE_NETWORKS.md).
> [!TIP]
> You may need to increase the time between scans `ARPSCAN_RUN_SCHD` and the timeout `ARPSCAN_RUN_TIMEOUT` (and similar settings for related plugins) when adding more subnets. If the timeout setting is exceeded, the scan is canceled to prevent the application from hanging due to rogue plugins.
> Check [debugging plugins](./DEBUG_PLUGINS.md) for more tips.
## Example Values
@@ -24,7 +21,17 @@ If direct scans are not possible (Wi-Fi Extenders, VPNs and inaccessible network
* One subnet: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0']`
* Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 --vlan=107']`
If you get timeout messages, decrease the network mask (e.g.: from `/16` to `/24`) or increase the `TIMEOUT` setting (e.g.: `ARPSCAN_RUN_TIMEOUT` to `300` (5-minute timeout)) for the plugin and the interval between scans (e.g.: `ARPSCAN_RUN_SCHD` to `*/10 * * * *` (scans every 10 minutes)).
> [!TIP]
> When adding more subnets, you may need to increase both the scan interval (`ARPSCAN_RUN_SCHD`) and the timeout (`ARPSCAN_RUN_TIMEOUT`)—as well as similar settings for related plugins.
>
> If the timeout is too short, you may see timeout errors in the log. To prevent the application from hanging due to unresponsive plugins, scans are canceled when they exceed the timeout limit.
>
> To fix this:
> - Reduce the subnet size (e.g., change `/16` to `/24`).
> - Increase the timeout (e.g., set `ARPSCAN_RUN_TIMEOUT` to `300` for a 5-minute timeout).
> - Extend the scan interval (e.g., set `ARPSCAN_RUN_SCHD` to `*/10 * * * *` to scan every 10 minutes).
>
> For more troubleshooting tips, see [Debugging Plugins](./DEBUG_PLUGINS.md).
---

View File

@@ -51,7 +51,7 @@ services:
![Project settings](./img/SYNOLOGY/07_Create_project.png)
7. Replace the paths to your volume and/or comment out unnecessary line(s):
7. Replace the paths to your volume and comment out unnecessary line(s):
- This is only an example, your paths will differ.

View File

@@ -1,49 +1,70 @@
# Debugging inaccessible UI
## 1. Port conflicts
The application uses the following default ports:
When opening an issue please:
- **Web UI**: `20211`
- **GraphQL API**: `20212`
The **Web UI** is served by an **nginx** server, while the **API backend** runs on a **Flask (Python)** server.
## Changing Ports
- To change the **Web UI** port, update the `PORT` environment variable in the `docker-compose.yml` file.
- To change the **GraphQL API** port, use the `GRAPHQL_PORT` setting, either directly or via Docker:
```yaml
APP_CONF_OVERRIDE={"GRAPHQL_PORT":"20212"}
```
For more information, check the [Docker installation guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md).
## Possible issues and troubleshooting
Follow all of the below in order to disqualify potential causes of issues and to troubleshoot these problems faster.
### 1. Port conflicts
When opening an issue or debugging:
1. Include a screenshot of what you see when accessing `HTTP://<your rpi IP>/20211` (or your custom port)
1. [Follow steps 1, 2, 3, 4 on this page](./DEBUG_TIPS.md)
1. Execute the following in the container to see the processes and their ports and submit a screenshot of the result:
1. `sudo apk add lsof`
1. `sudo lsof -i`
1. Try running the `nginx` command in the container
1. if you get `nginx: [emerg] bind() to 0.0.0.0:20211 failed (98: Address in use)` try using a different port number
- `sudo apk add lsof`
- `sudo lsof -i`
1. Try running the `nginx` command in the container:
- if you get `nginx: [emerg] bind() to 0.0.0.0:20211 failed (98: Address in use)` try using a different port number
![lsof ports](./img/WEB_UI_PORT_DEBUG/container_port.png)
## 2. JavaScript issues
### 2. JavaScript issues
Check for browser console (F12 browser dev console) errors + check different browsers.
## 3. Clear the app cache and cached JavaScript files
### 3. Clear the app cache and cached JavaScript files
Refresh the browser cache (usually shoft + refresh), try a private window, or different browsers. Please also refresh the app cache by clicking the 🔃 (reload) button in the header of the application.
## 4. Disable proxy
### 4. Disable proxies
If you have any reverse proxy or similar, try disabling it.
## 5. Disable your firewall
### 5. Disable your firewall
If you are using a firewall, try to temporarily disabling it.
## 6. Post your docker start details
### 6. Post your docker start details
If you haven't, post your docker compose/run command.
## 7. Check for errors in your PHP/NGINX error logs
### 7. Check for errors in your PHP/NGINX error logs
In the container execute:
In the container execute and investigate:
`cat /var/log/nginx/error.log`
`cat /app/log/app.php_errors.log`
## 8. Make sure permissions are correct
### 8. Make sure permissions are correct
> [!TIP]
> You can try to start the container without mapping the `/app/config` and `/app/db` dirs and if the UI shows up then the issue is most likely related to your file system permissions or file ownership.

130
docs/WORKFLOWS.md Executable file
View File

@@ -0,0 +1,130 @@
# Workflows Overview
The workflows module in NetAlertX allows to automate repetitive tasks, making network management more efficient. Whether you need to assign newly discovered devices to a specific Network Node, auto-group devices from a given vendor, unarchive a device if detected online, or automatically delete devices, this module provides the flexibility to tailor the automations to your needs.
![Workflows diagram](./img/WORKFLOWS/workflows_diagram.png)
Below are a few examples that demonstrate how this module can be used to simplify network management tasks.
## Updating Workflows
> [!NOTE]
> In order to apply a workflow change, you must first **Save** the changes and then reload the application by clicking **Restart server**.
## Workflow components
### Triggers
![Trigger example](./img/WORKFLOWS/trigger.jpg)
Triggers define the event that activates a workflow. They monitor changes to objects within the system, such as updates to devices or the insertion of new entries. When the specified event occurs, the workflow is executed.
> [!TIP]
> Workflows not running? Check the [Workflows debugging](./WORKFLOWS_DEBUGGING.md) guide how to troubleshoot triggers and conditions.
#### Example Trigger:
- **Object Type**: `Devices`
- **Event Type**: `update`
This trigger will activate when a `Device` object is updated.
### Conditions
![Conditions example](./img/WORKFLOWS/conditions.png)
Conditions determine whether a workflow should proceed based on certain criteria. These criteria can be set for specific fields, such as whether a device is from a certain vendor, or whether it is new or archived. You can combine conditions using logical operators (`AND`, `OR`).
> [!TIP]
> To better understand how to use specific Device fields, please read through the [Database overview](./DATABASE.md) guide.
#### Example Condition:
- **Logic**: `AND`
- **Field**: `devVendor`
- **Operator**: `contains` (case in-sensitive)
- **Value**: `Google`
This condition checks if the device's vendor is `Google`. The workflow will only proceed if the condition is true.
### Actions
![Actions example](./img/WORKFLOWS/actions.jpg)
Actions define the tasks that the workflow will perform once the conditions are met. Actions can include updating fields or deleting devices.
You can include multiple actions that should execute once the conditions are met.
#### Example Action:
- **Action Type**: `update_field`
- **Field**: `devIsNew`
- **Value**: `0`
This action updates the `devIsNew` field to `0`, marking the device as no longer new.
# Examples
Below you can find a couple of configuration examples.
![Workflow example](./img/WORKFLOWS/workflows.png)
---
## Example 1: Assign Device to Network Node Based on IP
This workflow assigns newly added devices with IP addresses in the `192.168.1.*` range to the device with the MAC address `6c:6d:6d:6c:6c:6c`.
### Trigger:
- **Object Type**: `Devices`
- **Event Type**: `insert`
### Conditions:
- **Logic**: `AND`
- `Field`: `devLastIP`
- `Operator`: `contains`
- `Value`: `192.168.1.`
This condition ensures that the workflow only applies to devices with an IP address in the `192.168.1.*` range.
### Actions:
- **Action Type**: `update_field`
- **Field**: `devNetworkNode`
- **Value**: `6c:6d:6d:6c:6c:6c`
---
## Example 2: Mark Device as Not New and Delete If from Google Vendor
This workflow automates the process of marking Google devices as not new and deleting them if they meet the criteria.
### Trigger:
- **Object Type**: `Devices`
- **Event Type**: `update`
### Conditions:
- **Logic**: `AND`
- `Field`: `devVendor`
- `Operator`: `contains`
- `Value`: `Google`
This condition checks if the device's vendor is `Google`.
- **Logic**: `AND`
- `Field`: `devIsNew`
- `Operator`: `equals`
- `Value`: `1`
This ensures the workflow applies only to new devices.
### Actions:
1. **Action Type**: `update_field`
- **Field**: `devIsNew`
- **Value**: `0`
This action marks the device as no longer new.
2. **Action Type**: `delete_device`
This action deletes the device after it is marked as not new.
> [!TIP]
> Share your workflows in [Discord](https://discord.com/invite/NczTUTWyRr) or [GitHub Discussions](https://github.com/jokob-sk/NetAlertX/discussions).

38
docs/WORKFLOWS_DEBUGGING.md Executable file
View File

@@ -0,0 +1,38 @@
# Workflows debugging and troubleshooting
> [!TIP]
> Before troubleshooting, please ensure you have [Debugging enabled](./DEBUG_TIPS.md).
Workflows are triggered by various events. These events are captured and listed in the _Integrations -> App Events_ section of the application.
## Troubleshooting triggers
> [!NOTE]
> Workflow events are processed once every 5 seconds. However, if a scan or other background tasks are running, this can cause a delay up to a few minutes.
If an event doesn't trigger a workflow as expected, check the _App Events_ section for the event. You can filter these by the ID of the device (`devMAC` or `devGUID`).
![App events search](./img/WORKFLOWS/workflows_app_events_search.png)
Once you find the _Event Guid_ and _Object GUID_, use them to find relevant debug entries.
Navigate to _Mainetenace -> Logs_ where you can filter the logs based on the _Event or Object GUID_.
![Log events search](./img/WORKFLOWS/workflows_logs_search.png)
Below you can find some example `app.log` entries that will help you understand why a Workflow was or was not triggered.
```bash
16:27:03 [WF] Checking if '13f0ce26-1835-4c48-ae03-cdaf38f328fe' triggers the workflow 'Sample Device Update Workflow'
16:27:03 [WF] self.triggered 'False' for event '[[155], ['13f0ce26-1835-4c48-ae03-cdaf38f328fe'], [0], ['2025-04-02 05:26:56'], ['Devices'], ['050b6980-7af6-4409-950d-08e9786b7b33'], ['DEVICES'], ['00:11:32:ef:a5:6c'], ['192.168.1.82'], ['050b6980-7af6-4409-950d-08e9786b7b33'], [None], [0], [0], ['devPresentLastScan'], ['online'], ['update'], [None], [None], [None], [None]] and trigger {"object_type": "Devices", "event_type": "insert"}'
16:27:03 [WF] Checking if '13f0ce26-1835-4c48-ae03-cdaf38f328fe' triggers the workflow 'Location Change'
16:27:03 [WF] self.triggered 'True' for event '[[155], ['13f0ce26-1835-4c48-ae03-cdaf38f328fe'], [0], ['2025-04-02 05:26:56'], ['Devices'], ['050b6980-7af6-4409-950d-08e9786b7b33'], ['DEVICES'], ['00:11:32:ef:a5:6c'], ['192.168.1.82'], ['050b6980-7af6-4409-950d-08e9786b7b33'], [None], [0], [0], ['devPresentLastScan'], ['online'], ['update'], [None], [None], [None], [None]] and trigger {"object_type": "Devices", "event_type": "update"}'
16:27:03 [WF] Event with GUID '13f0ce26-1835-4c48-ae03-cdaf38f328fe' triggered the workflow 'Location Change'
```
Note how one trigger executed, but the other didn't based on different `"event_type"` values. One is `"event_type": "insert"`, the other `"event_type": "update"`.
Given the Event is a update event (note `...['online'], ['update'], [None]...` in the event structure), the `"event_type": "insert"` trigger didn't execute.

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
docs/img/WORKFLOWS/actions.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/img/WORKFLOWS/conditions.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/img/WORKFLOWS/trigger.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
docs/img/WORKFLOWS/workflows.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

View File

@@ -8,7 +8,6 @@ NetAlertX provides contextual help within the application:
- **Hover over settings, fields, or labels** to see additional tooltips and guidance.
- **Click ❔ (question-mark) icons** next to various elements to view detailed information.
- Access the in-app **Help / FAQ** section for frequently asked questions and quick answers.
---

View File

@@ -1141,14 +1141,14 @@ input[readonly] {
.settings-sticky-bottom-section {
position: fixed;
z-index: 999;
background-color: #5B5B66;
/* background-color: #5B5B66; */
/* opacity: 0.8; */
bottom: 30px;
border-radius: 5px;
/* margin:1px; */
border-width: 1px;
/* border-width: 1px;
border-style: solid;
border-color: inherit;
border-color: inherit; */
/* width: 87%; */
padding: 10px;
}
@@ -1517,25 +1517,25 @@ input[readonly] {
/* AdminLTE overrides */
#networkTree .box
{
border-top:1px;
/* border-top:1px; */
border-top-color:grey;
padding:0px;
padding-top:6px;
margin:0px;
align-items:center;
border-radius:20px;
width:180px;
display:flex;
/* width:190px; Don't change, smaller causes line break in network view */
/* display:flex; */
flex-direction:column;
justify-content:center;
/* display: inline-grid; */
}
.networkHelpIcon
.helpIcon
{
padding: 5px;
margin-left: 5px;
top: 55px;
position: absolute;
z-index:5;
padding: 5px;
margin-left: 0px;
top: 47px;
position: absolute;
z-index: 5;
}
#networkTree .netNodeText
{
@@ -1576,17 +1576,16 @@ input[readonly] {
width: auto;
}
#networkTree .netCollapse
{
display: block;
position: absolute;
margin-left: 170px;
font-size: large;
left: -15px;
right: 0;
margin-right: -3px;
}
#networkTree .highlightedNode
{
border: solid;
/* border: solid; */
border-color:cyan;
}
#networkTree .netStatus-Off-line i,
@@ -1597,7 +1596,6 @@ input[readonly] {
.spanNetworkTree {
display: inline-block;
width: 135px;
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis;
@@ -1613,6 +1611,11 @@ input[readonly] {
/* margin-left: 0.2em; */
}
.networkTable .networkNodeTabHeaders a {
display: block;
height: 3em;
}
.networkTable .icon {
/* padding-left:2em; */
width:2em;
@@ -1631,7 +1634,6 @@ input[readonly] {
.networkNodeTabHeaders
{
max-width: 200px;
text-overflow: ellipsis;
overflow: hidden;
text-wrap: nowrap;
@@ -1709,13 +1711,6 @@ input[readonly] {
padding-top: 20px;
}
.login-page .login-custom
{
width:480px;
}
/*Hidden special button*/
@media (max-width: 365px) {
@@ -1843,12 +1838,54 @@ input[readonly] {
/* -----------------------------------------------------------------------------
Workflows
----------------------------------------------------------------------------- */
#wf-content-wrapper
{
display: grid;
}
#workflowContainer
{
display: grid;
}
#workflowContainerWrap {
display: grid;
}
#workflowContainerWrap .panel-collapse
{
padding: 5px;
}
.workflows
{
max-width: 800px;
}
.workflows .col-sm-12, .workflows .col-sx-12
{
padding-right: 5px;
padding-left: 5px;
}
.workflows .add-button-wrap .button-container
{
padding-bottom: 5px;
text-align: center;
}
.workflows .actions-list {
display: block;
}
.workflows .form-group {
margin-bottom: 7px;
z-index: 1;
display: flex;
opacity: 0.7;
}
.workflows .section-title
{
padding: 10px;
@@ -1857,8 +1894,8 @@ input[readonly] {
}
.workflows .panel, .workflows .box {
padding-top: 10px;
padding-bottom: 10px;
padding-top: 5px;
padding-bottom: 5px;
}
@@ -1866,24 +1903,86 @@ input[readonly] {
color: #000;
}
.workflows .button-container
{
/* display: contents; */
text-align: center;
/* width: 100%; */
}
/* .workflows .panel:hover{
opacity: 1;
}
.workflows .panel{
opacity: 0.8;
} */
.workflows .bottom-buttons button
{
margin: 5px;
}
.workflows .condition-list button
.workflows .button-container
{
padding-right: 0px !important;
padding-left: 0px !important;
}
/* .workflows .condition-list button
{
margin: 2px;
}
} */
.button-container button
/* .button-container button
{
width:100%;
} */
.red-hover-text:hover
{
color: var(--color-red) !important;
}
#workflowContainerWrap
.green-hover-text:hover
{
display: contents;
color: var(--color-green) !important;
}
.workflows .bckg-icon-1-line
{
font-size: 3em;
display: block;
position: absolute;
opacity: 0.1;
right: 0.1em;
}
.workflows .bckg-icon-2-line
{
font-size: 6em;
display: block;
position: absolute;
opacity: 0.1;
right: 0.1em;
}
.workflows .bckg-icon-3-line
{
font-size: 9em;
display: block;
position: absolute;
opacity: 0.1;
right: 0.1em;
}
.workflows .remove-condition
{
z-index: 1;
}
.workflows .workflow-card
{
display: block;
}
.workflow-card .panel-title

View File

@@ -744,4 +744,5 @@
.thresholdFormControl
{
color:#000;
}
}

View File

@@ -266,7 +266,7 @@
})
}, 1);
}, 100);
});
}
@@ -338,6 +338,7 @@
// -----------------------------------------------------------------------------
// Save device data to DB
function setDeviceData(direction = '', refreshCallback = '') {
// Check MAC
if (mac === '') {

View File

@@ -74,10 +74,10 @@
<!-- box-header -->
<div class="box-header">
<div class=" col-md-9 ">
<div class=" col-sm-8 ">
<h3 id="tableDevicesTitle" class="box-title text-gray "></h3>
</div>
<div class="dummyDevice col-md-3 ">
<div class="dummyDevice col-sm-4 ">
<span id="multiEditPlc">
<!-- multi edit button placeholder -->
</span>
@@ -218,7 +218,7 @@ function getDevicesTotals() {
// Attempt to fetch data
$.ajax({
url: '/php/server/query_json.php',
url: 'php/server/query_json.php',
type: "GET",
dataType: "json",
data: {
@@ -336,7 +336,7 @@ let columnFilters = [];
function initFilters() {
// Attempt to fetch data
$.ajax({
url: '/php/server/query_json.php',
url: 'php/server/query_json.php',
type: "GET",
dataType: "json",
data: {
@@ -743,6 +743,7 @@ function initializeDatatable (status) {
'ordering' : true,
'info' : true,
'autoWidth' : false,
'dom': '<"top"f>rtl<"bottom"ip><"clear">',
// Parameters
'pageLength' : tableRows,
@@ -987,7 +988,7 @@ function handleLoadingDialog(needsReload = false)
{
// console.log(`needsReload: ${needsReload}`);
$.get('/php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
$.get('php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
if(data.includes("update_api|devices"))
{

View File

@@ -2,10 +2,13 @@
<link rel="stylesheet" href="css/app.css">
<?php
require dirname(__FILE__).'/php/server/init.php';
//------------------------------------------------------------------------------
// check if authenticated
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
// Be CAREFUL WHEN INCLUDING NEW PHP FILES
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/server/db.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/language/lang.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
$CookieSaveLoginName = 'NetAlertX_SaveLogin';
@@ -92,10 +95,8 @@ if (isset ($_SESSION["login"]) == FALSE || $_SESSION["login"] != 1)
<!-- iCheck -->
<link rel="stylesheet" href="lib/iCheck/square/blue.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="lib/font-awesome/fontawesome.min.css">
<link rel="stylesheet" href="lib/font-awesome/solid.css">
<link rel="stylesheet" href="lib/font-awesome/brands.css">
<link rel="stylesheet" href="lib/font-awesome/v5-font-face.css">
<link rel="stylesheet" href="lib/font-awesome/all.min.css">
<!-- Favicon -->
<link id="favicon" rel="icon" type="image/x-icon" href="img/NetAlertX_logo.png">
@@ -112,7 +113,7 @@ switch ($UI_THEME) {
?>
<link rel="stylesheet" href="/css/offline-font.css">
</head>
<body class="hold-transition login-page">
<body class="hold-transition login-page col-sm-12 col-sx-12">
<div class="login-box login-custom">
<div class="login-logo">
<a href="/index2.php">Net<b>Alert</b><sup>x</sup></a>

View File

@@ -1303,6 +1303,38 @@ $(document).ready(function() {
}
});
// -----------------------------------------------------------
// Restart Backend Python Server
function askRestartBackend() {
// Ask
showModalWarning(getString('Maint_RestartServer'), getString('Maint_Restart_Server_noti_text'),
getString('Gen_Cancel'), getString('Maint_RestartServer'), 'restartBackend');
}
// -----------------------------------------------------------
function restartBackend() {
modalEventStatusId = 'modal-message-front-event'
// Execute
$.ajax({
method: "POST",
url: "php/server/util.php",
data: { function: "addToExecutionQueue", action: `${getGuid()}|cron_restart_backend` },
success: function(data, textStatus) {
// showModalOk ('Result', data );
// show message
showModalOk(getString("general_event_title"), `${getString("general_event_description")} <br/> <br/> <code id='${modalEventStatusId}'></code>`);
updateModalState()
write_notification('[Maintenance] App manually restarted', 'info')
}
})
}
// -----------------------------------------------------------------------------
// initialize
// -----------------------------------------------------------------------------

View File

@@ -85,7 +85,7 @@ function renderList(
// Check if database is locked
function checkDbLock() {
$.ajax({
url: "/php/server/query_logs.php?file=db_is_locked.log",
url: "php/server/query_logs.php?file=db_is_locked.log",
type: "GET",
success: function (response) {

View File

@@ -68,11 +68,13 @@ function showModalWarning(
callbackFunction = null,
triggeredBy = null
) {
prefix = "modal-warning";
// set captions
$("#modal-warning-title").html(title);
$("#modal-warning-message").html(message);
$("#modal-warning-cancel").html(btnCancel);
$("#modal-warning-OK").html(btnOK);
$(`#${prefix}-title`).html(title);
$(`#${prefix}-message`).html(message);
$(`#${prefix}-cancel`).html(btnCancel);
$(`#${prefix}-OK`).html(btnOK);
if (callbackFunction != null) {
modalCallbackFunction = callbackFunction;
@@ -83,7 +85,7 @@ function showModalWarning(
}
// Show modal
$("#modal-warning").modal("show");
$(`#${prefix}`).modal("show");
}
// -----------------------------------------------------------------------------
@@ -93,7 +95,8 @@ function showModalInput(
btnCancel = getString("Gen_Cancel"),
btnOK = getString("Gen_Okay"),
callbackFunction = null,
triggeredBy = null
triggeredBy = null,
defaultValue = ""
) {
prefix = "modal-input";
@@ -102,6 +105,7 @@ function showModalInput(
$(`#${prefix}-message`).html(message);
$(`#${prefix}-cancel`).html(btnCancel);
$(`#${prefix}-OK`).html(btnOK);
$(`#${prefix}-textarea`).val(defaultValue);
if (callbackFunction != null) {
modalCallbackFunction = callbackFunction;

View File

@@ -422,7 +422,7 @@ function updateModalState() {
setTimeout(function() {
// Fetch the content from the log file using an AJAX request
$.ajax({
url: '/php/server/query_logs.php?file=execution_queue.log',
url: 'php/server/query_logs.php?file=execution_queue.log',
type: 'GET',
success: function(data) {
// Update the content of the HTML element (e.g., a div with id 'logContent')

9
front/lib/font-awesome/all.min.css vendored Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,19 +0,0 @@
/*!
* Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2022 Fonticons, Inc.
*/
:root, :host {
--fa-style-family-classic: 'Font Awesome 6 Free';
--fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: block;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
.fas,
.fa-solid {
font-weight: 900; }

View File

@@ -1,6 +0,0 @@
/*!
* Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2022 Fonticons, Inc.
*/
:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}

View File

@@ -1,22 +0,0 @@
/*!
* Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2022 Fonticons, Inc.
*/
@font-face {
font-family: 'Font Awesome 5 Brands';
font-display: block;
font-weight: 400;
src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
@font-face {
font-family: 'Font Awesome 5 Free';
font-display: block;
font-weight: 900;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
@font-face {
font-family: 'Font Awesome 5 Free';
font-display: block;
font-weight: 400;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }

View File

@@ -1,6 +0,0 @@
/*!
* Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2022 Fonticons, Inc.
*/
@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}

File diff suppressed because one or more lines are too long

View File

@@ -209,7 +209,13 @@ $db->close();
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnImportPastedConfig" onclick="askImportPastedConfig()"><?= lang('Maintenance_Tool_ImportPastedConfig');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ImportPastedConfig_text');?></div>
</div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnDownloadWorkflows" onclick="DownloadWorkflows()"><?= lang('Maintenance_Tool_DownloadWorkflows');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_DownloadWorkflows_text');?></div>
</div>
</div>
</div>
<!-- ---------------------------Logging-------------------------------------------- -->
@@ -395,38 +401,6 @@ function deleteActHistory()
});
}
// -----------------------------------------------------------
// Restart Backend Python Server
function askRestartBackend() {
// Ask
showModalWarning('<?= lang('Maint_RestartServer');?>', '<?= lang('Maint_Restart_Server_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Maint_RestartServer');?>', 'restartBackend');
}
// -----------------------------------------------------------
function restartBackend() {
modalEventStatusId = 'modal-message-front-event'
// Execute
$.ajax({
method: "POST",
url: "php/server/util.php",
data: { function: "addToExecutionQueue", action: `${getGuid()}|cron_restart_backend` },
success: function(data, textStatus) {
// showModalOk ('Result', data );
// show message
showModalOk(getString("general_event_title"), `${getString("general_event_description")} <br/> <br/> <code id='${modalEventStatusId}'></code>`);
updateModalState()
write_notification('[Maintenance] App manually restarted', 'info')
}
})
}
// -----------------------------------------------------------
// Import pasted Config ASK
function askImportPastedConfig() {
@@ -440,17 +414,15 @@ function askImportPastedConfig() {
// Upload Settings Config
function UploadConfig()
{
// alert("aaa")
appConf = $('#modal-input-textarea').val()
// encode for import
appConfBase64 = btoa(appConf)
// import
$.post('php/server/query_replace_config.php', { config: appConfBase64 }, function(msg) {
$.post('php/server/query_replace_config.php', { base64data: appConfBase64, fileName: "app.conf" }, function(msg) {
console.log(msg);
// showMessage(msg);
write_notification(`[Maintenance] Settings imported from backup: ${msg}`, 'interrupt');
write_notification(`[Maintenance]: ${msg}`, 'interrupt');
});
}
@@ -463,6 +435,15 @@ function DownloadConfig()
openInNewTab("php/server/query_config.php?file=app.conf&download=true")
}
// -----------------------------------------------------------
// Download Workflows
function DownloadWorkflows()
{
// Execute
openInNewTab("php/server/query_config.php?file=workflows.json&download=true")
}
// -----------------------------------------------------------

View File

@@ -6,8 +6,6 @@
// online / offline badges HTML snippets
define('badge_online', '<div class="badge bg-green text-white" style="width: 60px;">Online</div>');
define('badge_offline', '<div class="badge bg-red text-white" style="width: 60px;">Offline</div>');
define('circle_online', '<div class="badge bg-green text-white" style="width: 10px; height: 10px; padding:2px; margin-top: -25px;">&nbsp;</div>');
define('circle_offline', '<div class="badge bg-red text-white" style="width: 10px; height: 10px; padding:2px; margin-top: -25px;">&nbsp;</div>');
define('sortable_column', ' <span class="sort-btn" onclick="sortColumn(this)"><i class="fa-solid fa-arrow-up-short-wide"></i></span>');
?>
@@ -22,7 +20,7 @@
<div class="content-wrapper">
<span class="networkHelpIcon"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a></span>
<span class="helpIcon"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md"><i class="fa fa-circle-question"></i></a></span>
<div id="networkTree" class="drag"></div>
@@ -39,21 +37,18 @@
}
// online/offline status circle (red/green)
$node_badge = "";
if($node_status == 1) // 1 means online, 0 offline
$icon_style = "";
if($node_status == 0) // 1 means online, 0 offline
{
$node_badge = circle_online;
} else
{
$node_badge = circle_offline;
}
$icon_style = "style=\"color:var(--color-red);\"";
}
$decoded_icon = base64_decode($icon);
$idFromMac = str_replace(":", "_", $node_mac);
$str_tab_header = '<li class="networkNodeTabHeaders '.$activetab.' " >
<a href="#'.$idFromMac.'" data-mytabmac="'.$node_mac.'" id="'.$idFromMac.'_id" data-toggle="tab" title="'.$node_name.' ">' // _id is added so it doesn't conflict with AdminLTE tab behavior
.'<div class="icon">'.$decoded_icon.' </div> <span class="node-name">'.$node_name.'</span>' .$str_port.$node_badge.
.'<div class="icon" '.$icon_style.'>'.$decoded_icon.' </div> <span class="node-name">'.$node_name.'</span>' .$str_port.
'</a>
</li>';
@@ -465,7 +460,7 @@
?>
<script src="lib/treeviz/bundle.js"></script>
<script src="lib/treeviz/bundle.js.map"></script>
<script defer>
@@ -697,34 +692,56 @@ function attachTreeEvents()
// ---------------------------------------------------------------------------
// Handle network node click - select correct tab in the bottom table
function handleNodeClick(nodeData)
function handleNodeClick(el)
{
const targetTabMAC = nodeData.data.mac;
const targetTabMAC = $(el).attr("data-mytreemacmain");
var targetTab = $(`a[data-mytabmac="${targetTabMAC}"]`);
// Simulate a click event on the target tab
targetTab.click();
if (targetTab.length) {
// Simulate a click event on the target tab
targetTab.click();
// Smooth scroll to the tab content
$('html, body').animate({
scrollTop: targetTab.offset().top - 50
}, 500); // Adjust the duration as needed
}
}
// ---------------------------------------------------------------------------
var myTree;
var visibleTreeArea = $(window).height()-155;
var nodeWidth = 120;
var emSize;
var nodeHeight;
var sizeCoefficient = 1.4
// var sizeCoefficient = 1.4
function pxToEm(px, element) {
var baseFontSize = parseFloat($(element || "body").css("font-size"));
return px / baseFontSize;
}
function emToPx(em, element) {
var baseFontSize = parseFloat($(element || "body").css("font-size"));
return Math.round(em * baseFontSize);
}
function initTree(myHierarchy)
{
// calculate the drawing area based on teh tree width and available screen size
var treeAreaHeight = visibleTreeArea > 800 ? 800 : visibleTreeArea;
let screenWidth = $('.content-header').width();
let treeWidth = (nodeWidth + 20) * parentNodesCount;
let treeAreaWidth = screenWidth < treeWidth ? treeWidth : screenWidth;
let baseFontSize = parseFloat($('html').css('font-size'));
let treeAreaHeight = ($(window).height() - 155); ;
// calculate the font size of the leaf nodes to fit everything into the tree area
leafNodesCount == 0 ? 1 : leafNodesCount;
emSize = pxToEm((treeAreaHeight/(leafNodesCount)).toFixed(2));
let screenWidthEm = pxToEm($('.networkTable').width());
// init the drawing area size
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${treeAreaWidth}px`)
$("#networkTree").attr('style', `height:${treeAreaHeight}px; width:${emToPx(screenWidthEm)}px`)
if(myHierarchy.type == "")
{
@@ -733,13 +750,14 @@ function initTree(myHierarchy)
return;
}
// calculate the font size of the leaf nodes to fit everything into the tree area
leafNodesCount == 0 ? 1 : leafNodesCount;
emSize = ((treeAreaHeight/(25*leafNodesCount)).toFixed(2));
emSize = emSize > 1 ? 1 : emSize;
// handle if only a few nodes
emSize > 1 ? emSize = 1 : emSize = emSize;
// nodeHeight = ((emSize*100*0.30).toFixed(0))
nodeHeight = ((emSize*100*0.30).toFixed(0))
let nodeHeightPx = emToPx(emSize*1);
let nodeWidthPx = emToPx(screenWidthEm / (parentNodesCount));
// handle if only a few nodes
nodeWidthPx > 160 ? nodeWidthPx = 160 : nodeWidthPx = nodeWidthPx;
console.log(Treeviz);
@@ -747,8 +765,7 @@ function initTree(myHierarchy)
htmlId: "networkTree",
renderNode: nodeData => {
var fontSize = "font-size:"+emSize+"em;";
(!emptyArr.includes(nodeData.data.port )) ? port = nodeData.data.port : port = "";
(port == "" || port == 0 || port == 'None' ) ? portBckgIcon = `<i class="fa fa-wifi"></i>` : portBckgIcon = `<i class="fa fa-ethernet"></i>`;
@@ -761,10 +778,10 @@ function initTree(myHierarchy)
${atob(nodeData.data.icon)}
</div>` : "";
devicePort = `<div class="netPort"
style="width:${emSize*sizeCoefficient}em;height:${emSize*sizeCoefficient}em">
style="width:${emSize}em;height:${emSize}em">
${portHtml}</div>
<div class="portBckgIcon"
style="margin-left:-${emSize*sizeCoefficient}em;">
style="margin-left:-${emSize}em;">
${portBckgIcon}
</div>`;
collapseExpandIcon = nodeData.data.hiddenChildren ?
@@ -773,7 +790,7 @@ function initTree(myHierarchy)
// generate +/- icon if node has children nodes
collapseExpandHtml = nodeData.data.hasChildren ?
`<div class="netCollapse"
style="font-size:${emSize*sizeCoefficient}em;top:${emSize/6}em"
style="font-size:${nodeHeightPx/2}px;top:${nodeHeightPx/4}px"
data-mytreepath="${nodeData.data.path}"
data-mytreemac="${nodeData.data.mac}">
<i class="fa fa-${collapseExpandIcon} pointer"></i>
@@ -787,21 +804,24 @@ function initTree(myHierarchy)
// css indicating online/offline status
statusCss = ` netStatus-${nodeData.data.status}`;
return result = `<div class="box ${nodeData.data.hasChildren ? "pointer":""} ${statusCss} ${highlightedCss}"
return result = `<div
class="node-inner box ${nodeData.data.hasChildren ? "pointer":""} ${statusCss} ${highlightedCss}"
data-mytreemacmain="${nodeData.data.mac}"
style="height:${nodeData.settings.nodeHeight}px;${fontSize}"
style="height:${nodeHeightPx}px;font-size:${nodeHeightPx-5}px;"
onclick="handleNodeClick(this)"
>
<div class="netNodeText">
<strong>${devicePort} ${deviceIcon}
<span class="spanNetworkTree anonymizeDev" >${nodeData.data.name}</span>
</strong>
${collapseExpandHtml}
</div>
</div>`;
<span class="spanNetworkTree anonymizeDev" style="width:${nodeWidthPx-50}px">${nodeData.data.name}</span>
</strong>
</div>
</div>
${collapseExpandHtml}`;
},
mainAxisNodeSpacing: 'auto',
secondaryAxisNodeSpacing: 0.3,
nodeHeight: nodeHeight.toString(),
// secondaryAxisNodeSpacing: 0.3,
nodeHeight: nodeHeightPx,
nodeWidth: nodeWidthPx,
marginTop: '5',
isHorizontal : true,
hasZoom: true,
@@ -811,8 +831,8 @@ function initTree(myHierarchy)
hasFlatData: false,
relationnalField: "children",
linkWidth: (nodeData) => 3,
linkColor: (nodeData) => "#ffcc80",
onNodeClick: (nodeData) => handleNodeClick(nodeData),
linkColor: (nodeData) => "#ffcc80"
// onNodeClick: (nodeData) => handleNodeClick(nodeData),
});
console.log(deviceListGlobal);

View File

@@ -1,6 +1,6 @@
<?php
ini_set('error_log', '../../log/app.php_errors.log'); // initializing the app.php_errors.log file for the maintenance section
require dirname(__FILE__).'/../templates/timezone.php';
require dirname(__FILE__).'/../templates/globals.php';
require dirname(__FILE__).'/db.php';
require dirname(__FILE__).'/util.php';
require dirname(__FILE__).'/../templates/language/lang.php';

View File

@@ -13,21 +13,23 @@ require dirname(__FILE__).'/../server/init.php';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// Get query string parameters ?file=settings_table.json&download=true
$file = isset($_GET['file']) ? $_GET['file'] : null;
$download = isset($_GET['download']) ? $_GET['download'] === 'true' : false;
$download = isset($_GET['download']) && $_GET['download'] === 'true';
// Check if file parameter is provided
if ($file) {
// Define the folder where files are located
$filePath = "/app/config/" . basename($file);
// Check if the file exists
if (file_exists($filePath)) {
// Handle download behavior
// Check if the file exists and is readable
if (file_exists($filePath) && is_readable($filePath)) {
// Determine file extension
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
if ($download) {
// Force file download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
@@ -35,19 +37,29 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
readfile($filePath);
exit;
} else {
// Display file content
header('Content-Type: text/plain');
echo file_get_contents($filePath);
// Serve file based on type
if ($extension === 'json') {
header('Content-Type: application/json');
echo json_encode(json_decode(file_get_contents($filePath), true), JSON_PRETTY_PRINT);
} else {
header('Content-Type: text/plain');
echo file_get_contents($filePath);
}
exit;
}
} else {
// File not found response
http_response_code(404);
header('Content-Type: application/json');
echo json_encode(["error" => "File not found"]);
exit;
}
} else {
// Missing file parameter response
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(["error" => "Missing 'file' parameter"]);
exit;
}
}
?>

View File

@@ -8,16 +8,24 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
require dirname(__FILE__).'/../server/init.php';
// ---- IMPORTS ----
global $fullConfPath;
global $configFolderPath;
//------------------------------------------------------------------------------
// Handle incoming requests
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Access the 'config' parameter from the POST request
$base64Data = $_POST['config'] ?? null;
$base64Data = $_POST['base64data'] ?? null;
if (!$base64Data) {
$msg = "Missing 'config' parameter.";
$msg = "Missing 'base64data' parameter.";
echo $msg;
http_response_code(400); // Bad request
die($msg);
}
$fileName = $_POST['fileName'] ?? null;
if (!$fileName) {
$msg = "Missing 'fileName' parameter.";
echo $msg;
http_response_code(400); // Bad request
die($msg);
@@ -33,15 +41,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
die($msg);
}
$fullPath = $configFolderPath.$fileName;
// Backup the original file
if (file_exists($fullConfPath)) {
copy($fullConfPath, $fullConfPath . ".bak");
if (file_exists($fullPath)) {
copy($fullPath, $fullPath . ".bak");
}
// Write the new configuration
$file = fopen($fullConfPath, "w");
$file = fopen($fullPath, "w");
if (!$file) {
$msg = "Unable to open file!";
$msg = "Unable to open file: ". $fullPath;
echo $msg;
http_response_code(500); // Server error
die($msg);
@@ -50,6 +60,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
fwrite($file, $input);
fclose($file);
echo "Configuration saved successfully.";
echo "Configuration file saved successfully: " .$fileName ;
}
?>

View File

@@ -8,7 +8,7 @@
# Puche 2021 / 2022+ jokob jokob@duck.com GNU GPLv3
//------------------------------------------------------------------------------
require dirname(__FILE__).'/../templates/timezone.php';
require dirname(__FILE__).'/../templates/globals.php';
require dirname(__FILE__).'/../templates/skinUI.php';
//------------------------------------------------------------------------------

View File

@@ -1,6 +1,6 @@
<?php
require dirname(__FILE__).'/../templates/timezone.php';
require dirname(__FILE__).'/../templates/globals.php';
//------------------------------------------------------------------------------
// check if authenticated

View File

@@ -30,7 +30,7 @@
<div class="pull-right no-hidden-xs">
| <a href="https://gurubase.io/g/netalertx" class="pointer" target="_blank" title="Ask AI"><i class="fa-regular fa-comment-dots fa-flip-horizontal"></i></a>
| <a href="https://jokob-sk.github.io/NetAlertX/" class="pointer" target="_blank" title="Documentation"><i class="fa fa-book"></i></a>
| <a href="https://github.com/jokob-sk/NetAlertX/issues" class="pointer" target="_blank"><i class="fa-solid fa-bug" title="Report a bug"></i></a>
| <a href="https://github.com/jokob-sk/NetAlertX/issues" class="pointer" target="_blank"><i class="fa fa-bug" title="Report a bug"></i></a>
| <a href="https://discord.com/invite/NczTUTWyRr" class="pointer" target="_blank"><i class="fa-brands fa-discord" title="Join Discord"></i></a>
| <?= lang('Maintenance_built_on');?>: <?php include 'php/templates/build.php'; ?>
| Version: <?php include 'php/templates/version.php'; ?>

View File

@@ -1,17 +1,21 @@
<?php
// ###################################
// ## TimeZone processing start
// ###################################
// ######################################################################
// ## Global constants and TimeZone processing
// ######################################################################
$configFolderPath = dirname(__FILE__)."/../../../config/";
$config_file = "app.conf";
$configFolderPath = "/app/config/";
$logFolderPath = "/app/log/";
$config_file = "app.conf";
$workflows_file = "workflows.json";
$log_file = "app_front.log";
$default_tz = "Europe/Berlin";
$fullConfPath = $configFolderPath.$config_file;
$fullWorkflowsPath = $configFolderPath.$workflows_file;
$config_file_lines = file($fullConfPath);
$config_file_lines_timezone = array_values(preg_grep('/^TIMEZONE\s.*/', $config_file_lines));
@@ -44,7 +48,7 @@ date_default_timezone_set($timeZone);
$date = new DateTime("now", new DateTimeZone($timeZone) );
$timestamp = $date->format('Y-m-d_H-i-s');
// ###################################
// ## TimeZone processing end
// ###################################
// ######################################################################
// ## Global constants and TimeZone processing
// ######################################################################

View File

@@ -59,10 +59,7 @@
<!-- Font Awesome -->
<link rel="stylesheet" href="lib/font-awesome/fontawesome.min.css">
<link rel="stylesheet" href="lib/font-awesome/solid.css">
<link rel="stylesheet" href="lib/font-awesome/brands.css">
<link rel="stylesheet" href="lib/font-awesome/v5-font-face.css">
<link rel="stylesheet" href="lib/font-awesome/all.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="lib/Ionicons/ionicons.min.css">
@@ -421,20 +418,15 @@
</li>
<!-- Integrations menu item -->
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php', 'appEvents.php' ) ) ){ echo 'active menu-open'; } ?>">
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'appEvents.php' ) ) ){ echo 'active menu-open'; } ?>">
<a href="#">
<i class="fa fa-fw fa-plug"></i> <span><?= lang('Navigation_Integrations');?></span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php', 'appEvents.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'appEvents.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
<li>
<div class="info-icon-nav"> </div>
<a href="workflows.php"><?= lang('Navigation_Workflows');?></a>
</li>
<li>
<div class="info-icon-nav"> </div>
<a href="appEvents.php"><?= lang('Navigation_AppEvents');?></a>
</li>
<li>
@@ -443,6 +435,11 @@
</ul>
</li>
<!-- workflows menu item -->
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('workflows.php') ) ){ echo 'active'; } ?>">
<a href="workflows.php"><i class="fa fa-fw fa-shuffle"></i> <span><?= lang('Navigation_Workflows');?></span></a>
</li>
<!-- system info menu item -->
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('systeminfo.php') ) ){ echo 'active'; } ?>">
<a href="systeminfo.php"><i class="fa fa-fw fa-info-circle"></i> <span><?= lang('Navigation_SystemInfo');?></span></a>

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "",
"Device_Title": "",
"Devices_Filters": "",
"Donations_Others": "",
"Donations_Platforms": "",
"Donations_Text": "",
"Donations_Title": "",
"ENABLE_PLUGINS_description": "",
"ENABLE_PLUGINS_name": "",
"ENCRYPTION_KEY_description": "",
@@ -367,6 +363,8 @@
"Maintenance_Title": "",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "",
"Maintenance_Tool_ExportCSV_noti": "",
"Maintenance_Tool_ExportCSV_noti_text": "",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "Tot",
"Device_Title": "Dispositius",
"Devices_Filters": "Filtres",
"Donations_Others": "Altres",
"Donations_Platforms": "Plataformes patrocinadores",
"Donations_Text": "Hola 👋! </br> Gràcies per fer clic en aquest element de menú 😅 </br> </br> Estic intentant recollir algunes donacions per fer un millor programari. També, m'ajudaria per cremar-me, i així recolzar aquesta aplicació més temps. Qualsevol petit (recurrent o no) patrocini em farà posar més esforç a aquesta aplicació. </br> M'agradaria escurçar la meva setmana de feina i en el temps restant enfocar-me en el NetAlertX. Així rebries més funcionalitat, una aplicació més neta i menys bugs. </br> </br> Gràcies per llegir-ho - Agraeixo qualsevol suport ❤🙏 </br> </br> TL;DR: Pel teu suport reps: </br> </br> <ul><li>Actualitzacions regulars per seguir les vostres dades i mantenir la família segura 🔄</li><li>Menys bugs 🐛🔫</li><li>Millor i més funcionalitat</li><li>Que no m'arribi el \"burn out\" 🔥🤯</li><li>Menys actualitzacions d'emergència 💨</li><li>Millors documentacions📚</li><li>Suport més ràpid i millor amb les incidències 🆘</li></ul> </br> 📧Correu electrònic <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si vols contactar o si hauria d'afegir altres programes de patrocini. </br>",
"Donations_Title": "Donacions",
"ENABLE_PLUGINS_description": "Habilita la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">connectors</a> funcionalitat. Carregar els connectors requereix més recursos de maquinari així podries voler desactivar-los en un sistema de baixos recursos.",
"ENABLE_PLUGINS_name": "Activa els connectors(Plugins)",
"ENCRYPTION_KEY_description": "Clau de xifrat de dades.",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Eines de manteniment",
"Maintenance_Tool_DownloadConfig": "Exportació de paràmetres",
"Maintenance_Tool_DownloadConfig_text": "Descarregueu una còpia de seguretat completa de la vostra configuració de configuració emmagatzemada al fitxer <code>app.conf</code>.",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "CSV Exportació de dispositius",
"Maintenance_Tool_ExportCSV_noti": "CSV Exportació",
"Maintenance_Tool_ExportCSV_noti_text": "Estàs segur que vols generar un fitxer CSV?",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Auto-refresc UI",
"VERSION_description": "Versió o valor timestamp per comprovar si l'aplicació va ser actualitzada.",
"VERSION_name": "Versió o timestamp",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "fa-square-plus",
"add_icon_event_tooltip": "Afegir nova icona",
"add_option_event_icon": "fa-square-plus",

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "",
"Device_Title": "",
"Devices_Filters": "",
"Donations_Others": "",
"Donations_Platforms": "",
"Donations_Text": "",
"Donations_Title": "",
"ENABLE_PLUGINS_description": "",
"ENABLE_PLUGINS_name": "",
"ENCRYPTION_KEY_description": "",
@@ -367,6 +363,8 @@
"Maintenance_Title": "",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "",
"Maintenance_Tool_ExportCSV_noti": "",
"Maintenance_Tool_ExportCSV_noti_text": "",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",

View File

@@ -16,8 +16,8 @@
"About_Design": "Entworfen für:",
"About_Exit": "Abmelden",
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
"AppEvents_AppEventProcessed": "",
"AppEvents_DateTimeCreated": "protokolliert",
"AppEvents_AppEventProcessed": "Verarbeitet",
"AppEvents_DateTimeCreated": "Protokolliert",
"AppEvents_Extra": "Extra",
"AppEvents_GUID": "Anwendungsereignis-GUID",
"AppEvents_Helper1": "Helfer 1",
@@ -30,7 +30,7 @@
"AppEvents_ObjectPlugin": "Verknüpfte Plugins",
"AppEvents_ObjectPrimaryID": "Primär ID",
"AppEvents_ObjectSecondaryID": "Sekundär ID",
"AppEvents_ObjectStatus": "Status (zum Log-Zeitpunkt)",
"AppEvents_ObjectStatus": "Protokollierter Status",
"AppEvents_ObjectStatusColumn": "Statusspalte",
"AppEvents_ObjectType": "Objekttyp",
"AppEvents_Plugin": "Plugin",
@@ -237,7 +237,7 @@
"Device_TableHead_Name": "Name",
"Device_TableHead_NetworkSite": "Netzwerkseite",
"Device_TableHead_Owner": "Eigentümer",
"Device_TableHead_Parent_MAC": "Übergeordnete MAC",
"Device_TableHead_Parent_MAC": "Übergeordneter Netzwerkknoten",
"Device_TableHead_Port": "Port",
"Device_TableHead_PresentLastScan": "Anwesenheit",
"Device_TableHead_RowID": "Zeilen ID",
@@ -256,10 +256,6 @@
"Device_Tablelenght_all": "Alle",
"Device_Title": "Geräte",
"Devices_Filters": "Filter",
"Donations_Others": "Andere",
"Donations_Platforms": "Sponsor-Platformen",
"Donations_Text": "Hey 👋! </br> Thanks for clicking on this menu item 😅 </br> </br> I'm trying to collect some donations to make you better software. Also, it would help me not to get burned out. Me burning out might mean end of support for this app. Any small (recurring or not) sponsorship makes me want ot put more effort into this app. I don't want to lock features (new plugins) behind paywalls 🔐. </br> Currently, I'm waking up 2h before work so I contribute to the app a bit. If I had some recurring income I could shorten my workweek and in the remaining time fully focus on NetAlertX. You'd get more functionality, a more polished app and less bugs. </br> </br> Thanks for reading - I'm super grateful for any support ❤🙏 </br> </br> TL;DR: By supporting me you get: </br> </br> <ul><li>Regular updates to keep your data and family safe 🔄</li><li>Less bugs 🐛🔫</li><li>Better and more functionality</li><li>I don't get burned out 🔥🤯</li><li>Less rushed releases 💨</li><li>Better docs📚</li><li>Quicker and better support with issues 🆘</li><li>Less grumpy me 😄</li></ul> </br> 📧Email me to <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> if you want to get in touch or if I should add other sponsorship platforms. </br>",
"Donations_Title": "Spenden",
"ENABLE_PLUGINS_description": "NOTUSED Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
"ENABLE_PLUGINS_name": "NOTUSED Enable Plugins",
"ENCRYPTION_KEY_description": "Schlüssel zur Datenverschlüsselung.",
@@ -393,6 +389,8 @@
"Maintenance_Title": "Wartungswerkzeuge",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "CSV Export",
"Maintenance_Tool_ExportCSV_noti": "CSV Export",
"Maintenance_Tool_ExportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei erstellen wollen?",
@@ -501,7 +499,7 @@
"NTFY_display_name": "NTFY",
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
"Navigation_About": "Über",
"Navigation_AppEvents": "",
"Navigation_AppEvents": "App-Ereignisse",
"Navigation_Devices": "Geräte",
"Navigation_Donations": "Spenden",
"Navigation_Events": "Ereignisse",
@@ -751,12 +749,38 @@
"WEBHOOK_SIZE_name": "Max payload size",
"WEBHOOK_URL_description": "Target URL starting with <code>http://</code> or <code>https://</code>.",
"WEBHOOK_URL_name": "Target URL",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "Aktionen",
"WF_Add": "",
"WF_Add_Condition": "Bedingung hinzufügen",
"WF_Add_Group": "Gruppe hinzufügen",
"WF_Condition_field": "Feld",
"WF_Condition_operator": "Betreiber",
"WF_Condition_value": "Wert",
"WF_Conditions": "Bedingungen",
"WF_Conditions_logic_rules": "Logikregeln",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "Auslöser",
"WF_Trigger_event_type": "Ereignistyp",
"WF_Trigger_type": "Auslösertyp",
"Webhooks_display_name": "Webhooks",
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_icon_event_tooltip": "Neues Symbol hinzufügen",
"add_option_event_icon": "",
"add_option_event_tooltip": "",
"add_option_event_tooltip": "Neuen Wert hinzufügen",
"copy_icons_event_icon": "",
"copy_icons_event_tooltip": "Icons aller Geräte mit demselben Gerätetyp überschreiben",
"devices_old": "Aktualisiert...",
@@ -764,7 +788,7 @@
"general_event_title": "",
"go_to_node_event_icon": "",
"go_to_node_event_tooltip": "",
"new_version_available": "",
"new_version_available": "Es ist eine neue Version verfügbar.",
"report_guid": "",
"report_guid_missing": "",
"report_select_format": "Format auswählen:",

View File

@@ -22,7 +22,7 @@
"AppEvents_ObjectPlugin": "Linked Plugin",
"AppEvents_ObjectPrimaryID": "Primary ID",
"AppEvents_ObjectSecondaryID": "Secondary ID",
"AppEvents_ObjectStatus": "Status (at log time)",
"AppEvents_ObjectStatus": "Logged Status",
"AppEvents_ObjectStatusColumn": "Status column",
"AppEvents_ObjectType": "Object Type",
"AppEvents_Plugin": "Plugin",
@@ -225,7 +225,7 @@
"Device_TableHead_Name": "Name",
"Device_TableHead_NetworkSite": "Network Site",
"Device_TableHead_Owner": "Owner",
"Device_TableHead_Parent_MAC": "Parent node MAC",
"Device_TableHead_Parent_MAC": "Parent network node",
"Device_TableHead_Port": "Port",
"Device_TableHead_PresentLastScan": "Presence",
"Device_TableHead_RowID": "Row ID",
@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "All",
"Device_Title": "Devices",
"Devices_Filters": "Filters",
"Donations_Others": "Others",
"Donations_Platforms": "Sponsor platforms",
"Donations_Text": "Hey 👋! </br> Thanks for clicking on this menu item 😅 </br> </br> I'm trying to collect some donations to make you better software. Also, it would help me not to get burned out, so I can support this app longer. Any small (recurring or not) sponsorship makes me want to put more effort into this app. </br> I'd love to shorten my work week and in the remaining time fully focus on NetAlertX. You'd get more functionality, a more polished app and less bugs. </br> </br> Thanks for reading - I'm grateful for any support ❤🙏 </br> </br> TL;DR: By supporting me you get: </br> </br> <ul><li>Regular updates to keep your data and family safe 🔄</li><li>Less bugs 🐛🔫</li><li>Better and more functionality</li><li>I don't get burned out 🔥🤯</li><li>Less rushed releases 💨</li><li>Better docs📚</li><li>Quicker and better support with issues 🆘</li></ul> </br> 📧Email me to <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> if you want to get in touch or if I should add other sponsorship platforms. </br>",
"Donations_Title": "Donations",
"ENABLE_PLUGINS_description": "Enables the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">plugins</a> functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.",
"ENABLE_PLUGINS_name": "Enable Plugins",
"ENCRYPTION_KEY_description": "Data encryption key.",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Maintenance tools",
"Maintenance_Tool_DownloadConfig": "Settings Export",
"Maintenance_Tool_DownloadConfig_text": "Download a full backup of your Settings configuration stored in the <code>app.conf</code> file.",
"Maintenance_Tool_DownloadWorkflows": "Workflows Export",
"Maintenance_Tool_DownloadWorkflows_text": "Download a full backup of your Workflows stored in the <code>workflows.json</code> file.",
"Maintenance_Tool_ExportCSV": "Devices Export (csv)",
"Maintenance_Tool_ExportCSV_noti": "Devices Export (csv)",
"Maintenance_Tool_ExportCSV_noti_text": "Are you sure you want to generate a CSV file?",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Auto-refresh UI",
"VERSION_description": "Version or timestamp helper value to check if app was upgraded.",
"VERSION_name": "Version or timestamp",
"WF_Action_Add": "Add Action",
"WF_Action_field": "Field",
"WF_Action_type": "Type",
"WF_Action_value": "Value",
"WF_Actions": "Actions",
"WF_Add": "Add Workflow",
"WF_Add_Condition": "Add Condition",
"WF_Add_Group": "Add Group",
"WF_Condition_field": "Field",
"WF_Condition_operator": "Operator",
"WF_Condition_value": "Value",
"WF_Conditions": "Conditions",
"WF_Conditions_logic_rules": "Logic rules",
"WF_Duplicate": "Duplicate Workflow",
"WF_Enabled": "Workflow enabled",
"WF_Export": "Export Workflow",
"WF_Export_Copy": "Copy the below workflow and import it where needed.",
"WF_Import": "Import Workflow",
"WF_Import_Copy": "Paste in the workflow you copied previously.",
"WF_Name": "Workflow name",
"WF_Remove": "Remove Workflow",
"WF_Remove_Copy": "Do you want to remove this workflow?",
"WF_Save": "Save Workflows",
"WF_Trigger": "Trigger",
"WF_Trigger_event_type": "Event type",
"WF_Trigger_type": "Trigger type",
"add_icon_event_icon": "fa-square-plus",
"add_icon_event_tooltip": "Add new icon",
"add_option_event_icon": "fa-square-plus",

View File

@@ -254,10 +254,6 @@
"Device_Tablelenght_all": "Todos",
"Device_Title": "Dispositivos",
"Devices_Filters": "",
"Donations_Others": "Otros",
"Donations_Platforms": "Plataforma de patrocinadores",
"Donations_Text": "¡Hola! 👋 </br> Gracias por hacer clic en este elemento 😅 del menú </br> </br>, estoy tratando de recolectar algunas donaciones para mejorar el software. Además, me ayudaría a no quemarse, por lo que puedo apoyar esta aplicación por más tiempo. Cualquier pequeño patrocinio (recurrente o no) me hace querer esforzarme más en esta aplicación. </br> Me encantaría acortar mi semana de trabajo y en el tiempo que me queda centrarme por completo en NetAlertX. Obtendrías más funcionalidad, una aplicación más pulida y menos errores. </br> </br> Gracias por leer, agradezco cualquier apoyo ❤🙏 </br> </br> TL; DR: Al apoyarme, obtienes: </br> </br> <ul><li>Actualizaciones periódicas para mantener tus datos y tu familia seguros 🔄</li><li>Menos errores 🐛🔫</li><li>Mejor y más funcionalidad</li><li>No me quemo 🔥🤯</li><li>Lanzamientos 💨menos apresurados</li> <li>Mejores documentos📚</li><li>Soporte más rápido y mejor con problemas 🆘</li></ul> </br> 📧Envíame un correo electrónico a <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si quieres ponerte en contacto o si debo añadir otras plataformas de patrocinio. </br>",
"Donations_Title": "Donaciones",
"ENABLE_PLUGINS_description": "Habilita la funcionalidad de los <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">complementos</a>. Cargar los complementos requiere más recursos de hardware, así que quizás quieras desactivarlo en hardware poco potente.",
"ENABLE_PLUGINS_name": "Habilitar complementos",
"ENCRYPTION_KEY_description": "",
@@ -391,6 +387,8 @@
"Maintenance_Title": "Herramientas de mantenimiento",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "Exportación CSV",
"Maintenance_Tool_ExportCSV_noti": "Exportación CSV",
"Maintenance_Tool_ExportCSV_noti_text": "¿Está seguro de que quiere generar un archivo CSV?",
@@ -748,6 +746,32 @@
"WEBHOOK_SIZE_name": "Tamaño máximo de carga útil",
"WEBHOOK_URL_description": "URL de destino comienza con <code>http://</code> o <code>https://</code>.",
"WEBHOOK_URL_name": "URL de destino",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"Webhooks_display_name": "Webhooks",
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
"Webhooks_settings_group": "<i class=\"fa fa-circle-nodes\"></i> Webhooks",

View File

@@ -8,7 +8,7 @@
"About_Design": "Conçu pour:",
"About_Exit": "Se déconnecter",
"About_Title": "Analyse de la sécurité du réseau et cadre de notification",
"AppEvents_AppEventProcessed": "",
"AppEvents_AppEventProcessed": "Traité(s)",
"AppEvents_DateTimeCreated": "Connecté",
"AppEvents_Extra": "Extra",
"AppEvents_GUID": "GUID dévénements de l'application",
@@ -22,7 +22,7 @@
"AppEvents_ObjectPlugin": "Plugin lié",
"AppEvents_ObjectPrimaryID": "Identité primaire",
"AppEvents_ObjectSecondaryID": "Identité secondaire",
"AppEvents_ObjectStatus": "État (au moment de l'enregistrement)",
"AppEvents_ObjectStatus": "État enregistré",
"AppEvents_ObjectStatusColumn": "Colonne d'état",
"AppEvents_ObjectType": "Type d'objet",
"AppEvents_Plugin": "Plugin",
@@ -225,7 +225,7 @@
"Device_TableHead_Name": "Nom",
"Device_TableHead_NetworkSite": "Site Réseau",
"Device_TableHead_Owner": "Propriétaire",
"Device_TableHead_Parent_MAC": "MAC du nœud principal",
"Device_TableHead_Parent_MAC": "Nœud réseau principal",
"Device_TableHead_Port": "Port",
"Device_TableHead_PresentLastScan": "Présence",
"Device_TableHead_RowID": "ID de colonne",
@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "Tous",
"Device_Title": "Appareils",
"Devices_Filters": "Filtres",
"Donations_Others": "Autres",
"Donations_Platforms": "Plateformes de sponsoring",
"Donations_Text": "Coucou 👋 ! </br> Merci d'avoir cliqué ici 😅 </br> </br> J'essaie de récolter des donations pour vous faire un meilleur produit. En plus, ça m'aide à éviter le burn-out pour développer cette application plus longtemps. Toute subvention (régulière ou non) me donne envie de poursuivre le développement de cette application.</br> J'aimerais réduire mon activité principale pour me concentrer plus longuement à NetAlertX. Vous auriez plus de fonctionnalités, une application mieux finie et avec moins de bugs.</br> </br> Merci de votre lecture - je vous suis reconnaissant pour votre soutien ❤🙏 </br> </br> Version courte : en me soutenant, vous aurez : </br> </br> <ul><li>Des mises à jour régulières pour protéger vos données personnelles et familiales 🔄</li><li>Moins de bugs 🐛🔫</li><li>Des fonctionnalités plus riches et plus nombreuses </li><li>Je ne me retrouve pas en burn-out 🔥🤯</li><li>Des versions moins à la va-vite 💨</li><li>une meilleure documentation <20></li><li>Un support meilleur et plus réactif en cas de problème 🆘</li></ul> </br> 📧Envoyez-moi un courriel à <a href='mailto :jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si vous voulez me contacter ou du je peux ajouter une autre plateforme de soutien. </br>",
"Donations_Title": "Dons",
"ENABLE_PLUGINS_description": "Active les fonctionnalités des <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">Plugins</a>. Charger des plugins nécessite plus de ressources, il est recommandé de les désactiver sur des systèmes de faible puissance.",
"ENABLE_PLUGINS_name": "Activer les Plugins",
"ENCRYPTION_KEY_description": "Clé de chiffrement des données.",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Outils de maintenance",
"Maintenance_Tool_DownloadConfig": "Export des paramètres",
"Maintenance_Tool_DownloadConfig_text": "Télécharger une sauvegarde complète de vos paramètres stockés dans le fichier <code>app.conf</code>.",
"Maintenance_Tool_DownloadWorkflows": "Export des workflows",
"Maintenance_Tool_DownloadWorkflows_text": "Télécharger une sauvegarde complète de vos workflows enregistrés dans le fichier <code>workflows.json</code>.",
"Maintenance_Tool_ExportCSV": "Export des appareils (csv)",
"Maintenance_Tool_ExportCSV_noti": "Export des appareils (csv)",
"Maintenance_Tool_ExportCSV_noti_text": "Êtes-vous sûr de vouloir générer un fichier CSV?",
@@ -465,7 +463,7 @@
"NETWORK_DEVICE_TYPES_description": "Les types d'appareils autorisés à être utilisés comme appareils réseau dans la vue Réseau. Le type d'appareils doit être identique au paramètre <code>Type</code> d'un appareil dans le détail des appareils. Ajouter le sur l'appareil grâce au bouton <code>+</code>. Ne pas supprimer de valeurs, seulement en ajouter de nouvelles.",
"NETWORK_DEVICE_TYPES_name": "Type d'appareil réseau",
"Navigation_About": "À propos",
"Navigation_AppEvents": "",
"Navigation_AppEvents": "Événements de l'appli",
"Navigation_Devices": "Appareils",
"Navigation_Donations": "Dons",
"Navigation_Events": "Évènements",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Rafraîchir automatiquement l'interface graphique",
"VERSION_description": "Valeur de la version ou du timestamp d'aide à vérifier si l'application a été mise à jour.",
"VERSION_name": "Version ou Timestamp",
"WF_Action_Add": "Ajouter une action",
"WF_Action_field": "Champ",
"WF_Action_type": "Type",
"WF_Action_value": "Valeur",
"WF_Actions": "Actions",
"WF_Add": "Ajouter un workflow",
"WF_Add_Condition": "Ajouter une condition",
"WF_Add_Group": "Ajouter un groupe",
"WF_Condition_field": "Champ",
"WF_Condition_operator": "Opérateur",
"WF_Condition_value": "Valeur",
"WF_Conditions": "Conditions",
"WF_Conditions_logic_rules": "Règles logiques",
"WF_Duplicate": "Dupliquer le workflow",
"WF_Enabled": "Workflow activé",
"WF_Export": "Exporter le workflow",
"WF_Export_Copy": "Copier le workflow ci-dessous pour pouvoir l'importer au besoin.",
"WF_Import": "Importer un workflow",
"WF_Import_Copy": "Coller le workflow précédemment copié.",
"WF_Name": "Nom du workflow",
"WF_Remove": "Supprimer le workflow",
"WF_Remove_Copy": "Voulez-vous supprimer ce workflow?",
"WF_Save": "Enregistrer les workflows",
"WF_Trigger": "Déclencheur",
"WF_Trigger_event_type": "Type d'événement",
"WF_Trigger_type": "Type de déclencheur",
"add_icon_event_icon": "fa-square-plus",
"add_icon_event_tooltip": "Ajouter une nouvelle icône",
"add_option_event_icon": "fa-square-plus",
@@ -718,4 +742,4 @@
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
}
}

42
front/php/templates/language/it_it.json Executable file → Normal file
View File

@@ -8,7 +8,7 @@
"About_Design": "Progettato per:",
"About_Exit": "Esci",
"About_Title": "Scanner di sicurezza di rete e framework di notifica",
"AppEvents_AppEventProcessed": "",
"AppEvents_AppEventProcessed": "Elaborato",
"AppEvents_DateTimeCreated": "Loggato",
"AppEvents_Extra": "Extra",
"AppEvents_GUID": "GUID evento applicazione",
@@ -22,7 +22,7 @@
"AppEvents_ObjectPlugin": "Plugin collegato",
"AppEvents_ObjectPrimaryID": "ID primario",
"AppEvents_ObjectSecondaryID": "ID secondario",
"AppEvents_ObjectStatus": "Stato (al momento del log)",
"AppEvents_ObjectStatus": "Stato registrato",
"AppEvents_ObjectStatusColumn": "Colonna di stato",
"AppEvents_ObjectType": "Tipo oggetto",
"AppEvents_Plugin": "Plugin",
@@ -225,7 +225,7 @@
"Device_TableHead_Name": "Nome",
"Device_TableHead_NetworkSite": "Sito di rete",
"Device_TableHead_Owner": "Proprietario",
"Device_TableHead_Parent_MAC": "MAC del nodo principale",
"Device_TableHead_Parent_MAC": "Nodo di rete principale",
"Device_TableHead_Port": "Porta",
"Device_TableHead_PresentLastScan": "Presenza",
"Device_TableHead_RowID": "ID riga",
@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "Tutti",
"Device_Title": "Dispositivi",
"Devices_Filters": "Filtri",
"Donations_Others": "Altri",
"Donations_Platforms": "Piattaforme sponsor",
"Donations_Text": "Hey 👋! </br> Grazie per aver cliccato su questa voce di menu 😅 </br> </br> Sto cercando di ricevere donazioni per poter fornire un software migliore. Inoltre potrebbe aiutarmi a non andare in burnout, in modo da poter supportare questa app più a lungo. Ogni piccola (ricorrente o non) sponsorizzazione mi invoglia a mettere più impegno nello sviluppo di questa app. </br> Mi piacerebbe accorciare la mia settimana lavorativa e nel tempo rimanente dedicarmi completamente a NetAlertX. Riceverai più funzionalità, un'applicazione più rifinita e con meno bug.</br> </br> Grazie per aver letto, ti sono grato per ogni tipo di supporto ❤🙏 </br> </br> TL;DR: Supportandomi otterrai: </br> </br> <ul><li>Aggiornamenti più regolari per mantenere i tuoi dati e la tua famiglia sicuri 🔄</li><li>Meno bug 🐛🔫</li><li>Funzionalità migliori e più numerose</li><li>Io non vado in burnout 🔥🤯</li><li>Rilasci meno affrettati 💨</li><li>Migliore documentazione 📚</li><li>Supporto migliore e più veloce in caso di problemi 🆘</li></ul> </br> 📧Invia una mail a <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> se vuoi contattarmi o chiedermi di aggiungere altre piattaforme di sponsorizzazione. </br>",
"Donations_Title": "Donazioni",
"ENABLE_PLUGINS_description": "Abilita la funzionalità <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">plugin</a>. Utilizzare i plugin richiede più risorse hardware, potresti voler disabilitare questa opzione sui dispositivi meno performanti.",
"ENABLE_PLUGINS_name": "Abilita plugin",
"ENCRYPTION_KEY_description": "Chiave di crittografia dei dati.",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Strumenti di manutenzione",
"Maintenance_Tool_DownloadConfig": "Impostazioni Esporta",
"Maintenance_Tool_DownloadConfig_text": "Scarica un backup completo della configurazione delle tue Impostazioni memorizzata nel file <code>app.conf</code>.",
"Maintenance_Tool_DownloadWorkflows": "Esportazione flussi di lavoro",
"Maintenance_Tool_DownloadWorkflows_text": "Scarica un backup completo dei tuoi flussi di lavoro archiviati nel file <code>workflows.json</code>.",
"Maintenance_Tool_ExportCSV": "Esporta dispositivi (csv)",
"Maintenance_Tool_ExportCSV_noti": "Esporta dispositivi (csv)",
"Maintenance_Tool_ExportCSV_noti_text": "Sei sicuro di voler generare un file CSV?",
@@ -465,7 +463,7 @@
"NETWORK_DEVICE_TYPES_description": "Quali tipi di dispositivo possono essere utilizzati come dispositivi di rete nella vista Rete. Il tipo di dispositivo deve corrispondere esattamente all'impostazione <code>Tipo</code> su un dispositivo specifico nei Dettagli dispositivo. Aggiungilo sul Dispositivo tramite il pulsante <code>+</code>. Non rimuovere i tipi esistenti, aggiungine solo di nuovi.",
"NETWORK_DEVICE_TYPES_name": "Tipi di dispositivi di rete",
"Navigation_About": "Informazioni su",
"Navigation_AppEvents": "",
"Navigation_AppEvents": "Eventi app",
"Navigation_Devices": "Dispositivi",
"Navigation_Donations": "Donazioni",
"Navigation_Events": "Eventi",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Aggiorna automaticamente la UI",
"VERSION_description": "Valore di supporto della versione o della marca temporale per verificare se l'app è stata aggiornata.",
"VERSION_name": "Versione o marca temporale",
"WF_Action_Add": "Aggiungi azione",
"WF_Action_field": "Campo",
"WF_Action_type": "Tipo",
"WF_Action_value": "Valore",
"WF_Actions": "Azioni",
"WF_Add": "Aggiungi flusso di lavoro",
"WF_Add_Condition": "Aggiungi condizione",
"WF_Add_Group": "Aggiungi gruppo",
"WF_Condition_field": "Campo",
"WF_Condition_operator": "Operatore",
"WF_Condition_value": "Valore",
"WF_Conditions": "Condizioni",
"WF_Conditions_logic_rules": "Regole logiche",
"WF_Duplicate": "Flusso di lavoro duplicato",
"WF_Enabled": "Flusso di lavoro abilitato",
"WF_Export": "Esporta flusso di lavoro",
"WF_Export_Copy": "Copia il flusso di lavoro sottostante e importalo dove necessario.",
"WF_Import": "Importa flusso di lavoro",
"WF_Import_Copy": "Incolla il flusso di lavoro copiato in precedenza.",
"WF_Name": "Nome flusso di lavoro",
"WF_Remove": "Rimuovi flusso di lavoro",
"WF_Remove_Copy": "Vuoi rimuovere questo flusso di lavoro?",
"WF_Save": "Salva flussi di lavoro",
"WF_Trigger": "Trigger",
"WF_Trigger_event_type": "Tipo evento",
"WF_Trigger_type": "Tipo di trigger",
"add_icon_event_icon": "fa-square-plus",
"add_icon_event_tooltip": "Aggiungi nuova icona",
"add_option_event_icon": "fa-square-plus",
@@ -718,4 +742,4 @@
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
}
}

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "Alle",
"Device_Title": "Enheter",
"Devices_Filters": "",
"Donations_Others": "Andre",
"Donations_Platforms": "Sponsorplattformer",
"Donations_Text": "Hei 👋! </br> Takk for at du klikket på dette menyelementet 😅 </br> </br> Jeg prøver å samle inn noen donasjoner for å lage bedre programvare. Dessuten ville det hjelpe meg å ikke bli utbrent, så jeg kan støtte denne appen lenger. Enhver liten (tilbakevendende eller ikke) sponsing gjør at jeg ønsker å legge mer innsats i denne appen. </br> Jeg vil gjerne forkorte arbeidsuken min og i den gjenværende tiden fokusere fullt ut på NetAlertX. Du vil få mer funksjonalitet, en mer polert app og mindre feil. </br> </br> Takk for at du leste - jeg er takknemlig for all støtte ❤🙏 </br> </br> TL;DR: Ved å støtte meg får du: </br> </br> <ul> <li>Jevne oppdateringer for å holde dataene dine og familien din trygge 🔄</li><li>Mindre feil 🐛🔫</li><li>Bedre og mer funksjonalitet</li><li>Jeg blir ikke utbrent 🔥🤯</li><li>Mindre forhastede utgivelser 💨</li><li>Bedre dokumenter📚</li><li>Raskere og bedre støtte med problemer 🆘</li></ul> </br> 📧 Send meg en e-post til <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> hvis du ønsker å komme i kontakt eller hvis jeg skal legge til andre sponsorplattformer. </br>",
"Donations_Title": "Donasjoner",
"ENABLE_PLUGINS_description": "Aktiverer <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">plugins</a> funksjonaliten. Å laste inn plugins krever mer maskinvareressurser, så det kan være lurt å deaktivere dem på et system med lav strøm.",
"ENABLE_PLUGINS_name": "Aktiver Plugins",
"ENCRYPTION_KEY_description": "",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Vedlikeholdsverktøy",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "Eksporter CSV",
"Maintenance_Tool_ExportCSV_noti": "Eksporter CSV",
"Maintenance_Tool_ExportCSV_noti_text": "Er du sikker på at du vil generere en CSV-fil?",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Oppdater UI automatisk",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "Wszystkie",
"Device_Title": "Urządzenia",
"Devices_Filters": "",
"Donations_Others": "Inne",
"Donations_Platforms": "Platforma Sponsora",
"Donations_Text": "Cześć 👋! </br> Dziękuje że kliknąłeś w to menu 😅 </br> </br> Próbuje zebrać trochę dotacji by ulepszyć to oprogramowanie. Także pomaga mi to się nie wypalić bym dalej mógł ulepszać to narzędzie. Każdy mały (powtarzający się lub nie) sponsoring sprawia że chce wkładać więcej pracy w tą aplikację. </br> Chciałbym skrócić mój tydzień pracy i w wolnym czasie skupić się nad NetAlertX. Dostawalibyście wtedy więcej funkcjonalności i były by one ciągle udoskonalane i posiadające mniej błędów. </br> </br> Dziękuję że to przeczytałeś - Jestem wdzięczny za pomoc ❤🙏</br> </br> TL;DR: Wspierając mnie otrzymujesz: </br> </br> <ul><li> Regularne aktualizacje by zapewnić twoim danym i rodzinie bezpieczeństwo 🔄 </li><li>Mniej błędów (bugów) 🐛🔫</li><li>Nowe i lepsze funkcjonalności</li><li>Nie tracę zapału do dalszego tworzenia 🔥🤯</li><li>Mniej pośpieszne, bardziej dopracowane wydania💨</li><li>Lepsza dokumentacja📚</li><li>Szybsza i lepsza pomoc w problemach🆘</li></ul> </br>📧Napisz E-mail do mnie na<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> jeżeli chcesz nawiązać kontakt albo czy powinien dodać kolejną platformę z sponsoringiem.</br>",
"Donations_Title": "Dotacje",
"ENABLE_PLUGINS_description": "Włącza funkcjonalność <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">pluginów</a>. Uruchomienie pluginów wymaga więcej zasobów sprzętu więcej możesz chcieć to wyłączyć dla słabszych systemów.",
"ENABLE_PLUGINS_name": "Włącz Pluginy",
"ENCRYPTION_KEY_description": "",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Narzędzia konserwacyjne",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "Eksport CSV",
"Maintenance_Tool_ExportCSV_noti": "Eksport CSV",
"Maintenance_Tool_ExportCSV_noti_text": "Jesteś pewien, że chcesz wygenerować plik CSV?",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Automatycznie odświeżaj UI",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",

View File

@@ -1,7 +1,7 @@
{
"API_CUSTOM_SQL_description": "Você pode especificar uma consulta SQL personalizada que irá gerar um arquivo JSON e, em seguida, expô-lo por meio do <a href=\"/php/server/query_json.php?file=table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> endpoint do arquivo</a>.",
"API_CUSTOM_SQL_name": "Endpoint customizado",
"API_TOKEN_description": "API token para comunicação segura, você pode gerar um valor ou inserir qualquer valor. Este é enviado no cabeçalho da requisição. Usado no <code>SYNC</code> plugin, servidor GraphQL .",
"API_TOKEN_description": "Token de API para comunicação segura. Gere um ou insira qualquer valor. Ele é enviado no cabeçalho da solicitação e usado no plugin <code>SYNC</code>, no servidor GraphQL e em outros endpoints de API. Você pode usar os endpoints de API para criar integrações personalizadas, conforme descrito na <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">documentação da API</a>.",
"API_TOKEN_name": "API token",
"API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
@@ -49,7 +49,7 @@
"BackDevices_DBTools_ImportCSVError": "O arquivo CSV não pode ser importado. Assegure que o formato está correto.",
"BackDevices_DBTools_ImportCSVMissing": "O arquivo CSV não foi localizado em <b>/config/devices.csv.</b>",
"BackDevices_DBTools_Purge": "As copias de segurança antigas foram excluidas",
"BackDevices_DBTools_UpdDev": "Dispositivo atualizado com sucesso",
"BackDevices_DBTools_UpdDev": "Dispositivo atualizado com sucesso. A lista de dispositivos principais pode levar algum tempo para recarregar se uma varredura estiver em andamento.",
"BackDevices_DBTools_UpdDevError": "Erro atualizando o dispositivo",
"BackDevices_DBTools_Upgrade": "Banco de dados atualizado com sucesso",
"BackDevices_DBTools_UpgradeError": "A atualização do banco de dados falhou",
@@ -61,17 +61,17 @@
"BackDevices_darkmode_enabled": "Modo Noturno Habilitado",
"CLEAR_NEW_FLAG_description": "Se habilitado (<code>0</code> está desativado), dispositivos marcados como<b>Novo Dispositivo</b> serão desmarcados se o limite (especificado em horas) exceder o tempo da <b>Primeira Sessão </b>.",
"CLEAR_NEW_FLAG_name": "",
"CustProps_cant_remove": "",
"CustProps_cant_remove": "Não é possível remover, é necessária pelo menos uma propriedade.",
"DAYS_TO_KEEP_EVENTS_description": "Esta é uma definição de manutenção. Especifica o número de dias de entradas de eventos que serão mantidas. Todos os eventos mais antigos serão eliminados periodicamente. Também se aplica ao Histórico de eventos do plug-in.",
"DAYS_TO_KEEP_EVENTS_name": "Excluir eventos mais antigos que",
"DISCOVER_PLUGINS_description": "",
"DISCOVER_PLUGINS_name": "",
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalhes do dispositivo",
"DISCOVER_PLUGINS_description": "Desative esta opção para acelerar a inicialização e a gravação de definições. Quando desativada, os plug-ins não são descobertos e não é possível adicionar novos plug-ins à definição<code>LOADED_PLUGINS</code>.",
"DISCOVER_PLUGINS_name": "Descobrir plugins",
"DevDetail_Copy_Device_Title": "Copiar detalhes do dispositivo",
"DevDetail_Copy_Device_Tooltip": "Copiar detalhes do dispositivo a partir da lista pendente. Tudo o que se encontra nesta página será substituído",
"DevDetail_CustomProperties_Title": "",
"DevDetail_CustomProps_reset_info": "",
"DevDetail_DisplayFields_Title": "",
"DevDetail_EveandAl_AlertAllEvents": "Alerte Todos os Eventos",
"DevDetail_CustomProperties_Title": "Propriedades personalizadas",
"DevDetail_CustomProps_reset_info": "Isto irá remover as suas propriedades personalizadas neste dispositivo e repô-las para o valor predefinido.",
"DevDetail_DisplayFields_Title": "Visualização",
"DevDetail_EveandAl_AlertAllEvents": "Eventos de alerta",
"DevDetail_EveandAl_AlertDown": "Alerta Desligado",
"DevDetail_EveandAl_Archived": "Arquivado",
"DevDetail_EveandAl_NewDevice": "Novo Dispositivo",
@@ -145,7 +145,7 @@
"DevDetail_Tab_EventsTableEvent": "Tipo de evento",
"DevDetail_Tab_EventsTableIP": "IP",
"DevDetail_Tab_EventsTableInfo": "Informações adicionais",
"DevDetail_Tab_Nmap": "<i class=\"fa fa-ethernet\"> </i>",
"DevDetail_Tab_Nmap": "<i class=\"fa fa-ethernet\"> </i> Nmap",
"DevDetail_Tab_NmapEmpty": "Nenhuma porta detectada com Nmap neste dispositivo.",
"DevDetail_Tab_NmapTableExtra": "Adicional",
"DevDetail_Tab_NmapTableHeader": "Resultados da verificação programada",
@@ -186,13 +186,13 @@
"DevDetail_button_Delete": "Excluir dispositivo",
"DevDetail_button_DeleteEvents": "Excluir eventos",
"DevDetail_button_DeleteEvents_Warning": "Tem certeza de que deseja excluir todos os eventos deste dispositivo?<br><br>(isso limpará o <b>Histórico de eventos</b> e as <b>sessões</b> e poderá ajudar com constantes (persistentes) notificações)",
"DevDetail_button_Delete_ask": "",
"DevDetail_button_Delete_ask": "Tem a certeza de que pretende apagar este dispositivo? Em vez disso, também o pode arquivar.",
"DevDetail_button_OverwriteIcons": "Substituir ícones",
"DevDetail_button_OverwriteIcons_Tooltip": "Substituir ícones de todos os dispositivos pelo mesmo tipo de dispositivo",
"DevDetail_button_OverwriteIcons_Warning": "Tem certeza de que deseja substituir todos os ícones de todos os dispositivos pelo mesmo tipo de dispositivo do tipo de dispositivo atual?",
"DevDetail_button_Reset": "Redefinir alterações",
"DevDetail_button_Save": "Salvar",
"DeviceEdit_ValidMacIp": "",
"DeviceEdit_ValidMacIp": "Insira um endereço <b>Mac</b> e <b>IP</b> válidos.",
"Device_MultiEdit": "Edição múltipla",
"Device_MultiEdit_Backup": "Cuidado, inserir valores errados abaixo interromperá sua configuração. Faça backup do seu banco de dados ou da configuração dos dispositivos primeiro (<a href=\"php/server/devices.php?action=ExportCSV\">clique para baixar <i class=\"fa-solid fa-download fa-bounce\"></i> </a>). Leia como recuperar dispositivos deste arquivo no <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/BACKUPS.md#scenario-2-corrupted-database\" target=\" _blank\">Documentação de backups</a>.",
"Device_MultiEdit_Fields": "Editar campos:",
@@ -208,7 +208,7 @@
"Device_Shortcut_Favorites": "Favoritos",
"Device_Shortcut_NewDevices": "Novos dispositivos",
"Device_Shortcut_OnlineChart": "Presença do dispositivo",
"Device_TableHead_AlertDown": "",
"Device_TableHead_AlertDown": "Alerta em baixo",
"Device_TableHead_Connected_Devices": "Conexões",
"Device_TableHead_CustomProps": "",
"Device_TableHead_Favorite": "Favorito",
@@ -227,11 +227,11 @@
"Device_TableHead_Owner": "Proprietário",
"Device_TableHead_Parent_MAC": "Nó pai MAC",
"Device_TableHead_Port": "Porta",
"Device_TableHead_PresentLastScan": "",
"Device_TableHead_PresentLastScan": "Presente",
"Device_TableHead_RowID": "ID da linha",
"Device_TableHead_Rowid": "ID da linha",
"Device_TableHead_SSID": "SSID",
"Device_TableHead_SourcePlugin": "",
"Device_TableHead_SourcePlugin": "Plugin de fonte",
"Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "Nó de sincronização",
"Device_TableHead_Type": "Tipo",
@@ -243,15 +243,11 @@
"Device_Tablelenght": "Mostrar entradas do _MENU_",
"Device_Tablelenght_all": "Todos",
"Device_Title": "Dispositivos",
"Devices_Filters": "",
"Donations_Others": "Outros",
"Donations_Platforms": "Plataformas de patrocinadores",
"Donations_Text": "Ei 👋! </br> Obrigado por clicar neste item de menu 😅 </br> </br> Estou tentando coletar algumas doações para melhorar o software. Além disso, isso me ajudaria a não ficar exausto, para que eu pudesse oferecer suporte a este aplicativo por mais tempo. Qualquer pequeno patrocínio (recorrente ou não) me faz querer colocar mais esforço neste aplicativo. </br> Eu adoraria encurtar minha semana de trabalho e no tempo restante focar totalmente no NetAlertX. Você obteria mais funcionalidades, um aplicativo mais sofisticado e menos bugs. </br> </br> Obrigado pela leitura - sou grato por qualquer apoio ❤🙏 </br> </br> TL;DR: Ao me apoiar, você obtém: </br> </br> <ul> <li>Atualizações regulares para manter seus dados e sua família seguros 🔄</li><li>Menos bugs 🐛🔫</li><li>Melhor e mais funcionalidade</li><li>Eu não fico exausto 🔥🤯</li><li>Lançamentos menos apressados 💨</li><li>Documentos melhores📚</li><li>Suporte melhor e mais rápido com problemas 🆘</li></ul> </br> 📧 Envie-me um e-mail para <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> se quiser entrar em contato ou se devo adicionar outras plataformas de patrocínio. </br>",
"Donations_Title": "Doações",
"Devices_Filters": "Filtros",
"ENABLE_PLUGINS_description": "Ativa a funcionalidade de <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">plugins</a>. Carregar plug-ins requer mais recursos de hardware, então você pode querer desativá-los em sistemas de baixa potência.",
"ENABLE_PLUGINS_name": "Habilitar plug-ins",
"ENCRYPTION_KEY_description": "",
"ENCRYPTION_KEY_name": "",
"ENCRYPTION_KEY_description": "Chave de encriptação de dados.",
"ENCRYPTION_KEY_name": "Chave de encriptação",
"Email_display_name": "Email",
"Email_icon": "<i class=\"fa fa-at\"></i>",
"Events_Loading": "Carregando...",
@@ -287,194 +283,196 @@
"Events_Tablelenght": "Mostrar entradas do _MENU_",
"Events_Tablelenght_all": "Todos",
"Events_Title": "Eventos",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"GRAPHQL_PORT_description": "O número da porta do servidor GraphQL. Certifique-se de que a porta seja exclusiva em todos os seus aplicativos neste host e nas instâncias do NetAlertX.",
"GRAPHQL_PORT_name": "Porta GraphQL",
"Gen_Action": "Ação",
"Gen_Add": "Adicionar",
"Gen_AddDevice": "",
"Gen_AddDevice": "Adicionar dispositivo",
"Gen_Add_All": "Adicionar todos",
"Gen_All_Devices": "Todos os Dispositivos",
"Gen_AreYouSure": "Tem certeza?",
"Gen_Backup": "Executar backup",
"Gen_Cancel": "Cancelar",
"Gen_Change": "",
"Gen_Change": "Alterar",
"Gen_Copy": "Executar",
"Gen_DataUpdatedUITakesTime": "OK - Pode levar um tempo para a interface do usuário ser atualizada se uma verificação estiver em execução.",
"Gen_Delete": "Excluir",
"Gen_DeleteAll": "Excluir todos",
"Gen_Description": "",
"Gen_Description": "Descrição",
"Gen_Error": "Erro",
"Gen_Filter": "Filtro",
"Gen_Generate": "",
"Gen_Generate": "Gerar",
"Gen_LockedDB": "ERRO - O banco de dados pode estar bloqueado - Verifique F12 Ferramentas de desenvolvimento -> Console ou tente mais tarde.",
"Gen_Offline": "Offline",
"Gen_Okay": "Ok",
"Gen_Online": "",
"Gen_Online": "Online",
"Gen_Purge": "Purge",
"Gen_ReadDocs": "Leia mais em documentos.",
"Gen_Remove_All": "Remover tudo",
"Gen_Remove_Last": "Remover o último",
"Gen_Reset": "",
"Gen_Reset": "Repor",
"Gen_Restore": "Executar restauração",
"Gen_Run": "Executar",
"Gen_Save": "Salvar",
"Gen_Saved": "Salvo",
"Gen_Search": "Procurar",
"Gen_Select": "",
"Gen_SelectIcon": "",
"Gen_SelectToPreview": "",
"Gen_Select": "Selecionar",
"Gen_SelectIcon": "<i class=\"fa-solid fa-chevron-down fa-fade\"></i>",
"Gen_SelectToPreview": "Selecionar para pré-visualizar",
"Gen_Selected_Devices": "Dispositivos selecionados:",
"Gen_Switch": "Trocar",
"Gen_Upd": "Atualizado com sucesso",
"Gen_Upd_Fail": "A atualização falhou",
"Gen_Update": "Atualizar",
"Gen_Update_Value": "Atualizar valor",
"Gen_ValidIcon": "",
"Gen_ValidIcon": "<i class=\"fa-solid fa-chevron-right \"></i>",
"Gen_Warning": "Aviso",
"Gen_Work_In_Progress": "Trabalho em andamento, um bom momento para enviar feedback em https://github.com/jokob-sk/NetAlertX/issues",
"Gen_create_new_device": "",
"Gen_create_new_device_info": "",
"Gen_create_new_device": "Novo dispositivo",
"Gen_create_new_device_info": "Os dispositivos são normalmente descobertos usando <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">plugins</a>. No entanto, em certos casos, pode ser necessário adicionar dispositivos manualmente. Para explorar cenários específicos, verifique a <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/REMOTE_NETWORKS.md\">documentação de Redes Remotas</a>.",
"General_display_name": "Geral",
"General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_description": "Esta é uma configuração de manutenção. Se habilitada (<code>0</code> is disabled), dispositivos marcados como <b>Novo Dispositivo</b> serão excluídos se o tempo de <b>Primeira Sessão</b> for mais antigo que as horas especificadas nesta configuração. Use esta configuração se quiser excluir automaticamente <b>Novos Dispositivos</b> após <code>X</code> horas.",
"HRS_TO_KEEP_NEWDEV_name": "Manter novos dispositivos por",
"HRS_TO_KEEP_OFFDEV_description": "",
"HRS_TO_KEEP_OFFDEV_name": "",
"LOADED_PLUGINS_description": "",
"LOADED_PLUGINS_name": "",
"LOG_LEVEL_description": "",
"LOG_LEVEL_name": "",
"Loading": "",
"Login_Box": "",
"Login_Default_PWD": "",
"Login_Info": "",
"Login_Psw-box": "",
"Login_Psw_alert": "",
"Login_Psw_folder": "",
"Login_Psw_new": "",
"Login_Psw_run": "",
"Login_Remember": "",
"Login_Remember_small": "",
"Login_Submit": "",
"Login_Toggle_Alert_headline": "",
"Login_Toggle_Info": "",
"Login_Toggle_Info_headline": "",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "",
"Maintenance_Status": "",
"Maintenance_Title": "",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_ExportCSV": "",
"Maintenance_Tool_ExportCSV_noti": "",
"Maintenance_Tool_ExportCSV_noti_text": "",
"Maintenance_Tool_ExportCSV_text": "",
"Maintenance_Tool_ImportCSV": "",
"Maintenance_Tool_ImportCSV_noti": "",
"Maintenance_Tool_ImportCSV_noti_text": "",
"Maintenance_Tool_ImportCSV_text": "",
"Maintenance_Tool_ImportConfig_noti": "",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_ImportPastedConfig": "",
"Maintenance_Tool_ImportPastedConfig_noti_text": "",
"Maintenance_Tool_ImportPastedConfig_text": "",
"Maintenance_Tool_arpscansw": "",
"Maintenance_Tool_arpscansw_noti": "",
"Maintenance_Tool_arpscansw_noti_text": "",
"Maintenance_Tool_arpscansw_text": "",
"Maintenance_Tool_backup": "",
"Maintenance_Tool_backup_noti": "",
"Maintenance_Tool_backup_noti_text": "",
"Maintenance_Tool_backup_text": "",
"Maintenance_Tool_check_visible": "",
"Maintenance_Tool_darkmode": "",
"Maintenance_Tool_darkmode_noti": "",
"Maintenance_Tool_darkmode_noti_text": "",
"Maintenance_Tool_darkmode_text": "",
"Maintenance_Tool_del_ActHistory": "",
"Maintenance_Tool_del_ActHistory_noti": "",
"Maintenance_Tool_del_ActHistory_noti_text": "",
"Maintenance_Tool_del_ActHistory_text": "",
"Maintenance_Tool_del_alldev": "",
"Maintenance_Tool_del_alldev_noti": "",
"Maintenance_Tool_del_alldev_noti_text": "",
"Maintenance_Tool_del_alldev_text": "",
"Maintenance_Tool_del_allevents": "",
"Maintenance_Tool_del_allevents30": "",
"Maintenance_Tool_del_allevents30_noti": "",
"Maintenance_Tool_del_allevents30_noti_text": "",
"Maintenance_Tool_del_allevents30_text": "",
"Maintenance_Tool_del_allevents_noti": "",
"Maintenance_Tool_del_allevents_noti_text": "",
"Maintenance_Tool_del_allevents_text": "",
"Maintenance_Tool_del_empty_macs": "",
"Maintenance_Tool_del_empty_macs_noti": "",
"Maintenance_Tool_del_empty_macs_noti_text": "",
"Maintenance_Tool_del_empty_macs_text": "",
"Maintenance_Tool_del_selecteddev": "",
"Maintenance_Tool_del_selecteddev_text": "",
"Maintenance_Tool_del_unknowndev": "",
"Maintenance_Tool_del_unknowndev_noti": "",
"Maintenance_Tool_del_unknowndev_noti_text": "",
"Maintenance_Tool_del_unknowndev_text": "",
"Maintenance_Tool_displayed_columns_text": "",
"Maintenance_Tool_drag_me": "",
"Maintenance_Tool_order_columns_text": "",
"Maintenance_Tool_purgebackup": "",
"Maintenance_Tool_purgebackup_noti": "",
"Maintenance_Tool_purgebackup_noti_text": "",
"Maintenance_Tool_purgebackup_text": "",
"Maintenance_Tool_restore": "",
"Maintenance_Tool_restore_noti": "",
"Maintenance_Tool_restore_noti_text": "",
"Maintenance_Tool_restore_text": "",
"Maintenance_Tool_upgrade_database_noti": "",
"Maintenance_Tool_upgrade_database_noti_text": "",
"Maintenance_Tool_upgrade_database_text": "",
"Maintenance_Tools_Tab_BackupRestore": "",
"Maintenance_Tools_Tab_Logging": "",
"Maintenance_Tools_Tab_Settings": "",
"Maintenance_Tools_Tab_Tools": "",
"Maintenance_Tools_Tab_UISettings": "",
"Maintenance_arp_status": "",
"Maintenance_arp_status_off": "",
"Maintenance_arp_status_on": "",
"Maintenance_built_on": "",
"Maintenance_current_version": "",
"Maintenance_database_backup": "",
"Maintenance_database_backup_found": "",
"Maintenance_database_backup_total": "",
"Maintenance_database_lastmod": "",
"Maintenance_database_path": "",
"Maintenance_database_rows": "",
"Maintenance_database_size": "",
"Maintenance_lang_selector_apply": "",
"Maintenance_lang_selector_empty": "",
"Maintenance_lang_selector_lable": "",
"Maintenance_lang_selector_text": "",
"Maintenance_new_version": "",
"Maintenance_themeselector_apply": "",
"Maintenance_themeselector_empty": "",
"Maintenance_themeselector_lable": "",
"Maintenance_themeselector_text": "",
"Maintenance_version": "",
"NETWORK_DEVICE_TYPES_description": "",
"NETWORK_DEVICE_TYPES_name": "",
"Navigation_About": "",
"HRS_TO_KEEP_OFFDEV_description": "Esta é uma configuração de manutenção <b>EXCLUINDO dispositivos</b>. Se habilitado (<code>0</code> está desabilitado), dispositivos que estão <b>Offline</b> e sua data e hora <b>Last Offline</b> são mais antigas que as horas especificadas nesta configuração, serão deletados. Use esta configuração se você quiser remover automaticamente <b>Dispositivos Offline</b> após <code>X</code> horas offline.",
"HRS_TO_KEEP_OFFDEV_name": "Eliminar dispositivos offline após",
"LOADED_PLUGINS_description": "Quais plugins carregar. Adicionar plugins pode deixar o aplicativo lento. Leia mais sobre quais plugins precisam ser habilitados, tipos ou opções de escaneamento na <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">documentação de plugins</a>. Plugins descarregados perderão as suas configurações. Somente plugins <code>desabilitados</code> podem ser descarregados.",
"LOADED_PLUGINS_name": "Plugins carregados",
"LOG_LEVEL_description": "Esta definição permite um registo mais detalhado. Útil para depurar eventos gravados na base de dados.",
"LOG_LEVEL_name": "Imprimir registo adicional",
"Loading": "Carregando...",
"Login_Box": "Introduza a sua palavra-passe",
"Login_Default_PWD": "A palavra-passe predefinida “123456” ainda está ativa.",
"Login_Info": "As palavra-passes são definidas por meio do plugin Definir palavra-passe. Verifique a <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/set_password\">documentação do SETPWD</a> se tiver problemas para fazer login.",
"Login_Psw-box": "Palavra-passe",
"Login_Psw_alert": "Alerta de palavra-passe!",
"Login_Psw_folder": "na pasta de configuração.",
"Login_Psw_new": "nova_palavra-passe",
"Login_Psw_run": "Para alterar a palavra-passe, executar:",
"Login_Remember": "Lembrar",
"Login_Remember_small": "(válido por 7 dias)",
"Login_Submit": "Iniciar sessão",
"Login_Toggle_Alert_headline": "Alerta de palavra-passe!",
"Login_Toggle_Info": "Informações sobre a palavra-passe",
"Login_Toggle_Info_headline": "Informações sobre a palavra-passe",
"Maint_PurgeLog": "Limpar o registo",
"Maint_RestartServer": "Reiniciar o servidor",
"Maint_Restart_Server_noti_text": "Tem certeza de que deseja reiniciar o servidor backend? Isso pode causar inconsistência no aplicativo. Faça backup da sua configuração primeiro. <br/> <br/> Nota: Isso pode levar alguns minutos.",
"Maintenance_Running_Version": "Versão instalada",
"Maintenance_Status": "Situação",
"Maintenance_Title": "Ferramentas de manutenção",
"Maintenance_Tool_DownloadConfig": "Exportação de definições",
"Maintenance_Tool_DownloadConfig_text": "Baixe um backup completo da configuração das Configurações armazenada no arquivo <code>app.conf</code>.",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "Exportação de dispositivos (csv)",
"Maintenance_Tool_ExportCSV_noti": "Exportação de dispositivos (csv)",
"Maintenance_Tool_ExportCSV_noti_text": "Tem a certeza de que pretende gerar um ficheiro CSV?",
"Maintenance_Tool_ExportCSV_text": "Gere um arquivo CSV (valor separado por vírgula) contendo a lista de dispositivos, incluindo os relacionamentos de rede entre os nós de rede e os dispositivos conectados. Você também pode acionar isso acessando esta URL <code>your_NetAlertX_url/php/server/devices.php?action=ExportCSV</code> ou habilitando o plugin <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a>.",
"Maintenance_Tool_ImportCSV": "Importação de dispositivos (csv)",
"Maintenance_Tool_ImportCSV_noti": "Importação de dispositivos (csv)",
"Maintenance_Tool_ImportCSV_noti_text": "Tem certeza de que deseja importar o arquivo CSV? Isso <b>sobrescreverá</b> completamente os dispositivos em seu banco de dados.",
"Maintenance_Tool_ImportCSV_text": "Antes de usar esta função, faça um backup. Importe um arquivo CSV (valores separados por vírgula) contendo a lista de dispositivos, incluindo os relacionamentos de rede entre os nós de rede e os dispositivos conectados. Para fazer isso, coloque o arquivo CSV chamado <b>devices.csv</b> na sua pasta <b>/config</b>.",
"Maintenance_Tool_ImportConfig_noti": "Importação de configurações (app.conf)",
"Maintenance_Tool_ImportPastedCSV": "Importação de dispositivos (csv) (colar)",
"Maintenance_Tool_ImportPastedCSV_noti_text": "Tem certeza de que deseja importar o CSV colado? Isso <b>sobrescreverá</b> completamente os dispositivos em seu banco de dados.",
"Maintenance_Tool_ImportPastedCSV_text": "Antes de usar esta função, faça um backup. Importe um arquivo CSV (valor separado por vírgula) contendo a lista de Dispositivos, incluindo os relacionamentos de Rede entre os Nós de Rede e os dispositivos conectados.",
"Maintenance_Tool_ImportPastedConfig": "Configurações Importar (colar)",
"Maintenance_Tool_ImportPastedConfig_noti_text": "Tem certeza de que deseja importar as configurações coladas? Isso irá <b>sobrescrever</b> completamente o arquivo <code>app.conf</code>.",
"Maintenance_Tool_ImportPastedConfig_text": "Importa o arquivo <code>app.conf</code> contendo todas as configurações do aplicativo. Você pode querer baixar primeiro o arquivo <code>app.conf</code> com a <b>Exportação de configurações</b>.",
"Maintenance_Tool_arpscansw": "Alternar arp-Scan (ligado/desligado)",
"Maintenance_Tool_arpscansw_noti": "Ativar ou desativar o arp-Scan",
"Maintenance_Tool_arpscansw_noti_text": "Quando o scanner é desligado, permanece desligado até ser novamente ativado.",
"Maintenance_Tool_arpscansw_text": "Ligar ou desligar o arp-scan. Quando o scan é desligado, permanece desligado até ser novamente ativado. As varreduras activas não são canceladas.",
"Maintenance_Tool_backup": "Cópia de segurança da BD",
"Maintenance_Tool_backup_noti": "Cópia de segurança da BD",
"Maintenance_Tool_backup_noti_text": "Tem a certeza de que pretende executar a cópia de segurança da BD? Certifique-se de que não está a ser executada nenhuma verificação.",
"Maintenance_Tool_backup_text": "Os backups do banco de dados estão localizados no diretório do banco de dados como um zip-archive, nomeado com a data de criação. Não há nenhum número máximo de backups.",
"Maintenance_Tool_check_visible": "Desmarque para esconder a coluna.",
"Maintenance_Tool_darkmode": "Modos de alternância (escuro/claro)",
"Maintenance_Tool_darkmode_noti": "Modos de alternância",
"Maintenance_Tool_darkmode_noti_text": "Após a mudança de tema, a página tenta recarregar-se para ativar a alteração. Se necessário, a cache deve ser limpa.",
"Maintenance_Tool_darkmode_text": "Alternar entre o modo escuro e o modo claro. Se a alternância não funcionar corretamente, tente limpar a cache do browser. A alteração ocorre no lado do servidor, pelo que afecta todos os dispositivos em utilização.",
"Maintenance_Tool_del_ActHistory": "Excluindo a atividade da rede",
"Maintenance_Tool_del_ActHistory_noti": "Excluir atividade de rede",
"Maintenance_Tool_del_ActHistory_noti_text": "Tem certeza de que deseja redefinir a atividade da rede?",
"Maintenance_Tool_del_ActHistory_text": "O gráfico de atividade da rede é redefinido. Isso não afeta os eventos.",
"Maintenance_Tool_del_alldev": "Excluir todos os dispositivos",
"Maintenance_Tool_del_alldev_noti": "Excluir dispositivos",
"Maintenance_Tool_del_alldev_noti_text": "Tem certeza de que deseja excluir todos os dispositivos?",
"Maintenance_Tool_del_alldev_text": "Antes de usar esta função, faça um backup. A exclusão não pode ser desfeita. Todos os dispositivos serão excluídos do banco de dados.",
"Maintenance_Tool_del_allevents": "Excluir eventos (Repor presença)",
"Maintenance_Tool_del_allevents30": "Excluir todos os eventos com mais de 30 dias",
"Maintenance_Tool_del_allevents30_noti": "Excluir eventos",
"Maintenance_Tool_del_allevents30_noti_text": "Tem certeza de que deseja excluir todos os eventos com mais de 30 dias? Isso redefiniu a presença de todos os dispositivos.",
"Maintenance_Tool_del_allevents30_text": "Antes de utilizar esta função, efectue uma cópia de segurança. A eliminação não pode ser anulada. Todos os eventos com mais de 30 dias na base de dados serão eliminados. Nesse momento, a presença de todos os dispositivos será reiniciada. Este facto pode dar origem a sessões inválidas. Isto significa que os dispositivos são apresentados como “presentes” apesar de estarem offline. Uma verificação enquanto o dispositivo em questão está online resolve o problema.",
"Maintenance_Tool_del_allevents_noti": "Excluir eventos",
"Maintenance_Tool_del_allevents_noti_text": "Tem certeza de que deseja excluir todos os eventos? Isso redefiniu a presença de todos os dispositivos.",
"Maintenance_Tool_del_allevents_text": "Antes de usar esta função, faça um backup. A exclusão não pode ser desfeita. Todos os eventos no banco de dados serão excluídos. Nesse momento, a presença de todos os dispositivos será redefinida. Isso pode levar a sessões inválidas. Isso significa que os dispositivos são exibidos como \"presente\" embora estejam offline. Uma varredura enquanto o dispositivo em questão é on-line resolve o problema.",
"Maintenance_Tool_del_empty_macs": "Excluir dispositivos com MACs vazios",
"Maintenance_Tool_del_empty_macs_noti": "Excluir dispositivos",
"Maintenance_Tool_del_empty_macs_noti_text": "Tem certeza de que deseja excluir todos os dispositivos com endereços MAC vazios?<br>(talvez você prefira arquivá-lo)",
"Maintenance_Tool_del_empty_macs_text": "Antes de usar esta função, faça um backup. A exclusão não pode ser desfeita. Todos os dispositivos sem MAC serão excluídos do banco de dados.",
"Maintenance_Tool_del_selecteddev": "Excluir dispositivos selecionados",
"Maintenance_Tool_del_selecteddev_text": "Antes de usar esta função, faça um backup. A exclusão não pode ser desfeita. Dispositivos selecionados serão excluídos do banco de dados.",
"Maintenance_Tool_del_unknowndev": "Excluir (desconhecido) Dispositivos",
"Maintenance_Tool_del_unknowndev_noti": "Excluir (desconhecido) Dispositivos",
"Maintenance_Tool_del_unknowndev_noti_text": "Tem certeza de que deseja excluir todos (desconhecido) e (nome não encontrado) dispositivos?",
"Maintenance_Tool_del_unknowndev_text": "Antes de usar esta função, faça um backup. A exclusão não pode ser desfeita. Todos os dispositivos nomeados (não conhecidos) serão excluídos do banco de dados.",
"Maintenance_Tool_displayed_columns_text": "Altere a visibilidade e a ordem das colunas na página <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Dispositivos</b></a>.",
"Maintenance_Tool_drag_me": "Arraste-me para reordenar colunas.",
"Maintenance_Tool_order_columns_text": "Maintenance_Tool_order_columns_text",
"Maintenance_Tool_purgebackup": "Limpar cópias de segurança",
"Maintenance_Tool_purgebackup_noti": "Limpar cópias de segurança",
"Maintenance_Tool_purgebackup_noti_text": "Tem certeza de que deseja excluir todos os backups exceto os últimos 3?",
"Maintenance_Tool_purgebackup_text": "Todos os outros backups serão excluídos exceto para os últimos 3 backups.",
"Maintenance_Tool_restore": "Restauração de DB",
"Maintenance_Tool_restore_noti": "Restauração de DB",
"Maintenance_Tool_restore_noti_text": "Tem a certeza de que quer executar a Restauração DB? Certifique-se de que nenhuma varredura está funcionando atualmente.",
"Maintenance_Tool_restore_text": "O backup mais recente pode ser restaurado através do botão, mas os backups mais antigos só podem ser restaurados manualmente. Após a restauração, faça uma verificação de integridade no banco de dados para segurança, caso o db estivesse atualmente em acesso de gravação quando o backup foi criado.",
"Maintenance_Tool_upgrade_database_noti": "Atualizar a base de dados",
"Maintenance_Tool_upgrade_database_noti_text": "Tem certeza de que deseja atualizar o banco de dados?<br>(talvez você prefira arquivá-lo)",
"Maintenance_Tool_upgrade_database_text": "Este botão actualizará a base de dados para ativar o gráfico Atividade de rede nas últimas 12 horas. Faça uma cópia de segurança da sua base de dados em caso de problemas.",
"Maintenance_Tools_Tab_BackupRestore": "Backup / Restauração",
"Maintenance_Tools_Tab_Logging": "Logs",
"Maintenance_Tools_Tab_Settings": "Configurações",
"Maintenance_Tools_Tab_Tools": "Ferramentas",
"Maintenance_Tools_Tab_UISettings": "Configurações de interface",
"Maintenance_arp_status": "Estado de digitalização",
"Maintenance_arp_status_off": "está actualmente desativado",
"Maintenance_arp_status_on": "scan(s) atualmente em execução",
"Maintenance_built_on": "Construído em",
"Maintenance_current_version": "Estás actualizado. Confira o que <a href=\"https://github.com/jokob-sk/NetAlertX/issues/138\" target=\"_blank\"> Estou trabalhando em</a>.",
"Maintenance_database_backup": "Backups DB",
"Maintenance_database_backup_found": "foram encontrados backups",
"Maintenance_database_backup_total": "uso total do disco",
"Maintenance_database_lastmod": "Última modificação",
"Maintenance_database_path": "Caminho da base de dados",
"Maintenance_database_rows": "Tabela (linhas)",
"Maintenance_database_size": "Tamanho de banco de dados",
"Maintenance_lang_selector_apply": "Aplicar",
"Maintenance_lang_selector_empty": "Selecionar a língua",
"Maintenance_lang_selector_lable": "Selecionar a língua",
"Maintenance_lang_selector_text": "A mudança ocorre no lado do cliente, por isso afeta apenas o navegador atual.",
"Maintenance_new_version": "Uma nova versão está disponível. Confira as <a href=\"https://github.com/jokob-sk/NetAlertX/releases\" target=\"_blank\">notas de lançamento</a>.",
"Maintenance_themeselector_apply": "Aplicar",
"Maintenance_themeselector_empty": "Escolha uma Skin",
"Maintenance_themeselector_lable": "Selecionar Skin",
"Maintenance_themeselector_text": "A mudança ocorre no lado do servidor, por isso afeta todos os dispositivos em uso.",
"Maintenance_version": "Atualizações de aplicativos",
"NETWORK_DEVICE_TYPES_description": "Quais tipos de dispositivos podem ser usados como dispositivos de rede na visualização de rede. O tipo de dispositivo tem de corresponder exatamente à configuração <code>Type</code> em um dispositivo específico em detalhes do dispositivo. Adicione-o no Dispositivo através do botão <code>+</code>. Não remova os tipos existentes, apenas adicione novos.",
"NETWORK_DEVICE_TYPES_name": "Tipos de dispositivo de rede",
"Navigation_About": "Sobre a",
"Navigation_AppEvents": "",
"Navigation_Devices": "",
"Navigation_Donations": "",
"Navigation_Events": "",
"Navigation_Integrations": "",
"Navigation_Maintenance": "",
"Navigation_Monitoring": "",
"Navigation_Network": "",
"Navigation_Notifications": "",
"Navigation_Plugins": "",
"Navigation_Devices": "Dispositivos",
"Navigation_Donations": "Doações",
"Navigation_Events": "Eventos",
"Navigation_Integrations": "Integrações",
"Navigation_Maintenance": "Manutenção",
"Navigation_Monitoring": "Acompanhamento",
"Navigation_Network": "Rede",
"Navigation_Notifications": "Notificações",
"Navigation_Plugins": "Plugins",
"Navigation_Presence": "",
"Navigation_Report": "",
"Navigation_Settings": "",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",
@@ -717,5 +741,5 @@
"settings_system_label": "",
"settings_update_item_warning": "",
"test_event_icon": "",
"test_event_tooltip": ""
"test_event_tooltip": "Guarde as alterações antes de testar as definições."
}

View File

@@ -8,7 +8,7 @@
"About_Design": "Разработан:",
"About_Exit": "Зарегистрироваться",
"About_Title": "Сетевой сканер и система уведомлений",
"AppEvents_AppEventProcessed": "",
"AppEvents_AppEventProcessed": "Обработанный",
"AppEvents_DateTimeCreated": "Журнал",
"AppEvents_Extra": "Дополнительно",
"AppEvents_GUID": "GUID события приложения",
@@ -22,7 +22,7 @@
"AppEvents_ObjectPlugin": "Связанный плагин",
"AppEvents_ObjectPrimaryID": "Первичный ID",
"AppEvents_ObjectSecondaryID": "Вторичный ID",
"AppEvents_ObjectStatus": "Состояние (во время входа в систему)",
"AppEvents_ObjectStatus": "Зарегистрированный статус",
"AppEvents_ObjectStatusColumn": "Колонка состояния",
"AppEvents_ObjectType": "Тип объекта",
"AppEvents_Plugin": "Плагин",
@@ -70,7 +70,7 @@
"DevDetail_Copy_Device_Tooltip": "Скопируйте данные с устройства из раскрывающегося списка. Все на этой странице будет перезаписано",
"DevDetail_CustomProperties_Title": "Пользовательские свойства",
"DevDetail_CustomProps_reset_info": "Это удалит ваши пользовательские свойства на этом устройстве и вернет их к значению по умолчанию.",
"DevDetail_DisplayFields_Title": "Дисплей",
"DevDetail_DisplayFields_Title": "Отображение",
"DevDetail_EveandAl_AlertAllEvents": "Оповещения о событиях",
"DevDetail_EveandAl_AlertDown": "Оповещение о доступности",
"DevDetail_EveandAl_Archived": "Архив",
@@ -225,7 +225,7 @@
"Device_TableHead_Name": "Имя",
"Device_TableHead_NetworkSite": "Сайт устройства",
"Device_TableHead_Owner": "Владелец",
"Device_TableHead_Parent_MAC": "MAC род. узла",
"Device_TableHead_Parent_MAC": "Родительский узел сети",
"Device_TableHead_Port": "Порт",
"Device_TableHead_PresentLastScan": "Присутствие",
"Device_TableHead_RowID": "ID строки",
@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "Все",
"Device_Title": "Устройства",
"Devices_Filters": "Фильтры",
"Donations_Others": "Другие",
"Donations_Platforms": "Спонсорские платформы",
"Donations_Text": "Привет 👋! </br> Спасибо, что нажали на этот пункт меню 😅 </br> </br> Я пытаюсь собрать пожертвования, чтобы сделать ваше программное обеспечение лучше. Кроме того, это поможет мне не перегореть, и я смогу дольше поддерживать это приложение. Любое небольшое спонсорство (периодическое или нет) вызывает у меня желание приложить больше усилий к этому приложению. </br> Мне бы хотелось сократить свою рабочую неделю и в оставшееся время полностью сосредоточиться на NetAlertX. Вы получите больше функциональности, более усовершенствованное приложение и меньше ошибок. </br> </br> Спасибо за прочтение буду благодарен за любую поддержку❤🙏 </br> </br> TL;DR: Поддержав меня, вы получаете: </br> </br> <ul><li>Регулярные обновления для обеспечения безопасности ваших данных и семьи 🔄</li><li>Меньше ошибок 🐛🔫</li><li>Лучшую функциональность➕</li><li>Я не выгораю 🔥🤯</li><li>Меньше поспешных релизов 💨</li><li>Лучшая документация📚</li><li>Быстрее и лучше поддержка по вопросам 🆘</li></ul> </br> 📧Напишите мне на <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> если вы хотите связаться или если следует добавить другие спонсорские платформы. </br>",
"Donations_Title": "Пожертвования",
"ENABLE_PLUGINS_description": "Включает функциональность <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">плагинов.</a> Загрузка плагинов требует больше аппаратных ресурсов, поэтому вы можете отключить их в маломощной системе.",
"ENABLE_PLUGINS_name": "Разрешить плагины",
"ENCRYPTION_KEY_description": "Ключ шифрования данных.",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Инструменты обслуживания",
"Maintenance_Tool_DownloadConfig": "Экспорт настроек",
"Maintenance_Tool_DownloadConfig_text": "Загрузите полную резервную копию конфигурации настроек, хранящуюся в файле <code>app.conf</code>.",
"Maintenance_Tool_DownloadWorkflows": "Экспорт Workflow",
"Maintenance_Tool_DownloadWorkflows_text": "Загрузите полную резервную копию ваших Workflow, хранящихся в файле <code> hairpflows.json </code>.",
"Maintenance_Tool_ExportCSV": "Экспорт устройств (csv)",
"Maintenance_Tool_ExportCSV_noti": "Экспорт устройств (csv)",
"Maintenance_Tool_ExportCSV_noti_text": "Вы уверены, что хотите создать файл CSV?",
@@ -465,7 +463,7 @@
"NETWORK_DEVICE_TYPES_description": "Какие типы устройств разрешено использовать в качестве сетевых устройств в представлении Сеть. Тип устройства должен точно соответствовать настройке <code>Type</code> для конкретного устройства в сведениях об устройстве. Добавьте его на устройство с помощью кнопки <code>+</code>. Не удаляйте существующие типы, а только добавляйте новые.",
"NETWORK_DEVICE_TYPES_name": "Типы сетевых устройств",
"Navigation_About": "О NetAlertX",
"Navigation_AppEvents": "",
"Navigation_AppEvents": "События приложения",
"Navigation_Devices": "Устройства",
"Navigation_Donations": "Пожертвования",
"Navigation_Events": "События",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Автоматическое обновление интерфейса",
"VERSION_description": "Вспомогательное значение версии или метки времени, позволяющее проверить, было ли приложение обновлено.",
"VERSION_name": "Версия или временная метка",
"WF_Action_Add": "Добавить действие",
"WF_Action_field": "Поле",
"WF_Action_type": "Тип",
"WF_Action_value": "Значение",
"WF_Actions": "Действия",
"WF_Add": "Добавить Workflow",
"WF_Add_Condition": "Добавить условие",
"WF_Add_Group": "Добавить группу",
"WF_Condition_field": "Поле",
"WF_Condition_operator": "Оператор",
"WF_Condition_value": "Значение",
"WF_Conditions": "Условия",
"WF_Conditions_logic_rules": "Правила логики",
"WF_Duplicate": "Дублировать Workflow",
"WF_Enabled": "Включить Workflow",
"WF_Export": "Экспорт Workflow",
"WF_Export_Copy": "Скопируйте приведенный ниже Workflow и импортируйте его, где это необходимо.",
"WF_Import": "Импорт Workflow",
"WF_Import_Copy": "Вставьте в Workflow, который вы скопировали ранее.",
"WF_Name": "Имя Workflow",
"WF_Remove": "Удалить Workflow",
"WF_Remove_Copy": "Вы хотите удалить этот Workflow?",
"WF_Save": "Сохранить Workflow",
"WF_Trigger": "Триггер",
"WF_Trigger_event_type": "Тип события",
"WF_Trigger_type": "Тип триггера",
"add_icon_event_icon": "fa-square-plus",
"add_icon_event_tooltip": "Добавить новую иконку",
"add_option_event_icon": "fa-square-plus",
@@ -718,4 +742,4 @@
"settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>",
"test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки."
}
}

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "",
"Device_Title": "Cihazlar",
"Devices_Filters": "",
"Donations_Others": "Diğerleri",
"Donations_Platforms": "",
"Donations_Text": "",
"Donations_Title": "",
"ENABLE_PLUGINS_description": "",
"ENABLE_PLUGINS_name": "",
"ENCRYPTION_KEY_description": "",
@@ -367,6 +363,8 @@
"Maintenance_Title": "",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "",
"Maintenance_Tool_ExportCSV_noti": "",
"Maintenance_Tool_ExportCSV_noti_text": "Bir CSV dosyası oluşturmak istediğinize emin misiniz?",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",

View File

@@ -8,7 +8,7 @@
"About_Design": "Призначений для:",
"About_Exit": "Вийти",
"About_Title": "Сканер безпеки мережі та структура сповіщень",
"AppEvents_AppEventProcessed": "",
"AppEvents_AppEventProcessed": "Оброблено",
"AppEvents_DateTimeCreated": "Зареєстровано",
"AppEvents_Extra": "Екстра",
"AppEvents_GUID": "GUID події програми",
@@ -22,7 +22,7 @@
"AppEvents_ObjectPlugin": "Пов’язаний плагін",
"AppEvents_ObjectPrimaryID": "Основний ідентифікатор",
"AppEvents_ObjectSecondaryID": "Вторинний ідентифікатор",
"AppEvents_ObjectStatus": "Статус (під час журналу)",
"AppEvents_ObjectStatus": "Зареєстрований статус",
"AppEvents_ObjectStatusColumn": "Колонка статусу",
"AppEvents_ObjectType": "Тип об'єкта",
"AppEvents_Plugin": "Плагін",
@@ -225,7 +225,7 @@
"Device_TableHead_Name": "Ім'я",
"Device_TableHead_NetworkSite": "Мережевий сайт",
"Device_TableHead_Owner": "Власник",
"Device_TableHead_Parent_MAC": "MAC батьківського вузла",
"Device_TableHead_Parent_MAC": "Узел родительской сети",
"Device_TableHead_Port": "Порт",
"Device_TableHead_PresentLastScan": "Присутність",
"Device_TableHead_RowID": "ID рядка",
@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "все",
"Device_Title": "Пристрої",
"Devices_Filters": "Фільтри",
"Donations_Others": "інші",
"Donations_Platforms": "Спонсорські платформи",
"Donations_Text": "Привіт 👋! </br> Дякуємо, що натиснули цей пункт меню 😅 </br> </br> Я намагаюся зібрати пожертви, щоб зробити ваше програмне забезпечення кращим. Крім того, це допоможе мені не згоріти, тому я можу підтримувати цю програму довше. Будь-яке невелике (постійне чи ні) спонсорство спонукає мене докласти більше зусиль до цієї програми. </br> Я хотів би скоротити свій робочий тиждень і в час, що залишився, повністю зосередитися на NetAlertX. Ви отримаєте більше функціональності, досконаліший додаток і менше помилок. </br> </br> Дякую, що прочитали я вдячний за будь-яку підтримку ❤🙏 </br> </br> TL;DR: Підтримуючи мене, ви отримуєте: </br> </br> <ul> <li>Регулярні оновлення для захисту ваших даних і родини 🔄</li><li>Менше помилок 🐛🔫</li><li>Краще та більше функціональність➕</li><li>Я не згорів 🔥🤯</li><li>Менш поспішних випусків 💨</li><li>Кращі документи📚</li><li>Швидша та краща підтримка із проблемами 🆘</li></ul> </br> 📧Напишіть мені електронною поштою на <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a>, якщо ви хочете зв’язатися з нами або якщо я маю додати інші платформи спонсорства. </br>",
"Donations_Title": "Пожертви",
"ENABLE_PLUGINS_description": "Вмикає функції <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">плагінів</a>. Завантаження плагінів вимагає більше апаратних ресурсів, тому ви можете вимкнути їх у системі з низьким енергоспоживанням.",
"ENABLE_PLUGINS_name": "Увімкнути плагіни",
"ENCRYPTION_KEY_description": "Ключ шифрування даних.",
@@ -367,6 +363,8 @@
"Maintenance_Title": "Інструменти обслуговування",
"Maintenance_Tool_DownloadConfig": "Експорт налаштувань",
"Maintenance_Tool_DownloadConfig_text": "Завантажте повну резервну копію конфігурації налаштувань, яка зберігається у файлі <code>app.conf</code>.",
"Maintenance_Tool_DownloadWorkflows": "Експорт робочих процесів",
"Maintenance_Tool_DownloadWorkflows_text": "Завантажте повну резервну копію робочих процесів, які зберігаються у файлі <code>workflows.json</code>.",
"Maintenance_Tool_ExportCSV": "Експорт пристроїв (csv)",
"Maintenance_Tool_ExportCSV_noti": "Експорт пристроїв (csv)",
"Maintenance_Tool_ExportCSV_noti_text": "Ви впевнені, що хочете створити файл CSV?",
@@ -465,7 +463,7 @@
"NETWORK_DEVICE_TYPES_description": "Які типи пристроїв дозволено використовувати як мережеві пристрої в поданні мережі. Тип пристрою має точно відповідати налаштуванню <code>Тип</code> на певному пристрої в Деталях пристрою. Додайте його на пристрій за допомогою кнопки <code>+</code>. Не видаляйте існуючі типи, лише додайте нові.",
"NETWORK_DEVICE_TYPES_name": "Типи мережевих пристроїв",
"Navigation_About": "про",
"Navigation_AppEvents": "",
"Navigation_AppEvents": "События приложения",
"Navigation_Devices": "Пристрої",
"Navigation_Donations": "Пожертви",
"Navigation_Events": "Події",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "Автоматичне оновлення інтерфейсу користувача",
"VERSION_description": "Допоміжне значення версії або позначки часу, щоб перевірити, чи було оновлено додаток.",
"VERSION_name": "Версія або позначка часу",
"WF_Action_Add": "Додати дію",
"WF_Action_field": "Поле",
"WF_Action_type": "Тип",
"WF_Action_value": "Значення",
"WF_Actions": "Дії",
"WF_Add": "Додати робочий процес",
"WF_Add_Condition": "Додати умову",
"WF_Add_Group": "Додати групу",
"WF_Condition_field": "Поле",
"WF_Condition_operator": "Оператор",
"WF_Condition_value": "Значення",
"WF_Conditions": "Умови",
"WF_Conditions_logic_rules": "Логічні правила",
"WF_Duplicate": "Дубльований робочий процес",
"WF_Enabled": "Робочий процес увімкнено",
"WF_Export": "Робочий процес експорту",
"WF_Export_Copy": "Скопіюйте наведений нижче робочий процес і імпортуйте його, де потрібно.",
"WF_Import": "Робочий процес імпорту",
"WF_Import_Copy": "Вставте робочий процес, який ви скопіювали раніше.",
"WF_Name": "Назва робочого процесу",
"WF_Remove": "Видалити робочий процес",
"WF_Remove_Copy": "Ви хочете видалити цей робочий процес?",
"WF_Save": "Зберегти робочі процеси",
"WF_Trigger": "Тригер",
"WF_Trigger_event_type": "Тип події",
"WF_Trigger_type": "Тип тригера",
"add_icon_event_icon": "фа-квадрат-плюс",
"add_icon_event_tooltip": "додати новий значок",
"add_option_event_icon": "фа-квадрат-плюс",
@@ -714,8 +738,8 @@
"settings_readonly": "Неможливо ЧИТАТИ або ЗАПИСАТИ <code>app.conf</code>. Спробуйте перезапустити контейнер і прочитайте <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/FILE_PERMISSIONS.md\" target=\"_blank\">документацію щодо дозволів на файли</a>",
"settings_saved": "<br/>Налаштування збережено. <br/> Перезавантаження... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
"settings_system_icon": "фа-твердий фа-передача",
"settings_system_label": "система",
"settings_system_label": "Система",
"settings_update_item_warning": "Оновіть значення нижче. Слідкуйте за попереднім форматом. <b>Перевірка не виконана.</b>",
"test_event_icon": "fa-vial-circle- check",
"test_event_tooltip": "Перш ніж перевіряти налаштування, збережіть зміни."
}
}

View File

@@ -244,10 +244,6 @@
"Device_Tablelenght_all": "所有",
"Device_Title": "设备",
"Devices_Filters": "",
"Donations_Others": "其他",
"Donations_Platforms": "赞助平台",
"Donations_Text": "嘿👋!</br> 感谢您点击此菜单项😅 </br> </br> 我正在尝试收集一些捐款来为您制作更好的软件。此外,这将有助于我避免精疲力竭,这样我就可以更长时间地支持这个应用程序。任何小额(无论是否经常性)赞助都会让我想在这个应用程序上投入更多精力。</br> 我希望缩短我的工作周,并在剩余的时间里完全专注于 NetAlertX。您将获得更多功能、更精致的应用程序和更少的错误。 </br> </br> 感谢阅读 - 我感谢任何支持 ❤🙏 </br> </br> TL;DR通过支持我您将获得</br> </br> <ul><li>定期更新以确保您的数据和家人安全🔄</li><li>更少的错误🐛🔫</li><li>更好、更多的功能➕</li><li>我不会精疲力竭🔥🤯</li><li>更不仓促的发布💨</li><li>更好的文档📚</li><li>更快、更好地解决问题🆘</li></ul> </br> 📧如果您想联系我或者我应该添加其他赞助平台,请给我发电子邮件至<a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a>。 </br>",
"Donations_Title": "捐款",
"ENABLE_PLUGINS_description": "启用<a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md\">插件</a>功能。加载插件需要更多硬件资源,因此您可能需要在低功耗系统上禁用它们。",
"ENABLE_PLUGINS_name": "启用插件",
"ENCRYPTION_KEY_description": "",
@@ -367,6 +363,8 @@
"Maintenance_Title": "维护工具",
"Maintenance_Tool_DownloadConfig": "",
"Maintenance_Tool_DownloadConfig_text": "",
"Maintenance_Tool_DownloadWorkflows": "",
"Maintenance_Tool_DownloadWorkflows_text": "",
"Maintenance_Tool_ExportCSV": "CSV 导出",
"Maintenance_Tool_ExportCSV_noti": "CSV 导出",
"Maintenance_Tool_ExportCSV_noti_text": "您确定要生成 CSV 文件吗?",
@@ -672,6 +670,32 @@
"UI_REFRESH_name": "自动刷新界面",
"VERSION_description": "",
"VERSION_name": "",
"WF_Action_Add": "",
"WF_Action_field": "",
"WF_Action_type": "",
"WF_Action_value": "",
"WF_Actions": "",
"WF_Add": "",
"WF_Add_Condition": "",
"WF_Add_Group": "",
"WF_Condition_field": "",
"WF_Condition_operator": "",
"WF_Condition_value": "",
"WF_Conditions": "",
"WF_Conditions_logic_rules": "",
"WF_Duplicate": "",
"WF_Enabled": "",
"WF_Export": "",
"WF_Export_Copy": "",
"WF_Import": "",
"WF_Import_Copy": "",
"WF_Name": "",
"WF_Remove": "",
"WF_Remove_Copy": "",
"WF_Save": "",
"WF_Trigger": "",
"WF_Trigger_event_type": "",
"WF_Trigger_type": "",
"add_icon_event_icon": "",
"add_icon_event_tooltip": "",
"add_option_event_icon": "",

View File

@@ -1,112 +1 @@
# 🔌 Plugins
NetAlertX supports additional plugins to extend its functionality, each with its own settings and options. Plugins can be loaded via the General -> `LOADED_PLUGINS` setting. For custom plugin development, refer to the [Plugin development guide](/docs/PLUGINS_DEV.md).
>[!NOTE]
> Please check this [Plugins debugging guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEBUG_PLUGINS.md) and the corresponding Plugin documentation in the below table if you are facing issues.
## ⚡ Quick start
> [!TIP]
> You can load additional Plugins via the General -> `LOADED_PLUGINS` setting.
1. Pick your `🔍 dev scanner` plugin (e.g. `ARPSCAN` or `NMAPDEV`), or import devices into the application with an `📥 importer` plugin. (See **✅Enabling plugins** below)
2. Pick a `▶️ publisher` plugin, if you want to send notifications. If you don't see a publisher you'd like to use, look at the [📚_publisher_apprise](/front/plugins/_publisher_apprise/) plugin which is a proxy for over 80 notification services.
3. Setup your [Network topology diagram](/docs/NETWORK_TREE.md)
4. Fine-tune [Notifications](/docs/NOTIFICATIONS.md)
5. [Backup your setup](/docs/BACKUPS.md)
6. Contribute and [Create custom plugins](/docs/PLUGINS_DEV.md)
## 📑 Available Plugins
Device-detecting plugins insert values into the `CurrentScan` database table. The plugins that are not required are safe to ignore, however, it makes sense to have at least some device-detecting plugins enabled, such as `ARPSCAN` or `NMAPDEV`.
| ID | Type | Description | Features | Required | Data source | Detailed docs |
|---------------|---------|--------------------------------------------|----------|----------|--------------|---------------------------------------------------------------------|
| `APPRISE` | ▶️ | Apprise notification proxy | | | Script | [_publisher_apprise](/front/plugins/_publisher_apprise/) |
| `ARPSCAN` | 🔍 | ARP-scan on current network | | | Script | [arp_scan](/front/plugins/arp_scan/) |
| `AVAHISCAN` | 🆎 | Avahi (mDNS-based) name resolution | | | Script | [avahi_scan](/front/plugins/avahi_scan/) |
| `ASUSWRT` | 🔍 | Import connected devices from AsusWRT | | | Script | [asuswrt_import](/front/plugins/asuswrt_import/) |
| `CSVBCKP` | ⚙ | CSV devices backup | | | Script | [csv_backup](/front/plugins/csv_backup/) |
| `CUSTPROP` | ⚙ | Managing custom device properties values | | Yes | Template | [custom_props](/front/plugins/custom_props/) |
| `DBCLNP` | ⚙ | Database cleanup | | Yes* | Script | [db_cleanup](/front/plugins/db_cleanup/) |
| `DDNS` | ⚙ | DDNS update | | | Script | [ddns_update](/front/plugins/ddns_update/) |
| `DHCPLSS` | 🔍/📥/🆎| Import devices from DHCP leases | | | Script | [dhcp_leases](/front/plugins/dhcp_leases/) |
| `DHCPSRVS` | ♻ | DHCP servers | | | Script | [dhcp_servers](/front/plugins/dhcp_servers/) |
| `FREEBOX` | 🔍/♻/🆎| Pull data and names from Freebox/Iliadbox | | | Script | [freebox](/front/plugins/freebox/) |
| `ICMP` | 🔍 | ICMP (ping) status checker | | | Script | [icmp_scan](/front/plugins/icmp_scan/) |
| `INTRNT` | 🔍 | Internet IP scanner | | | Script | [internet_ip](/front/plugins/internet_ip/) |
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
| `IPNEIGH` | 🔍 | Scan ARP (IPv4) and NDP (IPv6) tables | | | Script | [ipneigh](/front/plugins/ipneigh/) |
| `LUCIRPC` | 🔍 | Import connected devices from OpenWRT | | | Script | [luci_import](/front/plugins/luci_import/) |
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | | Script | [_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
| `NBTSCAN` | 🆎 | Nbtscan (NetBIOS-based) name resolution | | | Script | [nbtscan_scan](/front/plugins/nbtscan_scan/) |
| `NEWDEV` | ⚙ | New device template | | Yes | Template | [newdev_template](/front/plugins/newdev_template/) |
| `NMAP` | ♻ | Nmap port scanning & discovery | | | Script | [nmap_scan](/front/plugins/nmap_scan/) |
| `NMAPDEV` | 🔍 | Nmap dev scan on current network | | | Script | [nmap_dev_scan](/front/plugins/nmap_dev_scan/) |
| `NSLOOKUP` | 🆎 | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
| `OMDSDN` | 📥/🆎 | OMADA TP-Link import | 🖧 🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
| `PIHOLE` | 🔍/🆎/📥| Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
| `PUSHOVER` | ▶️ | Pushover notifications | | | Script | [_publisher_pushover](/front/plugins/_publisher_pushover/) |
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 🖧 🔄 | Yes | Script | [sync](/front/plugins/sync/) |
| `TELEGRAM` | ▶️ | Telegram notifications | | | Script | [_publisher_telegram](/front/plugins/_publisher_telegram/) |
| `UI` | ♻ | UI specific settings | | Yes | Template | [ui_settings](/front/plugins/ui_settings/) |
| `UNFIMP` | 🔍/📥/🆎| UniFi device import & sync | 🖧 | | Script | [unifi_import](/front/plugins/unifi_import/) |
| `VNDRPDT` | ⚙ | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) |
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
| `WOL` | ♻ | Automatic wake-on-lan | | | Script | [wake_on_lan](/front/plugins/wake_on_lan/) |
> \* The database cleanup plugin (`DBCLNP`) is not _required_ but the app will become unusable after a while if not executed.
> ❌ marked for removal
> ⌚It's recommended to use the same schedule interval for all plugins responsible for discovering new devices.
## Plugin types
| Plugin type | Icon | Description | When to run | Required | Data source [?](/docs/PLUGINS_DEV.md) |
| -------------- | ---- | ---------------------------------------------------------------- | ----------------------------------- | -------- | ------------------------------------- |
| publisher | ▶️ | Sending notifications to services. | `on_notification` | ✖ | Script |
| dev scanner | 🔍 | Create devices in the app, manages online/offline device status. | `schedule` | ✖ | Script / SQLite DB |
| name discovery | 🆎 | Discovers names of devices via various protocols. | `before_name_updates`, `schedule` | ✖ | Script |
| importer | 📥 | Importing devices from another service. | `schedule` | ✖ | Script / SQLite DB |
| system | ⚙ | Providing core system functionality. | `schedule` / always on | ✖/✔ | Script / Template |
| other | ♻ | Other plugins | misc | ✖ | Script / Template |
## Features
| Icon | Description |
| ---- | ------------------------------------------------------------ |
| 🖧 | Auto-imports the network topology diagram |
| 🔄 | Has the option to sync some data back into the plugin source |
## ✅Enabling plugins
Plugins can be enabled via Settings, and can be disabled as needed.
1. Research which plugin you'd like to use, enable `DISCOVER_PLUGINS` and load the required plugins in Settings via the `LOADED_PLUGINS` setting.
1. Save the changes and review the Settings of the newly loaded plugins.
1. Change the `<prefix>_RUN` Setting to the recommended or custom value as per the documentation of the given setting
- If using `schedule` on a `🔍 dev scanner` plugin, make sure the schedules are the same across all `🔍 dev scanner` plugins
### Disabling, Unloading and Ignoring plugins
1. Change the `<prefix>_RUN` Setting to `disabled` if you want to disable the plugin, but keep the settings
1. If you want to speed up the application, you can unload the plugin by unselecting it in the `LOADED_PLUGINS` setting.
- Careful, once you save the Settings Unloaded plugin settings will be lost (old `app.conf` files are kept in the `/config` folder)
1. You can completely ignore plugins by placing a `ignore_plugin` file into the plugin directory. Ignored plugins won't show up in the `LOADED_PLUGINS` setting.
## 🆕 Developing new custom plugins
If you want to develop a custom plugin, please read this [Plugin development guide](/docs/PLUGINS_DEV.md).
Plugins docs have been relocated. Check the new [Plugins Overview location](/docs/PLUGINS.md).

View File

@@ -446,6 +446,7 @@ def mqtt_start(db):
# # debug statement START 🔻
# if 'Moto' not in device["devName"]:
# mylog('none', [f"[{pluginName}] ALERT - ⚠⚠⚠⚠ DEBUGGING ⚠⚠⚠⚠ - this should not be in uncommented in production"])
# continue
# # debug statement END 🔺
@@ -462,7 +463,7 @@ def mqtt_start(db):
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_connection', 'calendar-end', device["devMac"])
# handle device_tracker
# device_tracker attributes
# IMPORTANT: shared payload - device_tracker attributes and individual sensors
devJson = {
"last_ip": device["devLastIP"],
"is_new": str(device["devIsNew"]),
@@ -477,6 +478,9 @@ def mqtt_start(db):
"network_parent_mac": device["devParentMAC"],
"network_parent_name": next((dev["devName"] for dev in devices if dev["devMAC"] == device["devParentMAC"]), "")
}
# bulk update device sensors in home assistant
publish_mqtt(mqtt_client, sensorConfig.state_topic, devJson) # REQUIRED, DON'T DELETE
# create and update is_present sensor
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'binary_sensor', 'is_present', 'wifi', device["devMac"])

View File

@@ -78,7 +78,8 @@ def main():
for device in filtered_devices:
is_online, output = execute_scan(device['devLastIP'], timeout, args)
mylog('verbose', [f'[{pluginName}] ip: "{device['devLastIP']}" is_online: "{is_online}"'])
mylog('verbose', [f"[{pluginName}] ip: {device['devLastIP']} is_online: {is_online}"])
if is_online:
plugin_objects.add_object(

View File

@@ -355,6 +355,34 @@
"string": "Если необходимо отключить проверку SSL/TLS для ресурсов HTTPS (для самоподписанных сертификатов и т. д.)"
}
]
},
{
"function": "only_reachable",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Only reachable"
}
],
"description": [
{
"language_code": "en_us",
"string": "Retrieve only devices that are reachable."
}
]
}
],
"database_column_definitions": [

View File

@@ -37,11 +37,17 @@ def main():
for entry in device_data:
mylog('verbose', [f'[{pluginName}] found: ', str(entry.mac).lower()])
name = str(entry.hostname)
if name.lower() == 'none':
name = '(unknown)'
plugin_objects.add_object(
primaryId = str(entry.mac).lower(),
secondaryId = entry.ip,
watched1 = entry.host,
watched2 = str(entry.hostname),
watched2 = name,
watched3 = "",
watched4 = "",
extra = pluginName,
@@ -67,7 +73,7 @@ def get_device_data():
else:
mylog('error', [f'[{pluginName}] login fail.'])
device_data = router.get_all_connected_devices(only_reachable=True)
device_data = router.get_all_connected_devices(only_reachable=get_setting_value("LUCIRPC_only_reachable"))
return device_data
if __name__ == '__main__':

View File

@@ -1,18 +1,60 @@
# Notifications User Guide
## Overview
Plugin supplying settings for Notification Processing.
This guide explains how the notification system works, including its dependencies, available notification types, and device-specific overrides.
### Notify on: `NTFPRCS_INCLUDED_SECTIONS`:
## Notification Dependencies
- `new_devices` - if a new device is detected
- `down_devices` - if a device with **Alert down** enabled (on a specific Device) disconnects
- `down_reconnected` - if a device, previously marked down and notified on, reconnects
- `events` - if an event for a device that has **Alert Events** enabled, is triggered
- `plugins` - if an event for a plugin, is triggered
The notification system relies on event data from devices and plugins. For notifications to function correctly:
- Devices must have alerts enabled in their settings.
- The notification processor uses the `NTFPRCS_INCLUDED_SECTIONS` setting to determine which types of notifications to send.
- Device-specific settings can override global notification rules.
Check the [Notifications guide](/docs/NOTIFICATIONS.md) for more details.
## Notification Types
### Usage
The following notification types are available based on the `NTFPRCS_INCLUDED_SECTIONS` setting:
### `new_devices`
- Notifies when a new device is detected on the network.
- Only sent if `new_devices` is enabled in `NTFPRCS_INCLUDED_SECTIONS`.
### `down_devices`
- Notifies when a device goes offline.
- The device must have **Alert Down** enabled in its settings.
- The notification is only sent if the device has not reconnected within the configured time window of `NTFPRCS_alert_down_time`.
### `down_reconnected`
- Notifies when a device that was previously reported as down reconnects.
- The device must have **Alert Down** enabled.
### `events`
- Notifies about specific events triggered by a device.
- The device must have **Alert Events** enabled in its settings.
- Includes events:
- `Connected`, `Down Reconnected`, `Disconnected`,`IP Changed`
- you can exclude devices with a custom where condition via the `NTFPRCS_event_condition` setting
### `plugins`
- Notifies when an event is triggered by a plugin.
- These notifications depend on the plugin's configuration of the `Watched_Value1-4` values and the `<plugin>_REPORT_ON` settings.
## Device-Specific Overrides
Certain notifications can be disabled per device:
### Alert Events Disabled
- If a device has **Alert Events** disabled, it will not receive notifications for general events (`events` section).
- This does not affect notifications for `down_devices`, `down_reconnected`, or `new_devices`.
### Alert Down Disabled
- If a device has **Alert Down** disabled, it will not receive notifications when it goes offline (`down_devices`) or reconnects (`down_reconnected`).
## Usage
- Review the **Settings** page to configure which notification types should be enabled.
- Ensure that device-specific alert settings align with your requirements.
For additional details, check the [Notifications Guide](/docs/NOTIFICATIONS.md).
- Check the Settings page for details.

View File

@@ -41,8 +41,8 @@ The OMADA SDN plugin aims at synchronizing data between NetAlertX and a TPLINK O
OMADA SDN limitation fixed by the plugin:
0. OMADA SDN can't use DNS for names and keep using MAC ref: https://community.tp-link.com/en/business/forum/topic/503782
- when you use an OMADA user Role = Administrator, the plugin will attempt to fix OMADA's shortcoming and populat the NAME field from NetAlertX (from DNS/DHCP/...)
![OMADA SDN account page](Oamadaomada_sdn_imp.png)
-
![OMADA SDN account page](omada_account_sample.png)
can not fix some of tplinks OMADA SDN own limitations/bugs:
1. OMADA SDN switches uplinks/downlinks is broken if the default router is not an OMADA native device

View File

@@ -285,16 +285,18 @@ def main():
mylog("verbose", [f"[{pluginName}] login to omada result is: {omada_login}"])
clients_list = callomada(["-t", "myomada", "clients"])
client_list_count = clients_list.count("\n")
mylog(
"verbose",
[f'[{pluginName}] clients found:"{clients_list.count("\n")}"\n{clients_list}'],
[f'[{pluginName}] clients found:"{client_list_count}"\n{clients_list}'],
)
switches_and_aps = callomada(["-t", "myomada", "devices"])
switches_and_aps_count = switches_and_aps.count("\n")
mylog(
"verbose",
[
f'[{pluginName}] omada devices (switches, access points) found:"{switches_and_aps.count("\n")}" \n {switches_and_aps}'
f'[{pluginName}] omada devices (switches, access points) found:"{switches_and_aps_count}" \n {switches_and_aps}'
],
)

View File

@@ -166,7 +166,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// get settings from the secured graphql endpoint
$.ajax({
url: "/php/server/query_graphql.php", // Replace with your GraphQL endpoint
url: "php/server/query_graphql.php", // Replace with your GraphQL endpoint
method: "POST",
contentType: "application/json",
data: JSON.stringify({

View File

@@ -48,7 +48,7 @@ require 'php/templates/header.php';
<script>
function fetchData(callback) {
$.get('/php/server/query_json.php', { file: 'user_notifications.json', nocache: Date.now() })
$.get('php/server/query_json.php', { file: 'user_notifications.json', nocache: Date.now() })
.done(function(response) {
if (response == "[]" || response == "") {
callback([]);

View File

@@ -7,8 +7,8 @@
<!-- Page ------------------------------------------------------------------ -->
<div class="content-wrapper">
<div class="content-wrapper" id="wf-content-wrapper">
<span class="helpIcon"> <a target="_blank" href="https://github.com/jokob-sk/NetAlertX/blob/main/docs/WORKFLOWS.md"><i class="fa fa-circle-question"></i></a></span>
<?php
require 'workflowsCore.php';
?>

View File

@@ -5,20 +5,30 @@
?>
<section class="content workflows">
<div id="workflowContainerWrap" class="bg-grey-dark color-palette col-sm-12 box-default box-info ">
<section class="content workflows col-sm-12 col-xs-12">
<div id="workflowContainerWrap" class="bg-grey-dark color-palette col-sm-12 col-xs-12 box-default box-info ">
<div id="workflowContainer"></div>
</div>
<div id="buttons" class="bottom-buttons col-sm-12">
<div class="add-workflow col-sm-12">
<button type="button" class="btn btn-primary add-workflow-btn col-sm-12" id="save">
<?= lang('Gen_Add');?>
<div id="buttons" class="bottom-buttons col-sm-12 col-xs-12">
<div class="add-workflow col-sm-4 col-xs-12">
<button type="button" class="btn btn-primary add-workflow-btn col-sm-12 col-xs-12" id="add">
<i class="fa fa-fw fa-plus"></i> <?= lang('WF_Add');?>
</button>
</div>
<div class="save-workflows col-sm-12">
<button type="button" class="btn btn-primary col-sm-12" id="save" onclick="saveWorkflows()">
<?= lang('DevDetail_button_Save');?>
<div class="import-wf col-sm-4 col-xs-12">
<button type="button" class="btn btn-primary col-sm-12 col-xs-12" id="import">
<i class="fa fa-fw fa-file-import"></i> <?= lang('WF_Import');?>
</button>
</div>
<div class="restart-app col-sm-4 col-xs-12">
<button type="button" class="btn btn-primary col-sm-12 col-xs-12" id="save" onclick="askRestartBackend()">
<i class="fa fa-fw fa-arrow-rotate-right"></i> <?= lang('Maint_RestartServer');?>
</button>
</div>
<div class="save-workflows col-xs-12">
<button type="button" class="btn btn-primary bg-green col-sm-12 col-xs-12" id="save" onclick="saveWorkflows()">
<i class="fa fa-fw fa-floppy-disk"></i> <?= lang('WF_Save');?>
</button>
</div>
</div>
@@ -29,26 +39,45 @@
let workflows = [];
let fieldOptions = [
"devMac", "devName", "devOwner", "devType", "devVendor", "devFavorite",
"devName", "devOwner", "devType", "devVendor", "devFavorite",
"devGroup", "devComments", "devFirstConnection", "devLastConnection",
"devLastIP", "devStaticIP", "devScan", "devLogEvents", "devAlertEvents",
"devAlertDown", "devSkipRepeated", "devLastNotification", "devPresentLastScan",
"devIsNew", "devLocation", "devIsArchived", "devParentMAC", "devParentPort",
"devIcon", "devGUID", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin"
"devIcon", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin"
];
let triggerTypes = [
"Devices"
];
let triggerEvents = [
"update", "insert", "delete"
];
let wfEnabledOptions = [
"Yes", "No"
];
let operatorTypes = [
"equals", "contains" , "regex"
];
let actionTypes = [
"update_field", "run_plugin", "delete_device"
"update_field", "delete_device"
];
let emptyWorkflow = {
"name": "New Workflow",
"trigger": {
"object_type": "Devices",
"event_type": "insert"
},
"conditions": [
],
"actions": [
]
};
// --------------------------------------
// Retrieve and process the data
function getData() {
@@ -57,13 +86,22 @@ function getData() {
getSetting()
$.get('php/server/query_json.php?file=workflows.json', function (res) {
$.get('php/server/query_json.php?file=workflows.json')
.done(function (res) {
workflows = res;
console.log(workflows);
updateWorkflowsJson(workflows);
renderWorkflows();
hideSpinner();
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.warn("Failed to load workflows.json:", textStatus, errorThrown);
workflows = []; // Set a default empty array to prevent crashes
updateWorkflowsJson(workflows);
renderWorkflows();
})
.always(function () {
hideSpinner(); // Ensure the spinner is hidden in all cases
});
}
@@ -90,22 +128,29 @@ function renderWorkflows() {
// Generate UI for a single workflow
function generateWorkflowUI(wf, wfIndex) {
let wfEnabled = (wf?.enabled ?? "No") == "Yes";
let $wfContainer = $("<div>", {
class: "workflow-card col-sm-12 col-sx-12",
class: "workflow-card panel col-sm-12 col-sx-12",
id: `wf-${wfIndex}-container`
});
// Workflow Name
let $wfLinkWrap = $("<div>",
{
class: "box box-solid box-primary ",
class: " ",
id: `wf-${wfIndex}-header`
}
)
let $wfEnabledIcon = $("<i>", {
class: `alignRight fa-regular ${wfEnabled ? "fa-dot-circle" : "fa-circle" }`
});
let $wfHeaderLink = $("<a>",
{
"class": "",
"class": "pointer ",
"data-toggle": "collapse",
"data-parent": "#workflowContainer",
"aria-expanded": false,
@@ -119,7 +164,7 @@ function generateWorkflowUI(wf, wfIndex) {
}
).text(wf.name)
$wfContainer.append($wfHeaderLink.append($wfLinkWrap.append($wfHeaderHeading)));
$wfContainer.append($wfHeaderLink.append($wfLinkWrap.append($wfHeaderHeading.append($wfEnabledIcon))));
// Collapsible panel start
@@ -131,13 +176,23 @@ function generateWorkflowUI(wf, wfIndex) {
let $wfCollapsiblePanel = $("<div>", {
class: `panel-collapse collapse ${isOpen ? 'in' : ''}`,
class: ` panel-collapse collapse ${isOpen ? 'in' : ''}`,
id: `wf-${wfIndex}-collapsible-panel`
});
let $wfEnabled = createEditableDropdown(
`[${wfIndex}].enabled`,
getString("WF_Enabled"),
wfEnabledOptions,
wfEnabled ? "Yes" :"No",
`wf-${wfIndex}-enabled`
);
$wfCollapsiblePanel.append($wfEnabled)
let $wfNameInput = createEditableInput(
`[${wfIndex}].name`,
"Workflow name",
getString("WF_Name"),
wf.name,
`wf-${wfIndex}-name`,
"workflow-name-input"
@@ -145,22 +200,26 @@ function generateWorkflowUI(wf, wfIndex) {
$wfCollapsiblePanel.append($wfNameInput)
let $triggersIcon = $("<i>", {
class: "fa-solid fa-bolt"
});
let $triggerTitle = $("<div>",
{
class:"section-title"
}
).text("Trigger:")
).append($triggersIcon).append(` ${getString("WF_Trigger")}:`)
// Trigger Section with dropdowns
let $triggerSection = $("<div>",
{
class: "box box-secondary col-sm-12 col-sx-12"
class: " col-sm-12 col-sx-12"
}
).append($triggerTitle);
let $triggerTypeDropdown = createEditableDropdown(
`[${wfIndex}].trigger.object_type`,
"Trigger Type",
getString("WF_Trigger_type"),
triggerTypes,
wf.trigger.object_type,
`wf-${wfIndex}-trigger-object-type`
@@ -168,39 +227,55 @@ function generateWorkflowUI(wf, wfIndex) {
let $eventTypeDropdown = createEditableDropdown(
`[${wfIndex}].trigger.event_type`,
"Event Type",
["update", "create", "delete"],
getString("WF_Trigger_event_type"),
triggerEvents,
wf.trigger.event_type,
`wf-${wfIndex}-trigger-event-type`
);
let $triggerIcon = $("<i>", {
class: "fa-solid fa-bolt bckg-icon-2-line"
});
$triggerSection.append($triggerIcon);
$triggerSection.append($triggerTypeDropdown);
$triggerSection.append($eventTypeDropdown);
$wfCollapsiblePanel.append($triggerSection);
// Conditions
let $conditionsTitle = $("<div>",
{
class:"section-title"
}
).text("Conditions:")
let $conditionsContainer = $("<div>").append($conditionsTitle);
let $conditionsIcon = $("<i>", {
class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270"
});
let $conditionsTitle = $("<div>", {
class: "section-title"
}).append($conditionsIcon).append(` ${getString("WF_Conditions")}:`);
let $conditionsContainer = $("<div>", {
class: "col-sm-12 col-sx-12"
}).append($conditionsTitle);
$conditionsContainer.append(renderConditions(wfIndex, `[${wfIndex}]`, 0, wf.conditions));
$wfCollapsiblePanel.append($conditionsContainer);
let $actionsIcon = $("<i>", {
class: "fa-solid fa-person-running fa-flip-horizontal"
});
let $actionsTitle = $("<div>",
{
class:"section-title"
}
).text("Actions:")
).append($actionsIcon).append(` ${getString("WF_Actions")}:`)
// Actions with action.field as dropdown
let $actionsContainer = $("<div>",
{
class: "actions-list box box-secondary"
class: "actions-list col-sm-12 col-sx-12 box "
}
).append($actionsTitle);
@@ -214,38 +289,49 @@ function generateWorkflowUI(wf, wfIndex) {
class: "panel col-sm-12 col-sx-12"
});
// Dropdown for action.field
let $fieldDropdown = createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].field`,
"Field",
fieldOptions,
action.field,
`wf-${wfIndex}-actionIndex-${actionIndex}-field`
);
// Dropdown for action.type
let $actionDropdown= createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].type`,
"Type",
getString("WF_Action_type"),
actionTypes,
action.field,
action.type,
`wf-${wfIndex}-actionIndex-${actionIndex}-type`
);
// Action Value Input (Editable)
let $actionValueInput = createEditableInput(
`[${wfIndex}].actions[${actionIndex}].value`,
"Value",
action.value,
`wf-${wfIndex}-actionIndex-${actionIndex}-value`,
"action-value-input"
);
$actionEl.append($actionDropdown);
$actionEl.append($fieldDropdown);
$actionEl.append($actionValueInput);
// how big should the background icon be
let numberOfLines = 1
if(action.type == "update_field")
{
numberOfLines = 3
// Dropdown for action.field
let $fieldDropdown = createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].field`,
getString("WF_Action_field"),
fieldOptions,
action.field,
`wf-${wfIndex}-actionIndex-${actionIndex}-field`
);
// Textbox for action.value
let $actionValueInput = createEditableInput(
`[${wfIndex}].actions[${actionIndex}].value`,
getString("WF_Action_value"),
action.value,
`wf-${wfIndex}-actionIndex-${actionIndex}-value`,
"action-value-input"
);
$actionEl.append($fieldDropdown);
$actionEl.append($actionValueInput);
}
// Actions
@@ -255,8 +341,8 @@ function generateWorkflowUI(wf, wfIndex) {
class: "fa-solid fa-trash"
});
let $actionRemoveButton = $("<button>", {
class: "btn btn-secondary remove-action btn-orange",
let $actionRemoveButton = $("<div>", {
class: "pointer remove-action red-hover-text",
actionIndex: actionIndex,
wfIndex: wfIndex
})
@@ -264,7 +350,14 @@ function generateWorkflowUI(wf, wfIndex) {
$actionRemoveButtonWrap.append($actionRemoveButton);
let $actionIcon = $("<i>", {
class: `fa-solid fa-person-running fa-flip-horizontal bckg-icon-${numberOfLines}-line `
});
$actionEl.prepend($actionIcon)
$actionElWrap.append($actionEl)
$actionElWrap.append($actionRemoveButtonWrap)
$actionsContainer.append($actionElWrap);
@@ -273,34 +366,66 @@ function generateWorkflowUI(wf, wfIndex) {
});
// add action button
let $actionAddButtonWrap = $("<div>", { class: "button-container col-sm-12 col-sx-12" });
let $actionAddIcon = $("<i>", {
class: "fa-solid fa-plus"
});
let $actionAddButton = $("<button>", {
class : "btn btn-secondary add-action",
let $actionAddButton = $("<div>", {
class : "pointer add-action green-hover-text",
lastActionIndex : lastActionIndex,
wfIndex: wfIndex
}).append($actionAddIcon).append("Add Action")
}).append($actionAddIcon).append(` ${getString("WF_Action_Add")}`)
$actionsContainer.append($actionAddButton)
$actionAddButtonWrap.append($actionAddButton)
$actionsContainer.append($actionAddButtonWrap)
let $wfRemoveButtonWrap = $("<div>", { class: "button-container col-sm-12 col-sx-12" });
let $wfRemoveButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" });
let $wfRemoveIcon = $("<i>", {
class: "fa-solid fa-trash"
});
let $wfRemoveButton = $("<button>", {
class: "btn btn-secondary remove-wf",
let $wfRemoveButton = $("<div>", {
class: "pointer remove-wf red-hover-text",
wfIndex: wfIndex
})
.append($wfRemoveIcon) // Add icon
.append("Remove Workflow"); // Add text
.append(` ${getString("WF_Remove")}`); // Add text
let $wfDuplicateButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" });
let $wfDuplicateIcon = $("<i>", {
class: "fa-solid fa-copy"
});
let $wfDuplicateButton = $("<div>", {
class: "pointer duplicate-wf green-hover-text",
wfIndex: wfIndex
})
.append($wfDuplicateIcon) // Add icon
.append(` ${getString("WF_Duplicate")}`); // Add text
let $wfExportButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" });
let $wfExportIcon = $("<i>", {
class: "fa-solid fa-file-export"
});
let $wfExportButton = $("<div>", {
class: "pointer export-wf green-hover-text",
wfIndex: wfIndex
})
.append($wfExportIcon) // Add icon
.append(` ${getString("WF_Export")}`); // Add text
$wfCollapsiblePanel.append($actionsContainer);
$wfCollapsiblePanel.append($wfDuplicateButtonWrap.append($wfDuplicateButton))
$wfCollapsiblePanel.append($wfExportButtonWrap.append($wfExportButton))
$wfCollapsiblePanel.append($wfRemoveButtonWrap.append($wfRemoveButton))
$wfContainer.append($wfCollapsiblePanel)
@@ -312,12 +437,21 @@ function generateWorkflowUI(wf, wfIndex) {
// Render conditions recursively
function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, conditions) {
let $conditionList = $("<div>", {
class: "condition-list panel panel-secondary col-sm-12 col-sx-12",
class: "condition-list panel col-sm-12 col-sx-12",
parentIndexPath: parentIndexPath
});
lastConditionIndex = 0
let $conditionListWrap = $("<div>", {
class: `condition-list-wrap ${conditionGroupsIndex==0?"col-sm-12":"col-sm-11"} col-sx-12`,
conditionGroupsIndex: conditionGroupsIndex
});
let $deleteConditionGroupWrap = $("<div>", {
class: "condition-group-wrap-del col-sm-1 col-sx-12"
});
$.each(conditions, function (conditionIndex, condition) {
let currentPath = `${parentIndexPath}.conditions[${conditionIndex}]`;
@@ -331,7 +465,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
let $logicDropdown = createEditableDropdown(
`${currentPath}.logic`,
"Logic Rules",
getString("WF_Conditions_logic_rules"),
["AND", "OR"],
condition.logic,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-logic` // id
@@ -347,6 +481,10 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
} else {
// INDIVIDUAL CONDITIONS
let $conditionIcon = $("<i>", {
class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270 bckg-icon-3-line "
});
let $conditionItem = $("<div>",
{
class: "panel col-sm-12 col-sx-12",
@@ -354,6 +492,8 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
wfIndex: wfIndex
});
$conditionItem.append($conditionIcon); // Append background icon
let $conditionItemsWrap = $("<div>",
{
class: "conditionItemsWrap col-sm-11 col-sx-12"
@@ -361,7 +501,8 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
// Create dropdown for condition field
let $fieldDropdown = createEditableDropdown(
`${currentPath}.field`,"Field",
`${currentPath}.field`,
getString("WF_Condition_field"),
fieldOptions,
condition.field,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-field`
@@ -370,7 +511,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
// Create dropdown for operator
let $operatorDropdown = createEditableDropdown(
`${currentPath}.operator`,
"Operator",
getString("WF_Condition_operator"),
operatorTypes,
condition.operator,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-operator`
@@ -379,12 +520,13 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
// Editable input for condition value
let $editableInput = createEditableInput(
`${currentPath}.value`,
"Condition Value",
getString("WF_Condition_value"),
condition.value,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-value`,
"condition-value-input"
);
$conditionItemsWrap.append($fieldDropdown); // Append field dropdown
$conditionItemsWrap.append($operatorDropdown); // Append operator dropdown
$conditionItemsWrap.append($editableInput); // Append editable input for condition value
@@ -393,8 +535,8 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
let $conditionRemoveButtonIcon = $("<i>", {
class: "fa-solid fa-trash"
});
let $conditionRemoveButton = $("<button>", {
class : "btn btn-secondary remove-condition col-sm-12 col-sx-12",
let $conditionRemoveButton = $("<div>", {
class : "pointer remove-condition red-hover-text",
conditionIndex : conditionIndex,
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
@@ -410,21 +552,21 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
lastConditionIndex = conditionIndex
});
let $buttonWrap = $("<div>", {
class: "button-wrap col-sm-12 col-sx-12"
let $addButtonWrap = $("<div>", {
class: "add-button-wrap col-sm-12 col-sx-12"
});
if (conditionGroupsIndex != 0) {
// Add Condition button
let $conditionAddWrap = $("<div>", { class: "button-container col-sx-12" });
let $conditionAddWrap = $("<div>", { class: "button-container col-sm-6 col-sx-12" });
let $conditionAddIcon = $("<i>", {
class: "fa-solid fa-plus"
});
let $conditionAddButton = $("<button>", {
class: "btn btn-secondary add-condition col-sx-12",
let $conditionAddButton = $("<div>", {
class: "pointer add-condition green-hover-text col-sx-12",
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
}).append($conditionAddIcon).append("Add Condition");
}).append($conditionAddIcon).append(` ${getString("WF_Add_Condition")}`);
$conditionAddWrap.append($conditionAddButton);
// Remove Condition Group button
@@ -432,35 +574,45 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
let $conditionGroupRemoveIcon = $("<i>", {
class: "fa-solid fa-trash"
});
let $conditionGroupRemoveButton = $("<button>", {
class: "btn btn-secondary remove-condition-group col-sx-12",
let $conditionGroupRemoveButton = $("<div>", {
class: "pointer remove-condition-group red-hover-text col-sx-12",
lastConditionIndex: lastConditionIndex,
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
}).append($conditionGroupRemoveIcon).append("Remove Condition Group");
}).append($conditionGroupRemoveIcon);
$conditionGroupRemoveWrap.append($conditionGroupRemoveButton);
$buttonWrap.append($conditionAddWrap);
$buttonWrap.append($conditionGroupRemoveWrap);
$addButtonWrap.append($conditionAddWrap);
$deleteConditionGroupWrap.append($conditionGroupRemoveWrap);
}
// Add Condition Group button
let $conditionsGroupAddWrap = $("<div>", { class: "button-container col-sm-12 col-sx-12" });
let $conditionsGroupAddWrap = $("<div>", { class: "button-container col-sm-6 col-sx-12" });
let $conditionsGroupAddIcon = $("<i>", {
class: "fa-solid fa-plus"
});
let $conditionsGroupAddButton = $("<button>", {
class: "btn btn-secondary add-condition-group col-sx-12",
let $conditionsGroupAddButton = $("<div>", {
class: "pointer add-condition-group green-hover-text col-sx-12",
wfIndex: wfIndex,
parentIndexPath: parentIndexPath
}).append($conditionsGroupAddIcon).append("Add Condition Group");
}).append($conditionsGroupAddIcon).append(` ${getString("WF_Add_Group")}`);
$conditionsGroupAddWrap.append($conditionsGroupAddButton);
$buttonWrap.append($conditionsGroupAddWrap);
$conditionList.append($buttonWrap);
$addButtonWrap.append($conditionsGroupAddWrap);
$conditionList.append($addButtonWrap);
$conditionListWrap.append($conditionList)
return $conditionList;
let $res = $("<div>", {
class: "condition-list-res col-sm-12 col-sx-12"
});
$res.append($conditionListWrap)
$res.append($deleteConditionGroupWrap)
return $res;
}
@@ -577,6 +729,8 @@ function updateWorkflowObject(newValue, jsonPath) {
console.log("Updated workflows:", workflows);
updateWorkflowsJson(workflows)
renderWorkflows();
}
@@ -661,7 +815,62 @@ function addWorkflow(workflows) {
// Function to remove a Workflow
function removeWorkflow(workflows, wfIndex) {
workflows.splice(wfIndex, 1);
showModalWarning ('<?= lang('WF_Remove');?>', '<?= lang('WF_Remove_Copy');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', `executeRemoveWorkflow`, wfIndex);
}
// ---------------------------------------------------
// Function to execute the remove of a Workflow
function executeRemoveWorkflow() {
workflows = getWorkflowsJson()
workflows.splice($('#modal-warning').attr("data-myparam-triggered-by"), 1);
updateWorkflowsJson(workflows)
// Re-render the UI
renderWorkflows();
}
// ---------------------------------------------------
// Function to duplicate a Workflow
function duplicateWorkflow(workflows, wfIndex) {
workflows.push(workflows[wfIndex])
updateWorkflowsJson(workflows)
// Re-render the UI
renderWorkflows();
}
// ---------------------------------------------------
// Function to export a Workflow
function exportWorkflow(workflows, wfIndex) {
// Add new icon as base64 string
showModalInput ('<i class="fa fa-file-export pointer"></i> <?= lang('WF_Export');?>', '<?= lang('WF_Export_Copy');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', null, null, JSON.stringify(workflows[wfIndex], null, 2));
}
// ---------------------------------------------------
// Function to import a Workflow
function importWorkflow(workflows, wfIndex) {
// Add new icon as base64 string
showModalInput ('<i class="fa fa-file-import pointer"></i> <?= lang('WF_Import');?>', '<?= lang('WF_Import_Copy');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'importWorkflowExecute', null, "" );
}
function importWorkflowExecute()
{
var json = JSON.parse($('#modal-input-textarea').val());
workflows = getWorkflowsJson()
workflows.push(json);
updateWorkflowsJson(workflows)
@@ -876,17 +1085,22 @@ function updateWorkflowsJson(workflows)
// Get empty workflow JSON
function getEmptyWorkflowJson()
{
return {
"name": "New Workflow",
"trigger": {
"object_type": "Devices",
"event_type": "create"
},
"conditions": [
],
"actions": [
]
}
return emptyWorkflow;
}
// ---------------------------------------------------
// Save workflows JSON
function saveWorkflows()
{
// encode for import
appConfBase64 = btoa(JSON.stringify(getWorkflowsJson()))
// import
$.post('php/server/query_replace_config.php', { base64data: appConfBase64, fileName: "workflows.json" }, function(msg) {
console.log(msg);
// showMessage(msg);
write_notification(`[WF]: ${msg}`, 'interrupt');
});
}
// ---------------------------------------------------
@@ -900,6 +1114,21 @@ $(document).on("click", ".remove-wf", function () {
removeWorkflow(getWorkflowsJson(), wfIndex);
});
$(document).on("click", ".duplicate-wf", function () {
let wfIndex = $(this).attr("wfindex");
duplicateWorkflow(getWorkflowsJson(), wfIndex);
});
$(document).on("click", ".export-wf", function () {
let wfIndex = $(this).attr("wfindex");
exportWorkflow(getWorkflowsJson(), wfIndex);
});
$(document).on("click", ".import-wf", function () {
let wfIndex = $(this).attr("wfindex");
importWorkflow(getWorkflowsJson(), wfIndex);
});
$(document).on("click", ".add-condition", function () {
let wfIndex = $(this).attr("wfindex");
let parentIndexPath = $(this).attr("parentIndexPath");

View File

@@ -35,12 +35,14 @@ nav:
- Security: SECURITY.md
- Advanced guides:
- Remote Networks: REMOTE_NETWORKS.md
- Notifications Guide: NOTIFICATIONS.md
- Notifications Guide: NOTIFICATIONS.md
- Name Resolution: NAME_RESOLUTION.md
- Authelia: AUTHELIA.md
- Performance: PERFORMANCE.md
- Reverse DNS: REVERSE_DNS.md
- Reverse Proxy: REVERSE_PROXY.md
- Webhooks (n8n): WEBHOOK_N8N.md
- Workflows: WORKFLOWS.md
- Help:
- Common issues: COMMON_ISSUES.md
- Random MAC: RANDOM_MAC.md
@@ -56,10 +58,12 @@ nav:
- Icons: ICONS.md
- Network Topology: NETWORK_TREE.md
- Troubleshooting:
- Inspecting Logs: LOGGING.md
- Debugging Tips: DEBUG_TIPS.md
- Debugging Invalid JSON: DEBUG_INVALID_JSON.md
- Debugging Plugins: DEBUG_PLUGINS.md
- Debugging Web UI Port: WEB_UI_PORT_DEBUG.md
- Debugging Workflows: WORKFLOWS_DEBUGGING.md
- Development:
- Plugin and app development:
- Environment Setup: DEV_ENV_SETUP.md

View File

@@ -196,8 +196,10 @@ def main ():
# Fetch new unprocessed events
new_events = workflow_manager.get_new_app_events()
mylog('debug', [f'[MAIN] Processing WORKFLOW new_events from get_new_app_events: {len(new_events)}'])
# Process each new event and check triggers
if new_events:
if len(new_events) > 0:
updateState("Workflows: Start")
update_api_flag = False
for event in new_events:

View File

@@ -75,7 +75,6 @@ class DB():
return arr
#-------------------------------------------------------------------------------
def upgradeDB(self):
"""
@@ -542,8 +541,7 @@ class DB():
# Plugin state
sql_Plugins_Objects = """ CREATE TABLE IF NOT EXISTS Plugins_Objects(
"Index" INTEGER,
Plugin TEXT NOT NULL,
ObjectGUID TEXT,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
@@ -561,6 +559,7 @@ class DB():
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
ObjectGUID TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
); """
self.sql.execute(sql_Plugins_Objects)
@@ -929,4 +928,19 @@ def get_all_devices(db):
return db.read(sql_devices_all)
#-------------------------------------------------------------------------------
def get_array_from_sql_rows(rows):
# Convert result into list of lists
arr = []
for row in rows:
if isinstance(row, sqlite3.Row):
arr.append(list(row)) # Convert row to list
elif isinstance(row, (tuple, list)):
arr.append(list(row)) # Already iterable, just convert to list
else:
arr.append([row]) # Handle single values safely
return arr
#-------------------------------------------------------------------------------

View File

@@ -71,7 +71,7 @@ class DeviceInstance:
self.db.sql.execute(f"""
UPDATE Devices SET {field} = ? WHERE devGUID = ?
""", (value, devGUID))
self.db.sql.commit()
self.db.commitDB()
# Delete a device by devGUID
def delete(self, devGUID):
@@ -81,4 +81,4 @@ class DeviceInstance:
raise ValueError(m)
self.db.sql.execute("DELETE FROM Devices WHERE devGUID = ?", (devGUID,))
self.db.sql.commit()
self.db.commitDB()

Some files were not shown because too many files have changed in this diff Show More