🔺GraphQL v0.1 + Devices table rebuild + removal of backend compatible scripts

This commit is contained in:
jokob-sk
2024-11-10 21:22:45 +11:00
parent 3cf3305b8f
commit 0bc8b39cec
76 changed files with 1622 additions and 2878 deletions

View File

@@ -15,7 +15,7 @@ ENV PATH="/opt/venv/bin:$PATH"
COPY . ${INSTALL_DIR}/ COPY . ${INSTALL_DIR}/
RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros \ RUN pip install graphene flask netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros \
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \ && bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \ && bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;" && bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"

View File

@@ -44,6 +44,8 @@ docker run -d --rm --network=host \
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` | |`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` |
|`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` | |`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` |
> You can override the default GraphQL port setting `GRAPHQL_PORT` (set to `20212`) by using the `APP_CONF_OVERRIDE` env variable.
### Docker paths ### Docker paths
> [!NOTE] > [!NOTE]

View File

@@ -58,38 +58,38 @@ Example JSON of the `table_devices.json` endpoint with two Devices (database row
{ {
"data": [ "data": [
{ {
"dev_MAC": "Internet", "devMac": "Internet",
"dev_Name": "Net - Huawei", "devName": "Net - Huawei",
"dev_DeviceType": "Router", "devType": "Router",
"dev_Vendor": null, "devVendor": null,
"dev_Group": "Always on", "devGroup": "Always on",
"dev_FirstConnection": "2021-01-01 00:00:00", "devFirstConnection": "2021-01-01 00:00:00",
"dev_LastConnection": "2021-01-28 22:22:11", "devLastConnection": "2021-01-28 22:22:11",
"dev_LastIP": "192.168.1.24", "devLastIP": "192.168.1.24",
"dev_StaticIP": 0, "devStaticIP": 0,
"dev_PresentLastScan": 1, "devPresentLastScan": 1,
"dev_LastNotification": "2023-01-28 22:22:28.998715", "devLastNotification": "2023-01-28 22:22:28.998715",
"dev_NewDevice": 0, "devIsNew": 0,
"dev_Network_Node_MAC_ADDR": "", "devParentMAC": "",
"dev_Network_Node_port": "", "devParentPort": "",
"dev_Icon": "globe" "devIcon": "globe"
}, },
{ {
"dev_MAC": "a4:8f:ff:aa:ba:1f", "devMac": "a4:8f:ff:aa:ba:1f",
"dev_Name": "Net - USG", "devName": "Net - USG",
"dev_DeviceType": "Firewall", "devType": "Firewall",
"dev_Vendor": "Ubiquiti Inc", "devVendor": "Ubiquiti Inc",
"dev_Group": "", "devGroup": "",
"dev_FirstConnection": "2021-02-12 22:05:00", "devFirstConnection": "2021-02-12 22:05:00",
"dev_LastConnection": "2021-07-17 15:40:00", "devLastConnection": "2021-07-17 15:40:00",
"dev_LastIP": "192.168.1.1", "devLastIP": "192.168.1.1",
"dev_StaticIP": 1, "devStaticIP": 1,
"dev_PresentLastScan": 1, "devPresentLastScan": 1,
"dev_LastNotification": "2021-07-17 15:40:10.667717", "devLastNotification": "2021-07-17 15:40:10.667717",
"dev_NewDevice": 0, "devIsNew": 0,
"dev_Network_Node_MAC_ADDR": "Internet", "devParentMAC": "Internet",
"dev_Network_Node_port": 1, "devParentPort": 1,
"dev_Icon": "shield-halved" "devIcon": "shield-halved"
} }
] ]
} }

View File

@@ -5,6 +5,8 @@ To download and install NetAlertX on the hardware/server directly use the `curl`
> [!NOTE] > [!NOTE]
> This is an Experimental feature 🧪 and it relies on community support. > This is an Experimental feature 🧪 and it relies on community support.
> >
> Looking for maintainers for this installation method 🙂
>
> There is no guarantee that the install script or any other script will gracefully handle other installed software. > There is no guarantee that the install script or any other script will gracefully handle other installed software.
> Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**. > Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**.

View File

@@ -170,20 +170,20 @@ This SQL query is executed on the `app.db` SQLite database file.
> SQL query example: > SQL query example:
> >
> ```SQL > ```SQL
> SELECT dv.dev_Name as Object_PrimaryID, > SELECT dv.devName as Object_PrimaryID,
> cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, > cast(dv.devLastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID,
> datetime() as DateTime, > datetime() as DateTime,
> ns.Service as Watched_Value1, > ns.Service as Watched_Value1,
> ns.State as Watched_Value2, > ns.State as Watched_Value2,
> 'null' as Watched_Value3, > 'null' as Watched_Value3,
> 'null' as Watched_Value4, > 'null' as Watched_Value4,
> ns.Extra as Extra, > ns.Extra as Extra,
> dv.dev_MAC as ForeignKey > dv.devMac as ForeignKey
> FROM > FROM
> (SELECT * FROM Nmap_Scan) ns > (SELECT * FROM Nmap_Scan) ns
> LEFT JOIN > LEFT JOIN
> (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv > (SELECT devName, devMac, devLastIP FROM Devices) dv
> ON ns.MAC = dv.dev_MAC > ON ns.MAC = dv.devMac
> ``` > ```
> >
> Required `CMD` setting example with above query (you can set `"type": "label"` if you want it to make uneditable in the UI): > Required `CMD` setting example with above query (you can set `"type": "label"` if you want it to make uneditable in the UI):
@@ -192,7 +192,7 @@ This SQL query is executed on the `app.db` SQLite database file.
> { > {
> "function": "CMD", > "function": "CMD",
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}, > "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
> "default_value":"SELECT dv.dev_Name as Object_PrimaryID, cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC", > "default_value":"SELECT dv.devName as Object_PrimaryID, cast(dv.devLastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT devName, devMac, devLastIP FROM Devices) dv ON ns.MAC = dv.devMac",
> "options": [], > "options": [],
> "localized": ["name", "description"], > "localized": ["name", "description"],
> "name" : [{ > "name" : [{
@@ -460,7 +460,7 @@ Below are some general additional notes, when defining `params`:
- `"name":"name_value"` - is used as a wildcard replacement in the `CMD` setting value by using curly brackets `{name_value}`. The wildcard is replaced by the result of the `"value" : "param_value"` and `"type":"type_value"` combo configuration below. - `"name":"name_value"` - is used as a wildcard replacement in the `CMD` setting value by using curly brackets `{name_value}`. The wildcard is replaced by the result of the `"value" : "param_value"` and `"type":"type_value"` combo configuration below.
- `"type":"<sql|setting>"` - is used to specify the type of the params, currently only 2 supported (`sql`,`setting`). - `"type":"<sql|setting>"` - is used to specify the type of the params, currently only 2 supported (`sql`,`setting`).
- `"type":"sql"` - will execute the SQL query specified in the `value` property. The sql query needs to return only one column. The column is flattened and separated by commas (`,`), e.g: `SELECT dev_MAC from DEVICES` -> `Internet,74:ac:74:ac:74:ac,44:44:74:ac:74:ac`. This is then used to replace the wildcards in the `CMD` setting. - `"type":"sql"` - will execute the SQL query specified in the `value` property. The sql query needs to return only one column. The column is flattened and separated by commas (`,`), e.g: `SELECT devMac from DEVICES` -> `Internet,74:ac:74:ac:74:ac,44:44:74:ac:74:ac`. This is then used to replace the wildcards in the `CMD` setting.
- `"type":"setting"` - The setting code name. A combination of the value from `unique_prefix` + `_` + `function` value, or otherwise the code name you can find in the Settings page under the Setting display name, e.g. `PIHOLE_RUN`. - `"type":"setting"` - The setting code name. A combination of the value from `unique_prefix` + `_` + `function` value, or otherwise the code name you can find in the Settings page under the Setting display name, e.g. `PIHOLE_RUN`.
- `"value": "param_value"` - Needs to contain a setting code name or SQL query without wildcards. - `"value": "param_value"` - Needs to contain a setting code name or SQL query without wildcards.
- `"timeoutMultiplier" : true` - used to indicate if the value should multiply the max timeout for the whole script run by the number of values in the given parameter. - `"timeoutMultiplier" : true` - used to indicate if the value should multiply the max timeout for the whole script run by the number of values in the given parameter.
@@ -474,13 +474,13 @@ Below are some general additional notes, when defining `params`:
> "params" : [{ > "params" : [{
> "name" : "ips", > "name" : "ips",
> "type" : "sql", > "type" : "sql",
> "value" : "SELECT dev_LastIP from DEVICES", > "value" : "SELECT devLastIP from DEVICES",
> "timeoutMultiplier" : true > "timeoutMultiplier" : true
> }, > },
> { > {
> "name" : "macs", > "name" : "macs",
> "type" : "sql", > "type" : "sql",
> "value" : "SELECT dev_MAC from DEVICES" > "value" : "SELECT devMac from DEVICES"
> }, > },
> { > {
> "name" : "timeout", > "name" : "timeout",
@@ -527,7 +527,7 @@ The UI component is defined as a JSON object containing a list of `elements`. Ea
```json ```json
{ {
"function": "dev_Icon", "function": "devIcon",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -536,7 +536,7 @@ The UI component is defined as a JSON object containing a list of `elements`. Ea
"elementOptions": [ "elementOptions": [
{ "cssClasses": "input-group-addon iconPreview" }, { "cssClasses": "input-group-addon iconPreview" },
{ "getStringKey": "Gen_SelectToPreview" }, { "getStringKey": "Gen_SelectToPreview" },
{ "customId": "NEWDEV_dev_Icon_preview" } { "customId": "NEWDEV_devIcon_preview" }
], ],
"transformers": [] "transformers": []
}, },
@@ -548,7 +548,7 @@ The UI component is defined as a JSON object containing a list of `elements`. Ea
{ {
"onChange": "updateIconPreview(this)" "onChange": "updateIconPreview(this)"
}, },
{ "customParams": "NEWDEV_dev_Icon,NEWDEV_dev_Icon_preview" } { "customParams": "NEWDEV_devIcon,NEWDEV_devIcon_preview" }
], ],
"transformers": [] "transformers": []
} }
@@ -649,7 +649,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
| See below for information on `threshold`, `replace`. | | | See below for information on `threshold`, `replace`. | |
| | | | | |
| `options` Property | Used in conjunction with types like `threshold`, `replace`, `regex`. | | `options` Property | Used in conjunction with types like `threshold`, `replace`, `regex`. |
| `options_params` Property | Used in conjunction with a `"options": "[{value}]"` template and `text.select`/`list.select`. Can specify SQL query (needs to return 2 columns `SELECT dev_Name as name, dev_Mac as id`) or Setting (not tested) to populate the dropdown. Check example below or have a look at the `NEWDEV` plugin `config.json` file. | | `options_params` Property | Used in conjunction with a `"options": "[{value}]"` template and `text.select`/`list.select`. Can specify SQL query (needs to return 2 columns `SELECT devName as name, devMac as id`) or Setting (not tested) to populate the dropdown. Check example below or have a look at the `NEWDEV` plugin `config.json` file. |
| `threshold` | The `options` array contains objects ordered from the lowest `maximum` to the highest. The corresponding `hexColor` is used for the value background color if it's less than the specified `maximum` but more than the previous one in the `options` array. | | `threshold` | The `options` array contains objects ordered from the lowest `maximum` to the highest. The corresponding `hexColor` is used for the value background color if it's less than the specified `maximum` but more than the previous one in the `options` array. |
| `replace` | The `options` array contains objects with an `equals` property, which is compared to the "value." If the values are the same, the string in `replacement` is displayed in the UI instead of the actual "value". | | `replace` | The `options` array contains objects with an `equals` property, which is compared to the "value." If the values are the same, the string in `replacement` is displayed in the UI instead of the actual "value". |
| `regex` | Applies a regex to the value. The `options` array contains objects with an `type` (must be set to `regex`) and `param` (must contain the regex itself) property. | | `regex` | Applies a regex to the value. The `options` array contains objects with an `type` (must be set to `regex`) and `param` (must contain the regex itself) property. |
@@ -669,7 +669,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
```json ```json
"function": "dev_DeviceType", "function": "devType",
"type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]},
"maxLength": 30, "maxLength": 30,
"default_value": "", "default_value": "",
@@ -678,7 +678,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
{ {
"name" : "value", "name" : "value",
"type" : "sql", "type" : "sql",
"value" : "SELECT '' as id, '' as name UNION SELECT dev_DeviceType as id, dev_DeviceType as name FROM (SELECT dev_DeviceType FROM Devices UNION SELECT 'Smartphone' UNION SELECT 'Tablet' UNION SELECT 'Laptop' UNION SELECT 'PC' UNION SELECT 'Printer' UNION SELECT 'Server' UNION SELECT 'NAS' UNION SELECT 'Domotic' UNION SELECT 'Game Console' UNION SELECT 'SmartTV' UNION SELECT 'Clock' UNION SELECT 'House Appliance' UNION SELECT 'Phone' UNION SELECT 'AP' UNION SELECT 'Gateway' UNION SELECT 'Firewall' UNION SELECT 'Switch' UNION SELECT 'WLAN' UNION SELECT 'Router' UNION SELECT 'Other') AS all_devices ORDER BY id;" "value" : "SELECT '' as id, '' as name UNION SELECT devType as id, devType as name FROM (SELECT devType FROM Devices UNION SELECT 'Smartphone' UNION SELECT 'Tablet' UNION SELECT 'Laptop' UNION SELECT 'PC' UNION SELECT 'Printer' UNION SELECT 'Server' UNION SELECT 'NAS' UNION SELECT 'Domotic' UNION SELECT 'Game Console' UNION SELECT 'SmartTV' UNION SELECT 'Clock' UNION SELECT 'House Appliance' UNION SELECT 'Phone' UNION SELECT 'AP' UNION SELECT 'Gateway' UNION SELECT 'Firewall' UNION SELECT 'Switch' UNION SELECT 'WLAN' UNION SELECT 'Router' UNION SELECT 'Other') AS all_devices ORDER BY id;"
}, },
{ {
"name" : "uilang", "name" : "uilang",

110
docs/UPDATES.md Executable file
View File

@@ -0,0 +1,110 @@
# Docker Update Strategies for NetAlertX
This guide outlines several approaches for updating Docker containers, specifically using NetAlertX. Each method offers different benefits depending on the situation. Here are the methods:
- Manual: Direct commands to stop, remove, and rebuild containers.
- Dockcheck: Semi-automated with more control, suited for bulk updates.
- Watchtower: Fully automated, runs continuously to check and update containers.
You can choose any approach that fits your workflow.
> In the examples I assume that the container name is `netalertx` and the image name is `netalertx` as well.
## 1. Manual Updates
Use this method when you need precise control over a single container or when dealing with a broken container that needs immediate attention.
Example Commands
To manually update the `netalertx` container, stop it, delete it, remove the old image, and start a fresh one with `docker-compose`.
```bash
# Stop the container
sudo docker container stop netalertx
# Remove the container
sudo docker container rm netalertx
# Remove the old image
sudo docker image rm netalertx
# Pull and start a new container
sudo docker-compose up -d
```
### Alternative: Force Pull with Docker Compose
You can also use `--pull always` to ensure Docker pulls the latest image before starting the container:
```bash
sudo docker-compose up --pull always -d
```
## 2. Dockcheck for Bulk Container Updates
Always check the [Dockcheck](https://github.com/mag37/dockcheck) docs if encountering issues with the guide below.
Dockcheck is a useful tool if you have multiple containers to update and some flexibility for handling potential issues that might arise during mass updates. Dockcheck allows you to inspect each container and decide when to update.
### Example Workflow with Dockcheck
You might use Dockcheck to:
- Inspect container versions.
- Pull the latest images in bulk.
- Apply updates selectively.
Dockcheck can help streamline bulk updates, especially if youre managing multiple containers.
Below is a script I use to run an update of the Dockcheck script and start a check for new containers:
```bash
cd /path/to/Docker &&
rm dockcheck.sh &&
wget https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh &&
sudo chmod +x dockcheck.sh &&
sudo ./dockcheck.sh
```
## 3. Automated Updates with Watchtower
Always check the [watchtower](https://github.com/containrrr/watchtower) docs if encountering issues with the guide below.
Watchtower monitors your Docker containers and automatically updates them when new images are available. This is ideal for ongoing updates without manual intervention.
### Setting Up Watchtower
#### 1. Pull the Watchtower Image:
```bash
docker pull containrrr/watchtower
```
#### 2. Run Watchtower to update all images:
```bash
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
--interval 300 # Check for updates every 5 minutes
```
#### 3. Run Watchtower to update only NetAlertX:
You can specify which containers to monitor by listing them. For example, to monitor netalertx only:
```bash
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower netalertx
```
## Summary
- Manual: Ideal for individual or critical updates.
- Dockcheck: Suitable for controlled, mass updates.
- Watchtower: Fully automated, best for continuous deployment setups.
These approaches allow you to maintain flexibility in how you update Docker containers, depending on the urgency and scale of the update.

View File

@@ -681,7 +681,7 @@ switch ($UI_THEME) {
// Iterate through the data and filter only visible devices // Iterate through the data and filter only visible devices
$.each(devicesList, function(index, item) { $.each(devicesList, function(index, item) {
// Check if the current item's MAC exists in visibleDevicesMACs // Check if the current item's MAC exists in visibleDevicesMACs
if (visibleDevicesMACs.includes(item.dev_MAC)) { if (visibleDevicesMACs.includes(item.devMac)) {
devicesList_tmp.push(item); devicesList_tmp.push(item);
} }
}); });
@@ -827,12 +827,12 @@ function initializeCombos () {
// nameTransformer) // callback to transform name // nameTransformer) // callback to transform name
generateOptionsOrSetOptions("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"]) generateOptionsOrSetOptions("NEWDEV_devIcon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"])
generateOptionsOrSetOptions("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' ) generateOptionsOrSetOptions("NEWDEV_devType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
generateOptionsOrSetOptions("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' ) generateOptionsOrSetOptions("NEWDEV_devOwner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
generateOptionsOrSetOptions("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' ) generateOptionsOrSetOptions("NEWDEV_devGroup", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
generateOptionsOrSetOptions("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' ) generateOptionsOrSetOptions("NEWDEV_devLocation", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
generateOptionsOrSetOptions("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' ) generateOptionsOrSetOptions("NEWDEV_devParentMAC", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
// Initialize static combos // Initialize static combos
initializeComboSkipRepeated (); initializeComboSkipRepeated ();
@@ -1171,7 +1171,7 @@ function getDeviceData (readAllData=false) {
var deviceData = JSON.parse(data); var deviceData = JSON.parse(data);
// check device exists // check device exists
if (deviceData['dev_MAC'] == null) { if (deviceData['devMac'] == null) {
// Status // Status
$('#deviceStatus').html ('--'); $('#deviceStatus').html ('--');
$('#deviceStatus')[0].className = 'text-gray'; $('#deviceStatus')[0].className = 'text-gray';
@@ -1227,16 +1227,16 @@ function getDeviceData (readAllData=false) {
} else { } else {
// Name // Name
if (deviceData['dev_Owner'] == null || deviceData['dev_Owner'] == '' || if (deviceData['devOwner'] == null || deviceData['devOwner'] == '' ||
(deviceData['dev_Name'].toString()).indexOf (deviceData['dev_Owner']) != -1 ) { (deviceData['devName'].toString()).indexOf (deviceData['devOwner']) != -1 ) {
$('#pageTitle').html (deviceData['dev_Name']); $('#pageTitle').html (deviceData['devName']);
} else { } else {
$('#pageTitle').html (deviceData['dev_Name'] + ' ('+ deviceData['dev_Owner'] +')'); $('#pageTitle').html (deviceData['devName'] + ' ('+ deviceData['devOwner'] +')');
} }
// Status // Status
$('#deviceStatus').html (deviceData['dev_Status'].replace('-', '')); $('#deviceStatus').html (deviceData['devStatus'].replace('-', ''));
switch (deviceData['dev_Status']) { switch (deviceData['devStatus']) {
case 'On-line': icon='fa fa-check'; color='text-green'; break; case 'On-line': icon='fa fa-check'; color='text-green'; break;
case 'Off-line': icon='fa fa-close'; color='text-gray'; break; case 'Off-line': icon='fa fa-close'; color='text-gray'; break;
case 'Down': icon='fa fa-warning'; color='text-red'; break; case 'Down': icon='fa fa-warning'; color='text-red'; break;
@@ -1247,16 +1247,16 @@ function getDeviceData (readAllData=false) {
$('#deviceStatusIcon')[0].className = icon +' '+ color; $('#deviceStatusIcon')[0].className = icon +' '+ color;
// Totals // Totals
$('#deviceSessions').html (deviceData['dev_Sessions'].toLocaleString()); $('#deviceSessions').html (deviceData['devSessions'].toLocaleString());
$('#deviceDownAlerts').html (deviceData['dev_DownAlerts'].toLocaleString()); $('#deviceDownAlerts').html (deviceData['devDownAlerts'].toLocaleString());
// Presence // Presence
$('#deviceEventsTitle').html ('Presence'); $('#deviceEventsTitle').html ('Presence');
$('#deviceEventsIcon').html ('<i class="fa fa-calendar">'); $('#deviceEventsIcon').html ('<i class="fa fa-calendar">');
if (deviceData['dev_PresenceHours'] == null || deviceData['dev_PresenceHours'] < 0) { if (deviceData['devPresenceHours'] == null || deviceData['devPresenceHours'] < 0) {
$('#deviceEvents').html ('0 h.'); $('#deviceEvents').html ('0 h.');
} else { } else {
$('#deviceEvents').html (deviceData['dev_PresenceHours'].toLocaleString() +' h.'); $('#deviceEvents').html (deviceData['devPresenceHours'].toLocaleString() +' h.');
} }
// Device info // Device info
@@ -1264,7 +1264,7 @@ function getDeviceData (readAllData=false) {
// Activate controls // Activate controls
$('#panDetails :input').attr('disabled', false); $('#panDetails :input').attr('disabled', false);
mac = deviceData['dev_MAC']; mac = deviceData['devMac'];
// update the mac parameter in the URL, this makes the selected device persistent when the page is reloaded // update the mac parameter in the URL, this makes the selected device persistent when the page is reloaded
var searchParams = new URLSearchParams(window.location.search); var searchParams = new URLSearchParams(window.location.search);
@@ -1275,51 +1275,51 @@ function getDeviceData (readAllData=false) {
devicesList = getDevicesList(); devicesList = getDevicesList();
// handle empty dev_Network_Node_MAC_ADDR // handle empty devParentMAC
networkParentMac = deviceData['dev_Network_Node_MAC_ADDR'] networkParentMac = deviceData['devParentMAC']
if(networkParentMac) if(networkParentMac)
{ {
networkParentMacName = getDeviceDataByMac(deviceData['dev_Network_Node_MAC_ADDR'], "dev_Name") networkParentMacName = getDeviceDataByMac(deviceData['devParentMAC'], "devName")
} else } else
{ {
networkParentMacName = '--' networkParentMacName = '--'
} }
$('#txtMAC').val (deviceData['dev_MAC']); $('#txtMAC').val (deviceData['devMac']);
$('#txtName').val (deviceData['dev_Name']); $('#txtName').val (deviceData['devName']);
$('#txtOwner').val (deviceData['dev_Owner']); $('#txtOwner').val (deviceData['devOwner']);
$('#txtDeviceType').val (deviceData['dev_DeviceType']); $('#txtDeviceType').val (deviceData['devType']);
$('#txtVendor').val (deviceData['dev_Vendor']); $('#txtVendor').val (deviceData['devVendor']);
$('#txtIcon').val (initDefault(deviceData['dev_Icon'], 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==')); // base64 laptop icon $('#txtIcon').val (initDefault(deviceData['devIcon'], 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==')); // base64 laptop icon
$('#txtIcon').trigger('change') $('#txtIcon').trigger('change')
if (deviceData['dev_Favorite'] == 1) {$('#chkFavorite').iCheck('check');} else {$('#chkFavorite').iCheck('uncheck');} if (deviceData['devFavorite'] == 1) {$('#chkFavorite').iCheck('check');} else {$('#chkFavorite').iCheck('uncheck');}
$('#txtGroup').val (deviceData['dev_Group']); $('#txtGroup').val (deviceData['devGroup']);
$('#txtLocation').val (deviceData['dev_Location']); $('#txtLocation').val (deviceData['devLocation']);
$('#txtComments').val (decodeSpecialChars(deviceData['dev_Comments'])); $('#txtComments').val (decodeSpecialChars(deviceData['devComments']));
$('#txtNetworkNodeMac').val ( networkParentMacName) ; $('#txtNetworkNodeMac').val ( networkParentMacName) ;
$('#txtNetworkNodeMac').attr ('data-mynodemac', deviceData['dev_Network_Node_MAC_ADDR']); $('#txtNetworkNodeMac').attr ('data-mynodemac', deviceData['devParentMAC']);
$('#txtNetworkPort').val (deviceData['dev_Network_Node_port']); $('#txtNetworkPort').val (deviceData['devParentPort']);
$('#txtNetworkSite').val (deviceData['dev_NetworkSite']); $('#txtNetworkSite').val (deviceData['devSite']);
$('#txtSSID').val (deviceData['dev_SSID']); $('#txtSSID').val (deviceData['devSSID']);
// disabling network node configuration if root Internet node // disabling network node configuration if root Internet node
toggleNetworkConfiguration(mac == 'Internet') toggleNetworkConfiguration(mac == 'Internet')
$('#txtFirstConnection').val (deviceData['dev_FirstConnection']); $('#txtFirstConnection').val (deviceData['devFirstConnection']);
$('#txtLastConnection').val (deviceData['dev_LastConnection']); $('#txtLastConnection').val (deviceData['devLastConnection']);
$('#txtLastIP').val (deviceData['dev_LastIP']); $('#txtLastIP').val (deviceData['devLastIP']);
$('#txtStatus').val (deviceData['dev_Status'].replace('-', '')); $('#txtStatus').val (deviceData['devStatus'].replace('-', ''));
if (deviceData['dev_StaticIP'] == 1) {$('#chkStaticIP').iCheck('check');} else {$('#chkStaticIP').iCheck('uncheck');} if (deviceData['devStaticIP'] == 1) {$('#chkStaticIP').iCheck('check');} else {$('#chkStaticIP').iCheck('uncheck');}
$('#txtScanCycle').val (deviceData['dev_ScanCycle'] == "1" ? "yes" : "no"); $('#txtScanCycle').val (deviceData['devScan'] == "1" ? "yes" : "no");
if (deviceData['dev_AlertEvents'] == 1) {$('#chkAlertEvents').iCheck('check');} else {$('#chkAlertEvents').iCheck('uncheck');} if (deviceData['devAlertEvents'] == 1) {$('#chkAlertEvents').iCheck('check');} else {$('#chkAlertEvents').iCheck('uncheck');}
if (deviceData['dev_AlertDeviceDown'] == 1) {$('#chkAlertDown').iCheck('check');} else {$('#chkAlertDown').iCheck('uncheck');} if (deviceData['devAlertDown'] == 1) {$('#chkAlertDown').iCheck('check');} else {$('#chkAlertDown').iCheck('uncheck');}
$('#txtSkipRepeated').val (findSkipRepeated (deviceData['dev_SkipRepeated'])); $('#txtSkipRepeated').val (findSkipRepeated (deviceData['devSkipRepeated']));
if (deviceData['dev_NewDevice'] == 1) {$('#chkNewDevice').iCheck('check');} else {$('#chkNewDevice').iCheck('uncheck');} if (deviceData['devIsNew'] == 1) {$('#chkNewDevice').iCheck('check');} else {$('#chkNewDevice').iCheck('uncheck');}
if (deviceData['dev_Archived'] == 1) {$('#chkArchived').iCheck('check');} else {$('#chkArchived').iCheck('uncheck');} if (deviceData['devIsArchived'] == 1) {$('#chkArchived').iCheck('check');} else {$('#chkArchived').iCheck('uncheck');}
if (deviceData['dev_RandomMAC'] == 1) {$('#iconRandomMACactive').removeClass ('hidden'); if (deviceData['devRandomMAC'] == 1) {$('#iconRandomMACactive').removeClass ('hidden');
$('#iconRandomMACinactive').addClass ('hidden'); } $('#iconRandomMACinactive').addClass ('hidden'); }
else {$('#iconRandomMACactive').addClass ('hidden'); else {$('#iconRandomMACactive').addClass ('hidden');
$('#iconRandomMACinactive').removeClass ('hidden'); }; $('#iconRandomMACinactive').removeClass ('hidden'); };
@@ -1329,7 +1329,7 @@ function getDeviceData (readAllData=false) {
pos = devicesList.findIndex(item => item.rowid == deviceData['rowid']); pos = devicesList.findIndex(item => item.rowid == deviceData['rowid']);
if (pos == -1) { if (pos == -1) {
devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['dev_MAC'], "name": deviceData['dev_Name'], "type": deviceData['dev_DeviceType']}); devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['devMac'], "name": deviceData['devName'], "type": deviceData['devType']});
pos=0; pos=0;
} }
} }
@@ -1401,7 +1401,7 @@ function performSwitch(direction)
// get new mac from the devicesList. Don't change to the commented out line below, the mac query string in the URL isn't updated yet! // get new mac from the devicesList. Don't change to the commented out line below, the mac query string in the URL isn't updated yet!
// mac = params.mac; // mac = params.mac;
mac = devicesList[pos].dev_MAC.toString(); mac = devicesList[pos].devMac.toString();
setCache("piaDeviceDetailsMac", mac); setCache("piaDeviceDetailsMac", mac);
@@ -1728,7 +1728,7 @@ function setTextValue (textElement, textValue) {
if(textElement == "txtNetworkNodeMac") if(textElement == "txtNetworkNodeMac")
{ {
$('#'+textElement).attr ('data-mynodemac', textValue); $('#'+textElement).attr ('data-mynodemac', textValue);
$('#'+textElement).val (getDeviceDataByMac(textValue, "dev_Name")); $('#'+textElement).val (getDeviceDataByMac(textValue, "devName"));
} else } else
{ {
$('#'+textElement).attr ('data-myvalue', textValue); $('#'+textElement).attr ('data-myvalue', textValue);

View File

@@ -77,16 +77,16 @@
<?= lang("DevDetail_Nmap_Scans_desc") ?> <?= lang("DevDetail_Nmap_Scans_desc") ?>
</div> </div>
<button type="button" id="piamanualnmap_fast" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'fast')"> <button type="button" id="piamanualnmap_fast" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'fast')">
<?= lang("DevDetail_Loading") ?> <?= lang("DevDetail_Loading") ?>
</button> </button>
<button type="button" id="piamanualnmap_normal" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'normal')"> <button type="button" id="piamanualnmap_normal" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'normal')">
<?= lang("DevDetail_Loading") ?> <?= lang("DevDetail_Loading") ?>
</button> </button>
<button type="button" id="piamanualnmap_detail" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'detail')"> <button type="button" id="piamanualnmap_detail" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'detail')">
<?= lang("DevDetail_Loading") ?> <?= lang("DevDetail_Loading") ?>
</button> </button>
<button type="button" id="piamanualnmap_skipdiscovery" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'skipdiscovery')"> <button type="button" id="piamanualnmap_skipdiscovery" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'skipdiscovery')">
<?= lang("DevDetail_Loading") ?> <?= lang("DevDetail_Loading") ?>
</button> </button>
@@ -155,7 +155,7 @@
$( "#tracerouteoutput" ).empty(); $( "#tracerouteoutput" ).empty();
$.ajax({ $.ajax({
method: "GET", method: "GET",
url: "./php/server/traceroute.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'dev_LastIP') + "", url: "./php/server/traceroute.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'devLastIP') + "",
beforeSend: function() { $('#tracerouteoutput').addClass("ajax_scripts_loading"); }, beforeSend: function() { $('#tracerouteoutput').addClass("ajax_scripts_loading"); },
complete: function() { $('#tracerouteoutput').removeClass("ajax_scripts_loading"); }, complete: function() { $('#tracerouteoutput').removeClass("ajax_scripts_loading"); },
success: function(data, textStatus) { success: function(data, textStatus) {
@@ -170,7 +170,7 @@
$( "#nslookupoutput" ).empty(); $( "#nslookupoutput" ).empty();
$.ajax({ $.ajax({
method: "GET", method: "GET",
url: "./php/server/nslookup.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'dev_LastIP') + "", url: "./php/server/nslookup.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'devLastIP') + "",
beforeSend: function() { $('#nslookupoutput').addClass("ajax_scripts_loading"); }, beforeSend: function() { $('#nslookupoutput').addClass("ajax_scripts_loading"); },
complete: function() { $('#nslookupoutput').removeClass("ajax_scripts_loading"); }, complete: function() { $('#nslookupoutput').removeClass("ajax_scripts_loading"); },
success: function(data, textStatus) { success: function(data, textStatus) {

View File

@@ -207,11 +207,7 @@ function main () {
$('#tableDevices tr').html(html); $('#tableDevices tr').html(html);
// Hide UI elements as per settings hideUIelements("UI_DEV_SECTIONS")
// setTimeout(() => {
hideUIelements("UI_DEV_SECTIONS")
// }, 10);
// Initialize components with parameters // Initialize components with parameters
initializeDatatable(getUrlAnchor('my_devices')); initializeDatatable(getUrlAnchor('my_devices'));
@@ -320,31 +316,31 @@ function filterDataByStatus(data, status) {
let result = true; let result = true;
if (!to_display.includes('down') && item.dev_PresentLastScan === 0 && item.dev_AlertDeviceDown !== 0) { if (!to_display.includes('down') && item.devPresentLastScan === 0 && item.devAlertDown !== 0) {
result = false; result = false;
} else if (!to_display.includes('new') && item.dev_NewDevice === 1) { } else if (!to_display.includes('new') && item.devIsNew === 1) {
result = false; result = false;
} else if (!to_display.includes('archived') && item.dev_Archived === 1) { } else if (!to_display.includes('archived') && item.devIsArchived === 1) {
result = false; result = false;
} else if (!to_display.includes('offline') && item.dev_PresentLastScan === 0) { } else if (!to_display.includes('offline') && item.devPresentLastScan === 0) {
result = false; result = false;
} else if (!to_display.includes('online') && item.dev_PresentLastScan === 1) { } else if (!to_display.includes('online') && item.devPresentLastScan === 1) {
result = false; result = false;
} }
return result; // Include all items for 'my_devices' status return result; // Include all items for 'my_devices' status
case 'connected': case 'connected':
return item.dev_PresentLastScan === 1; return item.devPresentLastScan === 1;
case 'favorites': case 'favorites':
return item.dev_Favorite === 1; return item.devFavorite === 1;
case 'new': case 'new':
return item.dev_NewDevice === 1; return item.devIsNew === 1;
case 'offline': case 'offline':
return item.dev_PresentLastScan === 0; return item.devPresentLastScan === 0;
case 'down': case 'down':
return (item.dev_PresentLastScan === 0 && item.dev_AlertDeviceDown !== 0); return (item.devPresentLastScan === 0 && item.devAlertDown !== 0);
case 'archived': case 'archived':
return item.dev_Archived === 1; return item.devIsArchived === 1;
default: default:
return true; // Include all items for unknown statuses return true; // Include all items for unknown statuses
} }
@@ -355,23 +351,23 @@ function filterDataByStatus(data, status) {
function getDeviceStatus(item) function getDeviceStatus(item)
{ {
if(item.dev_NewDevice === 1) if(item.devIsNew === 1)
{ {
return 'New'; return 'New';
} }
else if(item.dev_PresentLastScan === 1) else if(item.devPresentLastScan === 1)
{ {
return 'On-line'; return 'On-line';
} }
else if(item.dev_PresentLastScan === 0 && item.dev_AlertDeviceDown !== 0) else if(item.devPresentLastScan === 0 && item.devAlertDown !== 0)
{ {
return 'Down'; return 'Down';
} }
else if(item.dev_Archived === 1) else if(item.devIsArchived === 1)
{ {
return 'Archived'; return 'Archived';
} }
else if(item.dev_PresentLastScan === 0) else if(item.devPresentLastScan === 0)
{ {
return 'Off-line'; return 'Off-line';
} }
@@ -380,6 +376,164 @@ function getDeviceStatus(item)
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeDatatable_new (status) {
// Build GraphQL query dynamically based on tableColumnVisible
let columnsToFetch = [
'devMac', 'devName', 'devLastConnection', 'devIsArchived', 'devOwner', 'devType',
'devIcon', 'devFavorite', 'devGroup', 'devFirstConnection', 'devLastIP', 'devNetworkNodeMAC',
'devLocation', 'devVendor', 'devNetworkNodePort', 'devGUID', 'devSyncHubNodeName',
'devNetworkSite', 'devSSID', 'devSourcePlugin'
];
let selectedColumns = columnsToFetch.filter(col => tableColumnVisible.includes(col));
// Construct the GraphQL query
let graphqlQuery = `
query {
devices {
${selectedColumns.join('\n')}
}
}
`;
console.log(graphqlQuery);
$.ajax({
url: 'php/server/query_graphql.php', // PHP endpoint that proxies to the GraphQL server
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
query: graphqlQuery,
variables: {} // Optional: pass variables if needed
}),
success: function(response) {
console.log('GraphQL Response:', response);
// Handle the GraphQL response
let devicesListAll_JSON = response.data.devices;
let devicesListAll_JSON_str = JSON.stringify(devicesListAll_JSON);
setCache('devicesListAll_JSON', devicesListAll_JSON_str);
// Query data
getDevicesTotals(devicesListAll_JSON);
// Filter the data based on deviceStatus
var filteredData = filterDataByStatus(devicesListAll_JSON, deviceStatus);
// Convert JSON data into the desired format
var dataArray = {
data: filteredData.map(function(item) {
var originalRow = selectedColumns.map(function(column) {
return item[column] || "";
});
var newRow = [];
// Reorder data based on user-defined columns order
for (index = 0; index < tableColumnOrder.length; index++) {
newRow.push(originalRow[tableColumnOrder[index]]);
}
return newRow;
})
};
// Initialize DataTable
if ($.fn.dataTable.isDataTable('#tableDevices')) {
var table = $('#tableDevices').DataTable();
table.clear().destroy();
}
var table = $('#tableDevices').DataTable({
'data': dataArray["data"],
'paging': true,
'lengthChange': true,
'lengthMenu': [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
'searching': true,
'ordering': true,
'info': true,
'autoWidth': false,
'pageLength': tableRows,
'order': tableOrder,
'select': true,
'columnDefs': [
{ visible: false, targets: tableColumnHide },
{ className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] },
{ width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15)] },
{ width: '30px', targets: [mapIndx(10), mapIndx(13), mapIndx(18)] },
{ orderData: [mapIndx(12)], targets: mapIndx(8) },
// Device Name
{ targets: [mapIndx(0)], 'createdCell': function (td, cellData, rowData) {
$(td).html ('<b class="anonymizeDev"><a href="deviceDetails.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
}},
// Handle other column customizations (similar to the original code)
// Example for IP address formatting:
{ targets: [mapIndx(8)], 'createdCell': function (td, cellData) {
if (!emptyArr.includes(cellData)) {
$(td).html (`<span class="anonymizeIp">
<a href="http://${cellData}" class="pointer" target="_blank">${cellData}</a>
<a href="https://${cellData}" class="pointer" target="_blank"><i class="fa fa-lock "></i></a>
</span>`);
} else {
$(td).html('');
}
}},
// Other columns (Status, MAC, Date, etc.) can be similarly customized.
],
'processing': true,
'language': {
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
emptyTable: 'No data',
"lengthMenu": "<?= lang('Device_Tablelenght');?>",
"search": "<?= lang('Device_Searchbox');?>: ",
"paginate": {
"next": "<?= lang('Device_Table_nav_next');?>",
"previous": "<?= lang('Device_Table_nav_prev');?>"
},
"info": "<?= lang('Device_Table_info');?>",
}
});
// Event listeners for row selection and saving parameters (same as the original code)
$('#tableDevices').on('length.dt', function (e, settings, len) {
setCookie ("nax_parTableRows", len, 129600); // save for 90 days
});
$('#tableDevices').on('order.dt', function () {
setCookie ("nax_parTableOrder", JSON.stringify(table.order()), 129600); // save for 90 days
});
// Add multi-edit button and row selection functionality
$('#multiEditPlc').append(
`<button type="submit" id="multiEdit" class="btn btn-primary" style="display:none" onclick="multiEditDevices();">
<i class="fa fa-pencil pointer"></i> ${getString("Device_MultiEdit")}
</button>`
);
$('#tableDevices').on('click', 'tr', function () {
setTimeout(function(){
var anyRowSelected = $('#tableDevices tr.selected').length > 0;
$('#multiEdit').toggle(anyRowSelected);
}, 200);
});
hideSpinner(); // Hide the loading spinner
},
error: function(xhr, status, error) {
console.error('AJAX Error:', error);
}
});
}
function initializeDatatable (status) { function initializeDatatable (status) {
if(!status) if(!status)
@@ -435,31 +589,31 @@ function initializeDatatable (status) {
var dataArray = { var dataArray = {
data: filteredData.map(function(item) { data: filteredData.map(function(item) {
var originalRow = [ var originalRow = [
item.dev_Name || "", item.devName || "",
item.dev_Owner || "", item.devOwner || "",
item.dev_DeviceType || "", item.devType || "",
item.dev_Icon || "", item.devIcon || "",
item.dev_Favorite || "", item.devFavorite || "",
item.dev_Group || "", item.devGroup || "",
// --- // ---
item.dev_FirstConnection || "", item.devFirstConnection || "",
item.dev_LastConnection || "", item.devLastConnection || "",
item.dev_LastIP || "", item.devLastIP || "",
(isRandomMAC(item.dev_MAC)) || "", // Check if randomized MAC (isRandomMAC(item.devMac)) || "", // Check if randomized MAC
getDeviceStatus(item) || "", getDeviceStatus(item) || "",
item.dev_MAC || "", // hidden item.devMac || "", // hidden
formatIPlong(item.dev_LastIP) || "", // IP orderable formatIPlong(item.devLastIP) || "", // IP orderable
item.rowid || "", item.rowid || "",
item.dev_Network_Node_MAC_ADDR || "", item.devParentMAC || "",
getNumberOfChildren(item.dev_MAC, result.data) || 0, getNumberOfChildren(item.devMac, result.data) || 0,
item.dev_Location || "", item.devLocation || "",
item.dev_Vendor || "", item.devVendor || "",
item.dev_Network_Node_port || 0, item.devParentPort || 0,
item.dev_GUID || "", item.devGUID || "",
item.dev_SyncHubNodeName || "", item.devSyncHubNode || "",
item.dev_NetworkSite || "", item.devSite || "",
item.dev_SSID || "", item.devSSID || "",
item.dev_SourcePlugin || "" item.devSourcePlugin || ""
]; ];
var newRow = []; var newRow = [];
@@ -612,15 +766,15 @@ function initializeDatatable (status) {
devData = getDeviceDataByMac(rowData[mapIndx(11)]) devData = getDeviceDataByMac(rowData[mapIndx(11)])
if (devData.dev_PresentLastScan == 1) if (devData.devPresentLastScan == 1)
{ {
css = "green text-white statusOnline" css = "green text-white statusOnline"
icon = '<i class="fa-solid fa-plug"></i>' icon = '<i class="fa-solid fa-plug"></i>'
} else if (devData.dev_PresentLastScan != 1 && devData.dev_AlertDeviceDown == 1) } else if (devData.devPresentLastScan != 1 && devData.devAlertDown == 1)
{ {
css = "red text-white statusDown" css = "red text-white statusDown"
icon = '<i class="fa-solid fa-triangle-exclamation"></i>' icon = '<i class="fa-solid fa-triangle-exclamation"></i>'
} else if(devData.dev_PresentLastScan != 1) } else if(devData.devPresentLastScan != 1)
{ {
css = "gray text-white statusOffline" css = "gray text-white statusOffline"
icon = '<i class="fa-solid fa-xmark"></i>' icon = '<i class="fa-solid fa-xmark"></i>'
@@ -656,11 +810,6 @@ function initializeDatatable (status) {
$('#tableDevices').on( 'order.dt', function () { $('#tableDevices').on( 'order.dt', function () {
setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
setCache ('devicesList', getDevicesFromTable(table) );
} );
$('#tableDevices').on( 'search.dt', function () {
setCache ('devicesList', getDevicesFromTable(table) );
} ); } );
// add multi-edit button // add multi-edit button
@@ -679,7 +828,6 @@ function initializeDatatable (status) {
$('#multiEdit').toggle(anyRowSelected); $('#multiEdit').toggle(anyRowSelected);
}, 200); }, 200);
}); });
@@ -689,35 +837,6 @@ function initializeDatatable (status) {
}; };
// -----------------------------------------------------------------------------
// Gets a JSON list of rowID and mac from the displayed table in the UI
function getDevicesFromTable(table)
{
rowIDs = table.column(mapIndx(13), { 'search': 'applied' }).data().toArray() //
rowMACs = table.column(mapIndx(11), { 'search': 'applied' }).data().toArray() //
rowNames = table.column(mapIndx(0), { 'search': 'applied' }).data().toArray() //
rowTypes = table.column(mapIndx(2), { 'search': 'applied' }).data().toArray() //
rowIcons = table.column(mapIndx(3), { 'search': 'applied' }).data().toArray() //
rowParentMAC = table.column(mapIndx(14), { 'search': 'applied' }).data().toArray() //
rowStatus = table.column(mapIndx(10), { 'search': 'applied' }).data().toArray() //
result = []
rowIDs.map(function(rowID, index){
result.push({
"rowid": rowID,
"mac" : rowMACs[index],
"name" : rowNames[index],
"type" : rowTypes[index],
"icon" : rowIcons[index],
"parentMac" : rowParentMAC[index],
"status" : rowStatus[index] })
})
return JSON.stringify (result)
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function getNumberOfChildren(mac, devices) function getNumberOfChildren(mac, devices)
{ {
@@ -725,7 +844,7 @@ function getNumberOfChildren(mac, devices)
$.each(devices, function(index, dev) { $.each(devices, function(index, dev) {
if(dev.dev_Network_Node_MAC_ADDR != null && dev.dev_Network_Node_MAC_ADDR.trim() == mac.trim()) if(dev.devParentMAC != null && dev.devParentMAC.trim() == mac.trim())
{ {
childrenCount++; childrenCount++;
} }

View File

@@ -701,9 +701,9 @@ function navigateToDeviceWithIp (ip) {
$.each(devices, function(index, obj) { $.each(devices, function(index, obj) {
if(obj.dev_LastIP.trim() == ip.trim()) if(obj.devLastIP.trim() == ip.trim())
{ {
mac = obj.dev_MAC; mac = obj.devMac;
window.open(window.location.origin +'/deviceDetails.php?mac=' + mac , "_blank"); window.open(window.location.origin +'/deviceDetails.php?mac=' + mac , "_blank");
} }
@@ -714,7 +714,7 @@ function navigateToDeviceWithIp (ip) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function getNameByMacAddress(macAddress) { function getNameByMacAddress(macAddress) {
return getDeviceDataByMac(macAddress, "dev_Name") return getDeviceDataByMac(macAddress, "devName")
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -880,7 +880,7 @@ function getDeviceDataByMac(macAddress, dbColumn) {
const devices = JSON.parse(devicesCache); const devices = JSON.parse(devicesCache);
for (const device of devices) { for (const device of devices) {
if (device["dev_MAC"].toLowerCase() === macAddress.toLowerCase()) { if (device["devMac"].toLowerCase() === macAddress.toLowerCase()) {
if(dbColumn) if(dbColumn)
{ {

View File

@@ -23,7 +23,7 @@ function initDeviceSelectors(devicesListAll_JSON) {
// Loop through the devices list // Loop through the devices list
devicesList.forEach(function(device) { devicesList.forEach(function(device) {
selectorFieldsHTML += `<option value="${device.dev_MAC}">${device.dev_Name}</option>`; selectorFieldsHTML += `<option value="${device.devMac}">${device.devName}</option>`;
}); });
selector = `<div class="db_info_table_row col-sm-12" > selector = `<div class="db_info_table_row col-sm-12" >

View File

@@ -77,11 +77,11 @@
settingsData = res["data"]; settingsData = res["data"];
excludedColumns = ["NEWDEV_dev_MAC", "NEWDEV_dev_FirstConnection", "NEWDEV_dev_LastConnection", "NEWDEV_dev_LastNotification", "NEWDEV_dev_LastIP", "NEWDEV_dev_StaticIP", "NEWDEV_dev_ScanCycle", "NEWDEV_dev_PresentLastScan" ] excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
const relevantColumns = settingsData.filter(set => const relevantColumns = settingsData.filter(set =>
set.Group === "NEWDEV" && set.Group === "NEWDEV" &&
set.Code_Name.includes("_dev_") && set.Code_Name.includes("_dev") &&
!excludedColumns.includes(set.Code_Name) && !excludedColumns.includes(set.Code_Name) &&
!set.Code_Name.includes("__metadata") !set.Code_Name.includes("__metadata")
); );
@@ -143,13 +143,13 @@
console.log(columns[j].Code_Name) console.log(columns[j].Code_Name)
// Handle Icons as they need a preview // Handle Icons as they need a preview
if(columns[j].Code_Name == 'NEWDEV_dev_Icon') if(columns[j].Code_Name == 'NEWDEV_devIcon')
{ {
input = ` input = `
<span class="input-group-addon iconPreview" my-customid="NEWDEV_dev_Icon_preview"></span> <span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
<select class="form-control" <select class="form-control"
onChange="updateIconPreview(this)" onChange="updateIconPreview(this)"
my-customparams="NEWDEV_dev_Icon,NEWDEV_dev_Icon_preview" my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
id="${columns[j].Code_Name}" id="${columns[j].Code_Name}"
data-my-column="${columns[j].Code_Name}" data-my-column="${columns[j].Code_Name}"
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" > data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" >
@@ -283,7 +283,7 @@
console.log(columnValue); console.log(columnValue);
// update selected // update selected
executeAction('update', 'dev_MAC', selectorMacs(), targetColumns, columnValue ) executeAction('update', 'devMac', selectorMacs(), targetColumns, columnValue )
} }
@@ -333,7 +333,7 @@ function askDeleteSelectedDevices () {
function deleteSelectedDevices() function deleteSelectedDevices()
{ {
macs_tmp = selectorMacs() macs_tmp = selectorMacs()
executeAction('delete', 'dev_MAC', macs_tmp ) executeAction('delete', 'devMac', macs_tmp )
write_notification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info') write_notification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info')
} }

View File

@@ -162,14 +162,14 @@
} }
// Get all leafs connected to a node based on the node_mac // Get all leafs connected to a node based on the node_mac
$func_sql = 'SELECT dev_Network_Node_port as port, $func_sql = 'SELECT devParentPort as port,
dev_MAC as mac, devMac as mac,
dev_PresentLastScan as online, devPresentLastScan as online,
dev_Name as name, devName as name,
dev_DeviceType as type, devType as type,
dev_LastIP as last_ip, devLastIP as last_ip,
(select dev_DeviceType from Devices a where dev_MAC = "'.$node_mac.'") as node_type (select devType from Devices a where devMac = "'.$node_mac.'") as node_type
FROM Devices WHERE dev_Network_Node_MAC_ADDR = "'.$node_mac.'" order by port, name asc'; FROM Devices WHERE devParentMAC = "'.$node_mac.'" order by port, name asc';
global $db; global $db;
$func_result = $db->query($func_sql); $func_result = $db->query($func_sql);
@@ -278,21 +278,21 @@
$sql = "SELECT node_name, node_mac, online, node_type, node_ports_count, parent_mac, node_icon $sql = "SELECT node_name, node_mac, online, node_type, node_ports_count, parent_mac, node_icon
FROM FROM
( (
SELECT a.dev_Name as node_name, SELECT a.devName as node_name,
a.dev_MAC as node_mac, a.devMac as node_mac,
a.dev_PresentLastScan as online, a.devPresentLastScan as online,
a.dev_DeviceType as node_type, a.devType as node_type,
a.dev_Network_Node_MAC_ADDR as parent_mac, a.devParentMAC as parent_mac,
a.dev_Icon as node_icon a.devIcon as node_icon
FROM Devices a FROM Devices a
WHERE a.dev_DeviceType in (".$networkDeviceTypes.") WHERE a.devType in (".$networkDeviceTypes.")
) t1 ) t1
LEFT JOIN LEFT JOIN
( (
SELECT b.dev_Network_Node_MAC_ADDR as node_mac_2, SELECT b.devParentMAC as node_mac_2,
count() as node_ports_count count() as node_ports_count
FROM Devices b FROM Devices b
WHERE b.dev_Network_Node_MAC_ADDR NOT NULL group by b.dev_Network_Node_MAC_ADDR WHERE b.devParentMAC NOT NULL group by b.devParentMAC
) t2 ) t2
ON (t1.node_mac = t2.node_mac_2); ON (t1.node_mac = t2.node_mac_2);
"; ";
@@ -360,15 +360,15 @@
// Get all Unassigned / unconnected nodes // Get all Unassigned / unconnected nodes
$func_sql = 'SELECT $func_sql = 'SELECT
dev_MAC AS mac, devMac AS mac,
dev_PresentLastScan AS online, devPresentLastScan AS online,
dev_Name AS name, devName AS name,
dev_LastIP AS last_ip, devLastIP AS last_ip,
dev_Network_Node_MAC_ADDR devParentMAC
FROM Devices FROM Devices
WHERE dev_Network_Node_MAC_ADDR IS NULL WHERE devParentMAC IS NULL
OR dev_Network_Node_MAC_ADDR IN ("", " ", "undefined", "null") OR devParentMAC IN ("", " ", "undefined", "null")
AND dev_MAC NOT LIKE "%internet%" AND devMac NOT LIKE "%internet%"
ORDER BY name ASC;'; ORDER BY name ASC;';
global $db; global $db;

View File

@@ -73,22 +73,22 @@ function getDeviceData() {
// Device Data // Device Data
$sql = 'SELECT rowid, *, $sql = 'SELECT rowid, *,
CASE WHEN dev_AlertDeviceDown !=0 AND dev_PresentLastScan=0 THEN "Down" CASE WHEN devAlertDown !=0 AND devPresentLastScan=0 THEN "Down"
WHEN dev_PresentLastScan=1 THEN "On-line" WHEN devPresentLastScan=1 THEN "On-line"
ELSE "Off-line" END as dev_Status ELSE "Off-line" END as devStatus
FROM Devices FROM Devices
WHERE dev_MAC="'. $mac .'" or cast(rowid as text)="'. $mac. '"'; WHERE devMac="'. $mac .'" or cast(rowid as text)="'. $mac. '"';
$result = $db->query($sql); $result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_ASSOC); $row = $result -> fetchArray (SQLITE3_ASSOC);
$deviceData = $row; $deviceData = $row;
$mac = $deviceData['dev_MAC']; $mac = $deviceData['devMac'];
$deviceData['dev_Network_Node_MAC_ADDR'] = $row['dev_Network_Node_MAC_ADDR']; $deviceData['devParentMAC'] = $row['devParentMAC'];
$deviceData['dev_Network_Node_port'] = $row['dev_Network_Node_port']; $deviceData['devParentPort'] = $row['devParentPort'];
$deviceData['dev_FirstConnection'] = formatDate ($row['dev_FirstConnection']); // Date formated $deviceData['devFirstConnection'] = formatDate ($row['devFirstConnection']); // Date formated
$deviceData['dev_LastConnection'] = formatDate ($row['dev_LastConnection']); // Date formated $deviceData['devLastConnection'] = formatDate ($row['devLastConnection']); // Date formated
$deviceData['dev_RandomMAC'] = isRandomMAC($mac); $deviceData['devRandomMAC'] = isRandomMAC($mac);
// Count Totals // Count Totals
$condition = ' WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate; $condition = ' WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate;
@@ -101,19 +101,19 @@ function getDeviceData() {
OR ses_StillConnected = 1 )'; OR ses_StillConnected = 1 )';
$result = $db->query($sql); $result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_Sessions'] = $row[0]; $deviceData['devSessions'] = $row[0];
// Events // Events
$sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" '; $sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" ';
$result = $db->query($sql); $result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_Events'] = $row[0]; $deviceData['devEvents'] = $row[0];
// Down Alerts // Down Alerts
$sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType = "Device Down"'; $sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType = "Device Down"';
$result = $db->query($sql); $result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_DownAlerts'] = $row[0]; $deviceData['devDownAlerts'] = $row[0];
// Get current date using php, sql datetime does not return time respective to timezone. // Get current date using php, sql datetime does not return time respective to timezone.
$currentdate = date("Y-m-d H:i:s"); $currentdate = date("Y-m-d H:i:s");
@@ -130,7 +130,7 @@ function getDeviceData() {
OR ses_StillConnected = 1 )'; OR ses_StillConnected = 1 )';
$result = $db->query($sql); $result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM); $row = $result -> fetchArray (SQLITE3_NUM);
$deviceData['dev_PresenceHours'] = round ($row[0]); $deviceData['devPresenceHours'] = round ($row[0]);
// Return json // Return json
echo (json_encode ($deviceData)); echo (json_encode ($deviceData));
@@ -145,27 +145,27 @@ function setDeviceData() {
// sql // sql
$sql = 'UPDATE Devices SET $sql = 'UPDATE Devices SET
dev_Name = "'. quotes($_REQUEST['name']) .'", devName = "'. quotes($_REQUEST['name']) .'",
dev_Owner = "'. quotes($_REQUEST['owner']) .'", devOwner = "'. quotes($_REQUEST['owner']) .'",
dev_DeviceType = "'. quotes($_REQUEST['type']) .'", devType = "'. quotes($_REQUEST['type']) .'",
dev_Vendor = "'. quotes($_REQUEST['vendor']) .'", devVendor = "'. quotes($_REQUEST['vendor']) .'",
dev_Icon = "'. quotes($_REQUEST['icon']) .'", devIcon = "'. quotes($_REQUEST['icon']) .'",
dev_Favorite = "'. quotes($_REQUEST['favorite']) .'", devFavorite = "'. quotes($_REQUEST['favorite']) .'",
dev_Group = "'. quotes($_REQUEST['group']) .'", devGroup = "'. quotes($_REQUEST['group']) .'",
dev_Location = "'. quotes($_REQUEST['location']) .'", devLocation = "'. quotes($_REQUEST['location']) .'",
dev_Comments = "'. quotes($_REQUEST['comments']) .'", devComments = "'. quotes($_REQUEST['comments']) .'",
dev_Network_Node_MAC_ADDR = "'. quotes($_REQUEST['networknode']).'", devParentMAC = "'. quotes($_REQUEST['networknode']).'",
dev_Network_Node_port = "'. quotes($_REQUEST['networknodeport']).'", devParentPort = "'. quotes($_REQUEST['networknodeport']).'",
dev_SSID = "'. quotes($_REQUEST['ssid']).'", devSSID = "'. quotes($_REQUEST['ssid']).'",
dev_NetworkSite = "'. quotes($_REQUEST['networksite']).'", devSite = "'. quotes($_REQUEST['networksite']).'",
dev_StaticIP = "'. quotes($_REQUEST['staticIP']) .'", devStaticIP = "'. quotes($_REQUEST['staticIP']) .'",
dev_ScanCycle = "'. quotes($_REQUEST['scancycle']) .'", devScan = "'. quotes($_REQUEST['scancycle']) .'",
dev_AlertEvents = "'. quotes($_REQUEST['alertevents']) .'", devAlertEvents = "'. quotes($_REQUEST['alertevents']) .'",
dev_AlertDeviceDown = "'. quotes($_REQUEST['alertdown']) .'", devAlertDown = "'. quotes($_REQUEST['alertdown']) .'",
dev_SkipRepeated = "'. quotes($_REQUEST['skiprepeated']) .'", devSkipRepeated = "'. quotes($_REQUEST['skiprepeated']) .'",
dev_NewDevice = "'. quotes($_REQUEST['newdevice']) .'", devIsNew = "'. quotes($_REQUEST['newdevice']) .'",
dev_Archived = "'. quotes($_REQUEST['archived']) .'" devIsArchived = "'. quotes($_REQUEST['archived']) .'"
WHERE dev_MAC="' . $_REQUEST['mac'] .'"'; WHERE devMac="' . $_REQUEST['mac'] .'"';
// update Data // update Data
$result = $db->query($sql); $result = $db->query($sql);
@@ -185,7 +185,7 @@ function deleteDevice() {
global $db; global $db;
// sql // sql
$sql = 'DELETE FROM Devices WHERE dev_MAC="' . $_REQUEST['mac'] .'"'; $sql = 'DELETE FROM Devices WHERE devMac="' . $_REQUEST['mac'] .'"';
// execute sql // execute sql
$result = $db->query($sql); $result = $db->query($sql);
@@ -204,7 +204,7 @@ function deleteAllWithEmptyMACs() {
global $db; global $db;
// sql // sql
$sql = 'DELETE FROM Devices WHERE dev_MAC=""'; $sql = 'DELETE FROM Devices WHERE devMac=""';
// execute sql // execute sql
$result = $db->query($sql); $result = $db->query($sql);
@@ -223,7 +223,7 @@ function deleteUnknownDevices() {
global $db; global $db;
// sql // sql
$sql = 'DELETE FROM Devices WHERE dev_Name="(unknown)" OR dev_Name="(name not found)"'; $sql = 'DELETE FROM Devices WHERE devName="(unknown)" OR devName="(name not found)"';
// execute sql // execute sql
$result = $db->query($sql); $result = $db->query($sql);
@@ -598,30 +598,30 @@ function getDevicesList() {
// This object is used to map from the old order ( second parameter, first number) to the new mapping, that is represented by the 3rd parameter (Second number) // This object is used to map from the old order ( second parameter, first number) to the new mapping, that is represented by the 3rd parameter (Second number)
$columnOrderMapping = array( $columnOrderMapping = array(
array("dev_Name", 0, 0), array("devName", 0, 0),
array("dev_Owner", 1, 1), array("devOwner", 1, 1),
array("dev_DeviceType", 2, 2), array("devType", 2, 2),
array("dev_Icon", 3, 3), array("devIcon", 3, 3),
array("dev_Favorite", 4, 4), array("devFavorite", 4, 4),
array("dev_Group", 5, 5), array("devGroup", 5, 5),
array("dev_FirstConnection", 6, 6), array("devFirstConnection", 6, 6),
array("dev_LastConnection", 7, 7), array("devLastConnection", 7, 7),
array("dev_LastIP", 8, 8), array("devLastIP", 8, 8),
array("dev_MAC", 9, 9), array("devMac", 9, 9),
array("dev_Status", 10, 10), array("devStatus", 10, 10),
array("dev_MAC_full", 11, 11), array("devMac_full", 11, 11),
array("dev_LastIP_orderable", 12, 12), array("devLastIP_orderable", 12, 12),
array("rowid", 13, 13), array("rowid", 13, 13),
array("dev_Network_Node_MAC_ADDR", 14, 14), array("devParentMAC", 14, 14),
array("connected_devices", 15, 15), array("connected_devices", 15, 15),
array("dev_Location", 16, 16), array("devLocation", 16, 16),
array("dev_Vendor", 17, 17), array("devVendor", 17, 17),
array("dev_Network_Node_port", 18, 18), array("devParentPort", 18, 18),
array("dev_GUID", 19, 19), array("devGUID", 19, 19),
array("dev_SyncHubNodeName", 20, 20), array("devSyncHubNode", 20, 20),
array("dev_NetworkSite", 21, 21), array("devSite", 21, 21),
array("dev_SSID", 22, 22), array("devSSID", 22, 22),
array("dev_SourcePlugin", 23, 23) array("devSourcePlugin", 23, 23)
); );
if($forceDefaultOrder == FALSE) if($forceDefaultOrder == FALSE)
@@ -650,19 +650,19 @@ function getDevicesList() {
$sql = 'SELECT * FROM ( $sql = 'SELECT * FROM (
SELECT rowid, *, CASE SELECT rowid, *, CASE
WHEN t1.dev_AlertDeviceDown !=0 AND t1.dev_PresentLastScan=0 THEN "Down" WHEN t1.devAlertDown !=0 AND t1.devPresentLastScan=0 THEN "Down"
WHEN t1.dev_NewDevice=1 THEN "New" WHEN t1.devIsNew=1 THEN "New"
WHEN t1.dev_PresentLastScan=1 THEN "On-line" WHEN t1.devPresentLastScan=1 THEN "On-line"
ELSE "Off-line" END AS dev_Status ELSE "Off-line" END AS devStatus
FROM Devices t1 '.$condition.') t3 FROM Devices t1 '.$condition.') t3
LEFT JOIN LEFT JOIN
( (
SELECT dev_Network_Node_MAC_ADDR as dev_Network_Node_MAC_ADDR_t2, dev_MAC as dev_MAC_t2, SELECT devParentMAC as devParentMAC_t2, devMac as devMac_t2,
count() as connected_devices count() as connected_devices
FROM Devices b FROM Devices b
WHERE b.dev_Network_Node_MAC_ADDR NOT NULL group by b.dev_Network_Node_MAC_ADDR WHERE b.devParentMAC NOT NULL group by b.devParentMAC
) t2 ) t2
ON (t3.dev_MAC = t2.dev_Network_Node_MAC_ADDR_t2);'; ON (t3.devMac = t2.devParentMAC_t2);';
$result = $db->query($sql); $result = $db->query($sql);
@@ -671,31 +671,31 @@ function getDevicesList() {
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$defaultOrder = array ( $defaultOrder = array (
$row['dev_Name'], $row['devName'],
$row['dev_Owner'], $row['devOwner'],
handleNull($row['dev_DeviceType']), handleNull($row['devType']),
handleNull($row['dev_Icon'], "PGkgY2xhc3M9J2ZhIGZhLWxhcHRvcCc+PC9pPg=="), // laptop icon handleNull($row['devIcon'], "PGkgY2xhc3M9J2ZhIGZhLWxhcHRvcCc+PC9pPg=="), // laptop icon
$row['dev_Favorite'], $row['devFavorite'],
$row['dev_Group'], $row['devGroup'],
// ---- // ----
formatDate ($row['dev_FirstConnection']), formatDate ($row['devFirstConnection']),
formatDate ($row['dev_LastConnection']), formatDate ($row['devLastConnection']),
$row['dev_LastIP'], $row['devLastIP'],
( isRandomMAC($row['dev_MAC']) ), ( isRandomMAC($row['devMac']) ),
$row['dev_Status'], $row['devStatus'],
$row['dev_MAC'], // MAC (hidden) $row['devMac'], // MAC (hidden)
formatIPlong ($row['dev_LastIP']), // IP orderable formatIPlong ($row['devLastIP']), // IP orderable
$row['rowid'], // Rowid (hidden) $row['rowid'], // Rowid (hidden)
handleNull($row['dev_Network_Node_MAC_ADDR']), handleNull($row['devParentMAC']),
handleNull($row['connected_devices']), handleNull($row['connected_devices']),
handleNull($row['dev_Location']), handleNull($row['devLocation']),
handleNull($row['dev_Vendor']), handleNull($row['devVendor']),
handleNull($row['dev_Network_Node_port']), handleNull($row['devParentPort']),
handleNull($row['dev_GUID']), handleNull($row['devGUID']),
handleNull($row['dev_SyncHubNodeName']), handleNull($row['devSyncHubNode']),
handleNull($row['dev_NetworkSite']), handleNull($row['devSite']),
handleNull($row['dev_SSID']), handleNull($row['devSSID']),
handleNull($row['dev_SourcePlugin']) handleNull($row['devSourcePlugin'])
); );
$newOrder = array(); $newOrder = array();
@@ -758,13 +758,13 @@ function getDevicesListCalendar() {
// arrays of rows // arrays of rows
$tableData = array(); $tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
if ($row['dev_Favorite'] == 1) { if ($row['devFavorite'] == 1) {
$row['dev_Name'] = '<span class="text-yellow">&#9733</span>&nbsp'. $row['dev_Name']; $row['devName'] = '<span class="text-yellow">&#9733</span>&nbsp'. $row['devName'];
} }
$tableData[] = array ('id' => $row['dev_MAC'], $tableData[] = array ('id' => $row['devMac'],
'title' => $row['dev_Name'], 'title' => $row['devName'],
'favorite' => $row['dev_Favorite']); 'favorite' => $row['devFavorite']);
} }
// Return json // Return json
@@ -781,14 +781,14 @@ function getIcons() {
global $db; global $db;
// Device Data // Device Data
$sql = 'select dev_Icon from Devices group by dev_Icon'; $sql = 'select devIcon from Devices group by devIcon';
$result = $db->query($sql); $result = $db->query($sql);
// arrays of rows // arrays of rows
$tableData = array(); $tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$icon = handleNull($row['dev_Icon'], "<i class='fa fa-laptop'></i>"); $icon = handleNull($row['devIcon'], "<i class='fa fa-laptop'></i>");
// Push row data // Push row data
$tableData[] = array('id' => $icon, $tableData[] = array('id' => $icon,
'name' => $icon ); 'name' => $icon );
@@ -821,7 +821,7 @@ function getDevices() {
global $db; global $db;
// Device Data // Device Data
$sql = 'select dev_MAC, dev_Name from Devices'; $sql = 'select devMac, devName from Devices';
$result = $db->query($sql); $result = $db->query($sql);
@@ -829,8 +829,8 @@ function getDevices() {
$tableData = array(); $tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$name = handleNull($row['dev_Name'], "(unknown)"); $name = handleNull($row['devName'], "(unknown)");
$mac = handleNull($row['dev_MAC'], "(unknown)"); $mac = handleNull($row['devMac'], "(unknown)");
// Push row data // Push row data
$tableData[] = array('id' => $mac, $tableData[] = array('id' => $mac,
'name' => $name ); 'name' => $name );
@@ -858,7 +858,7 @@ function updateNetworkLeaf()
{ {
global $db; global $db;
// sql // sql
$sql = 'UPDATE Devices SET "dev_Network_Node_MAC_ADDR" = "'. $nodeMac .'" WHERE "dev_MAC"="' . $leafMac.'"' ; $sql = 'UPDATE Devices SET "devParentMAC" = "'. $nodeMac .'" WHERE "devMac"="' . $leafMac.'"' ;
// update Data // update Data
$result = $db->query($sql); $result = $db->query($sql);
@@ -885,7 +885,7 @@ function overwriteIconType()
{ {
global $db; global $db;
// sql // sql
$sql = 'UPDATE Devices SET "dev_Icon" = "'. $icon .'" where dev_DeviceType in (select dev_DeviceType from Devices where dev_MAC = "' . $mac.'")' ; $sql = 'UPDATE Devices SET "devIcon" = "'. $icon .'" where devType in (select devType from Devices where devMac = "' . $mac.'")' ;
// update Data // update Data
$result = $db->query($sql); $result = $db->query($sql);
@@ -935,19 +935,19 @@ function copyFromDevice() {
$result = $db->query($sql); $result = $db->query($sql);
// create temporary table with the source data // create temporary table with the source data
$sql = "CREATE TABLE temp_devices AS SELECT * FROM Devices WHERE dev_MAC = '". $MAC_FROM . "';"; $sql = "CREATE TABLE temp_devices AS SELECT * FROM Devices WHERE devMac = '". $MAC_FROM . "';";
$result = $db->query($sql); $result = $db->query($sql);
// update temporary table with the correct target MAC // update temporary table with the correct target MAC
$sql = "UPDATE temp_devices SET dev_MAC = '". $MAC_TO . "';"; $sql = "UPDATE temp_devices SET devMac = '". $MAC_TO . "';";
$result = $db->query($sql); $result = $db->query($sql);
// delete previous entry // delete previous entry
$sql = "DELETE FROM Devices WHERE dev_MAC = '". $MAC_TO . "';"; $sql = "DELETE FROM Devices WHERE devMac = '". $MAC_TO . "';";
$result = $db->query($sql); $result = $db->query($sql);
// insert new entry with the correct target MAC from the temporary table // insert new entry with the correct target MAC from the temporary table
$sql = "INSERT INTO Devices SELECT * FROM temp_devices WHERE dev_MAC = '".$MAC_TO."'"; $sql = "INSERT INTO Devices SELECT * FROM temp_devices WHERE devMac = '".$MAC_TO."'";
$result = $db->query($sql); $result = $db->query($sql);
// clean-up temporary table // clean-up temporary table
@@ -968,13 +968,13 @@ function copyFromDevice() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function getDeviceCondition ($deviceStatus) { function getDeviceCondition ($deviceStatus) {
switch ($deviceStatus) { switch ($deviceStatus) {
case 'all': return 'WHERE dev_Archived=0'; break; case 'all': return 'WHERE devIsArchived=0'; break;
case 'my': return 'WHERE dev_Archived=0'; break; case 'my': return 'WHERE devIsArchived=0'; break;
case 'connected': return 'WHERE dev_Archived=0 AND dev_PresentLastScan=1'; break; case 'connected': return 'WHERE devIsArchived=0 AND devPresentLastScan=1'; break;
case 'favorites': return 'WHERE dev_Archived=0 AND dev_Favorite=1'; break; case 'favorites': return 'WHERE devIsArchived=0 AND devFavorite=1'; break;
case 'new': return 'WHERE dev_Archived=0 AND dev_NewDevice=1'; break; case 'new': return 'WHERE devIsArchived=0 AND devIsNew=1'; break;
case 'down': return 'WHERE dev_Archived=0 AND dev_AlertDeviceDown !=0 AND dev_PresentLastScan=0'; break; case 'down': return 'WHERE devIsArchived=0 AND devAlertDown !=0 AND devPresentLastScan=0'; break;
case 'archived': return 'WHERE dev_Archived=1'; break; case 'archived': return 'WHERE devIsArchived=1'; break;
default: return 'WHERE 1=0'; break; default: return 'WHERE 1=0'; break;
} }
} }

View File

@@ -108,12 +108,12 @@ function getEvents() {
$periodDate = getDateFromPeriod(); $periodDate = getDateFromPeriod();
// SQL // SQL
$SQL1 = 'SELECT eve_DateTime AS eve_DateTimeOrder, dev_name, dev_owner, eve_DateTime, eve_EventType, NULL, NULL, NULL, NULL, eve_IP, NULL, eve_AdditionalInfo, NULL, Dev_MAC, eve_PendingAlertEmail $SQL1 = 'SELECT eve_DateTime AS eve_DateTimeOrder, devName, devOwner, eve_DateTime, eve_EventType, NULL, NULL, NULL, NULL, eve_IP, NULL, eve_AdditionalInfo, NULL, devMac, eve_PendingAlertEmail
FROM Events_Devices FROM Events_Devices
WHERE eve_DateTime >= '. $periodDate; WHERE eve_DateTime >= '. $periodDate;
$SQL2 = 'SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder, $SQL2 = 'SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder,
dev_name, dev_owner, Null, Null, ses_DateTimeConnection, ses_DateTimeDisconnection, NULL, NULL, ses_IP, NULL, ses_AdditionalInfo, ses_StillConnected, Dev_MAC devName, devOwner, Null, Null, ses_DateTimeConnection, ses_DateTimeDisconnection, NULL, NULL, ses_IP, NULL, ses_AdditionalInfo, ses_StillConnected, devMac
FROM Sessions_Devices '; FROM Sessions_Devices ';
// SQL Variations for status // SQL Variations for status

View File

@@ -0,0 +1,85 @@
<?php
// ---- IMPORTS ----
//------------------------------------------------------------------------------
// Check if authenticated
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
// Get init.php
require dirname(__FILE__).'/../server/init.php';
// ---- IMPORTS ----
// Helper function to get GraphQL URL (you can replace this with environment variables)
function getGraphQLUrl() {
$port = getSettingValue("GRAPHQL_PORT"); // Port for the GraphQL server
// return "$url:$port/graphql"; // Full URL to the GraphQL endpoint
return "0.0.0.0:$port/graphql"; // Full URL to the GraphQL endpoint
}
// Function to make a GraphQL query
function queryGraphQL($query, $variables = null) {
$url = getGraphQLUrl();
// Prepare the request data
$data = [
'query' => $query
];
// prepare header
$api_token = getSettingValue("API_TOKEN");
$headers = [
'Content-Type: application/json',
'Authorization: Bearer ' . $api_token // Add Authorization header
];
// Add variables if provided
if ($variables) {
$data['variables'] = $variables;
}
// Encode the data as JSON
$dataJson = json_encode($data);
// Initialize cURL
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJson);
// Execute the request and handle errors
$response = curl_exec($ch);
if ($response === false) {
error_log('GraphQL Request Error: ' . curl_error($ch));
return ["error" => "Request failed (GraphQL server might be down). URL: " .$url . " Error: ". curl_error($ch)];
}
curl_close($ch);
return json_decode($response, true); // Decode and return the JSON response
}
//------------------------------------------------------------------------------
// Handle incoming requests
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Decode the JSON input from the AJAX request
$input = json_decode(file_get_contents('php://input'), true);
// Ensure the query is set
if (!isset($input['query'])) {
echo json_encode(['error' => 'No query provided']);
exit;
}
// Extract the query and variables
$query = $input['query'];
$variables = isset($input['variables']) ? $input['variables'] : null;
// Call the GraphQL function
$result = queryGraphQL($query, $variables);
// Send the response back to the client
header('Content-Type: application/json');
echo json_encode($result);
}
?>

View File

@@ -548,36 +548,36 @@ function decodeSpecialChars($str) {
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
function getDevicesColumns(){ function getDevicesColumns(){
$columns = ["dev_MAC", $columns = ["devMac",
"dev_Name", "devName",
"dev_Owner", "devOwner",
"dev_DeviceType", "devType",
"dev_Vendor", "devVendor",
"dev_Favorite", "devFavorite",
"dev_Group", "devGroup",
"dev_Comments", "devComments",
"dev_FirstConnection", "devFirstConnection",
"dev_LastConnection", "devLastConnection",
"dev_LastIP", "devLastIP",
"dev_StaticIP", "devStaticIP",
"dev_ScanCycle", "devScan",
"dev_LogEvents", "devLogEvents",
"dev_AlertEvents", "devAlertEvents",
"dev_AlertDeviceDown", "devAlertDown",
"dev_SkipRepeated", "devSkipRepeated",
"dev_LastNotification", "devLastNotification",
"dev_PresentLastScan", "devPresentLastScan",
"dev_NewDevice", "devIsNew",
"dev_Location", "devLocation",
"dev_Archived", "devIsArchived",
"dev_Network_Node_port", "devParentPort",
"dev_Network_Node_MAC_ADDR", "devParentMAC",
"dev_Icon", "devIcon",
"dev_GUID", "devGUID",
"dev_SyncHubNodeName", "devSyncHubNode",
"dev_NetworkSite", "devSite",
"dev_SSID", "devSSID",
"dev_SourcePlugin" "devSourcePlugin"
]; ];
return $columns; return $columns;

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "", "API_CUSTOM_SQL_description": "",
"API_CUSTOM_SQL_name": "", "API_CUSTOM_SQL_name": "",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "", "API_display_name": "",
"API_icon": "", "API_icon": "",
"About_Design": "", "About_Design": "",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "", "Events_Tablelenght": "",
"Events_Tablelenght_all": "", "Events_Tablelenght_all": "",
"Events_Title": "", "Events_Title": "",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "", "Gen_Action": "",
"Gen_Add": "", "Gen_Add": "",
"Gen_Add_All": "", "Gen_Add_All": "",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "", "API_CUSTOM_SQL_description": "",
"API_CUSTOM_SQL_name": "", "API_CUSTOM_SQL_name": "",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "", "API_display_name": "",
"API_icon": "", "API_icon": "",
"About_Design": "", "About_Design": "",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "", "Events_Tablelenght": "",
"Events_Tablelenght_all": "", "Events_Tablelenght_all": "",
"Events_Title": "", "Events_Title": "",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "", "Gen_Action": "",
"Gen_Add": "", "Gen_Add": "",
"Gen_Add_All": "", "Gen_Add_All": "",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "", "API_CUSTOM_SQL_description": "",
"API_CUSTOM_SQL_name": "", "API_CUSTOM_SQL_name": "",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "", "API_display_name": "",
"API_icon": "", "API_icon": "",
"About_Design": "", "About_Design": "",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "", "Events_Tablelenght": "",
"Events_Tablelenght_all": "", "Events_Tablelenght_all": "",
"Events_Title": "", "Events_Title": "",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "", "Gen_Action": "",
"Gen_Add": "", "Gen_Add": "",
"Gen_Add_All": "", "Gen_Add_All": "",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Benutzerdefinierte SQL-Abfrage, welche eine JSON-Datei generiert und diese mit dem <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\">Dateiendpunkt <code>table_custom_endpoint.json</code></a> zur Verfügung stellt.", "API_CUSTOM_SQL_description": "Benutzerdefinierte SQL-Abfrage, welche eine JSON-Datei generiert und diese mit dem <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\">Dateiendpunkt <code>table_custom_endpoint.json</code></a> zur Verfügung stellt.",
"API_CUSTOM_SQL_name": "Benutzerdefinierte SQL-Abfrage", "API_CUSTOM_SQL_name": "Benutzerdefinierte SQL-Abfrage",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"APPRISE_HOST_description": "Apprise host URL starting with <code>http://</code> or <code>https://</code>. (do not forget to include <code>/notify</code> at the end)", "APPRISE_HOST_description": "Apprise host URL starting with <code>http://</code> or <code>https://</code>. (do not forget to include <code>/notify</code> at the end)",
@@ -282,6 +284,8 @@
"Events_Tablelenght": "Zeige _MENU_ Einträge", "Events_Tablelenght": "Zeige _MENU_ Einträge",
"Events_Tablelenght_all": "Alle", "Events_Tablelenght_all": "Alle",
"Events_Title": "Ereignisse", "Events_Title": "Ereignisse",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Action", "Gen_Action": "Action",
"Gen_Add": "Hinzufügen", "Gen_Add": "Hinzufügen",
"Gen_Add_All": "Alle hinzufügen", "Gen_Add_All": "Alle hinzufügen",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "You can specify a custom SQL query which will generate a JSON file and then expose it via the <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.", "API_CUSTOM_SQL_description": "You can specify a custom SQL query which will generate a JSON file and then expose it via the <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
"API_CUSTOM_SQL_name": "Custom endpoint", "API_CUSTOM_SQL_name": "Custom endpoint",
"API_TOKEN_description": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. Used in the <code>SYNC</code> plugin, GraphQL server.",
"API_TOKEN_name": "API token",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Designed for:", "About_Design": "Designed for:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Show _MENU_ entries", "Events_Tablelenght": "Show _MENU_ entries",
"Events_Tablelenght_all": "All", "Events_Tablelenght_all": "All",
"Events_Title": "Events", "Events_Title": "Events",
"GRAPHQL_PORT_description": "The port number of the GraphQL server.",
"GRAPHQL_PORT_name": "GraphQL port",
"Gen_Action": "Action", "Gen_Action": "Action",
"Gen_Add": "Add", "Gen_Add": "Add",
"Gen_Add_All": "Add all", "Gen_Add_All": "Add all",

6
front/php/templates/language/es_es.json Normal file → Executable file
View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Puede especificar una consulta SQL personalizada que generará un archivo JSON y luego lo expondrá a través del <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\">archivo <code>table_custom_endpoint.json</code ></a>.", "API_CUSTOM_SQL_description": "Puede especificar una consulta SQL personalizada que generará un archivo JSON y luego lo expondrá a través del <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\">archivo <code>table_custom_endpoint.json</code ></a>.",
"API_CUSTOM_SQL_name": "Endpoint personalizado", "API_CUSTOM_SQL_name": "Endpoint personalizado",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"APPRISE_HOST_description": "URL del host de Apprise que comienza con <code>http://</code> o <code>https://</code>. (no olvide incluir <code>/notify</code> al final)", "APPRISE_HOST_description": "URL del host de Apprise que comienza con <code>http://</code> o <code>https://</code>. (no olvide incluir <code>/notify</code> al final)",
@@ -280,6 +282,8 @@
"Events_Tablelenght": "Mostrando entradas del MENÚ", "Events_Tablelenght": "Mostrando entradas del MENÚ",
"Events_Tablelenght_all": "Todos", "Events_Tablelenght_all": "Todos",
"Events_Title": "Eventos", "Events_Title": "Eventos",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Acción", "Gen_Action": "Acción",
"Gen_Add": "Añadir", "Gen_Add": "Añadir",
"Gen_Add_All": "Añadir todo", "Gen_Add_All": "Añadir todo",
@@ -790,4 +794,4 @@
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. <b>O la validación no se realiza.</b>", "settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. <b>O la validación no se realiza.</b>",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes." "test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
} }

6
front/php/templates/language/fr_fr.json Normal file → Executable file
View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Vous pouvez spécifier votre propre requête SQL qui retournera un fichier JSON et l'exposer via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> le point de terminaison de fichier</a>.", "API_CUSTOM_SQL_description": "Vous pouvez spécifier votre propre requête SQL qui retournera un fichier JSON et l'exposer via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> le point de terminaison de fichier</a>.",
"API_CUSTOM_SQL_name": "Point de terminaison personnalisé", "API_CUSTOM_SQL_name": "Point de terminaison personnalisé",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Conçu pour:", "About_Design": "Conçu pour:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Afficher _MENU_ entrées", "Events_Tablelenght": "Afficher _MENU_ entrées",
"Events_Tablelenght_all": "Tous", "Events_Tablelenght_all": "Tous",
"Events_Title": "Évènements", "Events_Title": "Évènements",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Action", "Gen_Action": "Action",
"Gen_Add": "Ajouter", "Gen_Add": "Ajouter",
"Gen_Add_All": "Ajouter tous", "Gen_Add_All": "Ajouter tous",
@@ -711,4 +715,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>", "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_icon": "fa-vial-circle-check",
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage." "test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
} }

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

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite l'<a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code>endpoint del file</a>.", "API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite l'<a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code>endpoint del file</a>.",
"API_CUSTOM_SQL_name": "Endpoint personalizzato", "API_CUSTOM_SQL_name": "Endpoint personalizzato",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Progettato per:", "About_Design": "Progettato per:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Mostra _MENU_ elementi", "Events_Tablelenght": "Mostra _MENU_ elementi",
"Events_Tablelenght_all": "Tutti", "Events_Tablelenght_all": "Tutti",
"Events_Title": "Eventi", "Events_Title": "Eventi",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Azione", "Gen_Action": "Azione",
"Gen_Add": "Aggiungi", "Gen_Add": "Aggiungi",
"Gen_Add_All": "Aggiungi tutti", "Gen_Add_All": "Aggiungi tutti",
@@ -711,4 +715,4 @@
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>", "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_icon": "fa-vial-circle-check",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni." "test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
} }

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Du kan spesifisere en egendefinert SQL-Spørring som vil generere en JSON-fil og deretter eksponere den via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.", "API_CUSTOM_SQL_description": "Du kan spesifisere en egendefinert SQL-Spørring som vil generere en JSON-fil og deretter eksponere den via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
"API_CUSTOM_SQL_name": "Egendefinert endepunkt", "API_CUSTOM_SQL_name": "Egendefinert endepunkt",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Designet for:", "About_Design": "Designet for:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Show _MENU_ entries", "Events_Tablelenght": "Show _MENU_ entries",
"Events_Tablelenght_all": "Alle", "Events_Tablelenght_all": "Alle",
"Events_Title": "Hendelser", "Events_Title": "Hendelser",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Handling", "Gen_Action": "Handling",
"Gen_Add": "Legg til", "Gen_Add": "Legg til",
"Gen_Add_All": "Legg til alle", "Gen_Add_All": "Legg til alle",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Możesz określić własne zapytanie SQL które będzie generowało plik JSON i udostępnić je poprzez plik typu endpoint <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> </a>.", "API_CUSTOM_SQL_description": "Możesz określić własne zapytanie SQL które będzie generowało plik JSON i udostępnić je poprzez plik typu endpoint <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> </a>.",
"API_CUSTOM_SQL_name": "Własny endpoint", "API_CUSTOM_SQL_name": "Własny endpoint",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Zaprojektowany dla:", "About_Design": "Zaprojektowany dla:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Pokaż_wpisy_MENU", "Events_Tablelenght": "Pokaż_wpisy_MENU",
"Events_Tablelenght_all": "Wszystkie", "Events_Tablelenght_all": "Wszystkie",
"Events_Title": "Wydarzenia", "Events_Title": "Wydarzenia",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Akcja", "Gen_Action": "Akcja",
"Gen_Add": "Dodaj", "Gen_Add": "Dodaj",
"Gen_Add_All": "Dodaj wszystko", "Gen_Add_All": "Dodaj wszystko",

View File

@@ -1,6 +1,8 @@
{ {
"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=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> endpoint do arquivo</a>.", "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=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> endpoint do arquivo</a>.",
"API_CUSTOM_SQL_name": "Endpoint customizado", "API_CUSTOM_SQL_name": "Endpoint customizado",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Desenvolvido por:", "About_Design": "Desenvolvido por:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Mostrar entradas do _MENU_", "Events_Tablelenght": "Mostrar entradas do _MENU_",
"Events_Tablelenght_all": "Todos", "Events_Tablelenght_all": "Todos",
"Events_Title": "Eventos", "Events_Title": "Eventos",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Ação", "Gen_Action": "Ação",
"Gen_Add": "Adicionar", "Gen_Add": "Adicionar",
"Gen_Add_All": "Adicionar todos", "Gen_Add_All": "Adicionar todos",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "Вы можете указать собственный SQL-запрос, который будет генерировать файл JSON, а затем предоставлять его через конечную точку файла <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code></a>.", "API_CUSTOM_SQL_description": "Вы можете указать собственный SQL-запрос, который будет генерировать файл JSON, а затем предоставлять его через конечную точку файла <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code></a>.",
"API_CUSTOM_SQL_name": "Пользовательская конечная точка", "API_CUSTOM_SQL_name": "Пользовательская конечная точка",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Разработан:", "About_Design": "Разработан:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "Показать _MENU_ записей", "Events_Tablelenght": "Показать _MENU_ записей",
"Events_Tablelenght_all": "Все", "Events_Tablelenght_all": "Все",
"Events_Title": "События", "Events_Title": "События",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Действия", "Gen_Action": "Действия",
"Gen_Add": "Добавить", "Gen_Add": "Добавить",
"Gen_Add_All": "Добавить все", "Gen_Add_All": "Добавить все",
@@ -711,4 +715,4 @@
"settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>", "settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки." "test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки."
} }

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "", "API_CUSTOM_SQL_description": "",
"API_CUSTOM_SQL_name": "", "API_CUSTOM_SQL_name": "",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "", "API_display_name": "",
"API_icon": "", "API_icon": "",
"About_Design": "", "About_Design": "",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "", "Events_Tablelenght": "",
"Events_Tablelenght_all": "", "Events_Tablelenght_all": "",
"Events_Title": "", "Events_Title": "",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "Komut", "Gen_Action": "Komut",
"Gen_Add": "Ekle", "Gen_Add": "Ekle",
"Gen_Add_All": "Tümünü ekle", "Gen_Add_All": "Tümünü ekle",

View File

@@ -1,6 +1,8 @@
{ {
"API_CUSTOM_SQL_description": "您可以指定一个自定义 SQL 查询,它将生成一个 JSON 文件,然后通过 <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> 文件端点</a> 公开它。", "API_CUSTOM_SQL_description": "您可以指定一个自定义 SQL 查询,它将生成一个 JSON 文件,然后通过 <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> 文件端点</a> 公开它。",
"API_CUSTOM_SQL_name": "自定义终点", "API_CUSTOM_SQL_name": "自定义终点",
"API_TOKEN_description": "",
"API_TOKEN_name": "",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "设计用于:", "About_Design": "设计用于:",
@@ -270,6 +272,8 @@
"Events_Tablelenght": "", "Events_Tablelenght": "",
"Events_Tablelenght_all": "全部", "Events_Tablelenght_all": "全部",
"Events_Title": "事件", "Events_Title": "事件",
"GRAPHQL_PORT_description": "",
"GRAPHQL_PORT_name": "",
"Gen_Action": "动作", "Gen_Action": "动作",
"Gen_Add": "增加", "Gen_Add": "增加",
"Gen_Add_All": "全部添加", "Gen_Add_All": "全部添加",

View File

@@ -55,7 +55,7 @@ $configLines = file(CONFIG_PATH);
// Handle web protection and password // Handle web protection and password
$nax_WebProtection = strtolower(trim(getConfigLine('/^SETPWD_enable_password.*=/', $configLines)[1] ?? 'false')); $nax_WebProtection = strtolower(trim(getConfigLine('/^SETPWD_enable_password.*=/', $configLines)[1] ?? 'false'));
$nax_Password = getConfigValue('/^SETPWD_password.*=/', $configLines); $nax_Password = getConfigValue('/^SETPWD_password.*=/', $configLines);
$api_token = getConfigValue('/^SYNC_api_token.*=/', $configLines, "'"); $api_token = getConfigValue('/^API_TOKEN.*=/', $configLines, "'");
$expectedToken = 'Bearer ' . $api_token; $expectedToken = 'Bearer ' . $api_token;

View File

@@ -41,7 +41,7 @@
{ {
"name": "devices", "name": "devices",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP from DEVICES", "value": "SELECT devLastIP from DEVICES",
"timeoutMultiplier": true "timeoutMultiplier": true
} }
], ],
@@ -740,7 +740,7 @@
{ "elementType": "input", "elementOptions": [], "transformers": [] } { "elementType": "input", "elementOptions": [], "transformers": [] }
] ]
}, },
"default_value": "select rowid, * from Devices where dev_Name not in ({s-quote}null{s-quote}, {s-quote}(name not found){s-quote}, {s-quote}(unknown){s-quote})", "default_value": "select rowid, * from Devices where devName not in ({s-quote}null{s-quote}, {s-quote}(name not found){s-quote}, {s-quote}(unknown){s-quote})",
"options": [], "options": [],
"localized": ["name", "description"], "localized": ["name", "description"],
"name": [ "name": [

View File

@@ -443,49 +443,49 @@ def mqtt_start(db):
for device in devices: for device in devices:
# # debug statement START 🔻 # # debug statement START 🔻
# if 'Moto' not in device["dev_Name"]: # if 'Moto' not in device["devName"]:
# continue # continue
# # debug statement END 🔺 # # debug statement END 🔺
# Create devices in Home Assistant - send config messages # Create devices in Home Assistant - send config messages
deviceId = 'mac_' + device["dev_MAC"].replace(" ", "").replace(":", "_").lower() deviceId = 'mac_' + device["devMac"].replace(" ", "").replace(":", "_").lower()
# Normalize the string and remove unwanted characters # Normalize the string and remove unwanted characters
devDisplayName = re.sub('[^a-zA-Z0-9-_\\s]', '', normalize_string(device["dev_Name"])) devDisplayName = re.sub('[^a-zA-Z0-9-_\\s]', '', normalize_string(device["devName"]))
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_ip', 'ip-network', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_ip', 'ip-network', device["devMac"])
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'mac_address', 'folder-key-network', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'mac_address', 'folder-key-network', device["devMac"])
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'is_new', 'bell-alert-outline', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'is_new', 'bell-alert-outline', device["devMac"])
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'vendor', 'cog', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'vendor', 'cog', device["devMac"])
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'first_connection', 'calendar-start', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'first_connection', 'calendar-start', device["devMac"])
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_connection', 'calendar-end', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_connection', 'calendar-end', device["devMac"])
devJson = { devJson = {
"last_ip": device["dev_LastIP"], "last_ip": device["devLastIP"],
"is_new": str(device["dev_NewDevice"]), "is_new": str(device["devIsNew"]),
"vendor": sanitize_string(device["dev_Vendor"]), "vendor": sanitize_string(device["devVendor"]),
"mac_address": str(device["dev_MAC"]), "mac_address": str(device["devMac"]),
"model": devDisplayName, "model": devDisplayName,
"last_connection": prepTimeStamp(str(device["dev_LastConnection"])), "last_connection": prepTimeStamp(str(device["devLastConnection"])),
"first_connection": prepTimeStamp(str(device["dev_FirstConnection"])) } "first_connection": prepTimeStamp(str(device["devFirstConnection"])) }
# bulk update device sensors in home assistant # bulk update device sensors in home assistant
publish_mqtt(mqtt_client, sensorConfig.state_topic, devJson) publish_mqtt(mqtt_client, sensorConfig.state_topic, devJson)
# create and update is_present sensor # create and update is_present sensor
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'binary_sensor', 'is_present', 'wifi', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'binary_sensor', 'is_present', 'wifi', device["devMac"])
publish_mqtt(mqtt_client, sensorConfig.state_topic, publish_mqtt(mqtt_client, sensorConfig.state_topic,
{ {
"is_present": to_binary_sensor(str(device["dev_PresentLastScan"])) "is_present": to_binary_sensor(str(device["devPresentLastScan"]))
} }
) )
# handle device_tracker # handle device_tracker
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'device_tracker', 'is_home', 'home', device["dev_MAC"]) sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'device_tracker', 'is_home', 'home', device["devMac"])
# <away|home> are only valid states # <away|home> are only valid states
state = 'away' state = 'away'
if to_binary_sensor(str(device["dev_PresentLastScan"])) == "ON": if to_binary_sensor(str(device["devPresentLastScan"])) == "ON":
state = 'home' state = 'home'
publish_mqtt(mqtt_client, sensorConfig.state_topic, state) publish_mqtt(mqtt_client, sensorConfig.state_topic, state)

View File

@@ -56,9 +56,9 @@ def main():
# Mock list of devices (replace with actual device_handler.getUnknown() in production) # Mock list of devices (replace with actual device_handler.getUnknown() in production)
# unknown_devices = [ # unknown_devices = [
# {'dev_MAC': '00:11:22:33:44:55', 'dev_LastIP': '192.168.1.121'}, # {'devMac': '00:11:22:33:44:55', 'devLastIP': '192.168.1.121'},
# {'dev_MAC': '00:11:22:33:44:56', 'dev_LastIP': '192.168.1.9'}, # {'devMac': '00:11:22:33:44:56', 'devLastIP': '192.168.1.9'},
# {'dev_MAC': '00:11:22:33:44:57', 'dev_LastIP': '192.168.1.82'}, # {'devMac': '00:11:22:33:44:57', 'devLastIP': '192.168.1.82'},
# ] # ]
mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}']) mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
@@ -68,20 +68,20 @@ def main():
ensure_avahi_running() ensure_avahi_running()
for device in unknown_devices: for device in unknown_devices:
domain_name = execute_name_lookup(device['dev_LastIP'], timeout) domain_name = execute_name_lookup(device['devLastIP'], timeout)
# check if found and not a timeout ('to') # check if found and not a timeout ('to')
if domain_name != '' and domain_name != 'to': if domain_name != '' and domain_name != 'to':
plugin_objects.add_object( plugin_objects.add_object(
# "MAC", "IP", "Server", "Name" # "MAC", "IP", "Server", "Name"
primaryId = device['dev_MAC'], primaryId = device['devMac'],
secondaryId = device['dev_LastIP'], secondaryId = device['devLastIP'],
watched1 = '', # You can add any relevant info here if needed watched1 = '', # You can add any relevant info here if needed
watched2 = domain_name, watched2 = domain_name,
watched3 = '', watched3 = '',
watched4 = '', watched4 = '',
extra = '', extra = '',
foreignKey = device['dev_MAC']) foreignKey = device['devMac'])
plugin_objects.write_result_file() plugin_objects.write_result_file()

View File

@@ -38,7 +38,7 @@
{ {
"name": "ips", "name": "ips",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC", "value": "SELECT devLastIP from DEVICES order by devMac",
"timeoutMultiplier": true "timeoutMultiplier": true
} }
], ],

View File

@@ -141,7 +141,7 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
# Cleanup New Devices # Cleanup New Devices
if HRS_TO_KEEP_NEWDEV != 0: if HRS_TO_KEEP_NEWDEV != 0:
mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_NEWDEV)} hours (HRS_TO_KEEP_NEWDEV setting)']) mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_NEWDEV)} hours (HRS_TO_KEEP_NEWDEV setting)'])
query = f"""DELETE FROM Devices WHERE dev_NewDevice = 1 AND dev_FirstConnection < date('now', '-{str(HRS_TO_KEEP_NEWDEV)} hour')""" query = f"""DELETE FROM Devices WHERE devIsNew = 1 AND devFirstConnection < date('now', '-{str(HRS_TO_KEEP_NEWDEV)} hour')"""
mylog('verbose', [f'[{pluginName}] Query: {query} ']) mylog('verbose', [f'[{pluginName}] Query: {query} '])
cursor.execute (query) cursor.execute (query)
@@ -149,7 +149,7 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
# Cleanup Offline Devices # Cleanup Offline Devices
if HRS_TO_KEEP_OFFDEV != 0: if HRS_TO_KEEP_OFFDEV != 0:
mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_OFFDEV)} hours (HRS_TO_KEEP_OFFDEV setting)']) mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_OFFDEV)} hours (HRS_TO_KEEP_OFFDEV setting)'])
query = f"""DELETE FROM Devices WHERE dev_PresentLastScan = 0 AND dev_LastConnection < date('now', '-{str(HRS_TO_KEEP_OFFDEV)} hour'))""" query = f"""DELETE FROM Devices WHERE devPresentLastScan = 0 AND devLastConnection < date('now', '-{str(HRS_TO_KEEP_OFFDEV)} hour'))"""
mylog('verbose', [f'[{pluginName}] Query: {query} ']) mylog('verbose', [f'[{pluginName}] Query: {query} '])
cursor.execute (query) cursor.execute (query)
@@ -157,8 +157,8 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
# Clear New Flag # Clear New Flag
if CLEAR_NEW_FLAG != 0: if CLEAR_NEW_FLAG != 0:
mylog('verbose', [f'[{pluginName}] Devices: Clear "New Device" flag for all devices older than {str(CLEAR_NEW_FLAG)} hours (CLEAR_NEW_FLAG setting)']) mylog('verbose', [f'[{pluginName}] Devices: Clear "New Device" flag for all devices older than {str(CLEAR_NEW_FLAG)} hours (CLEAR_NEW_FLAG setting)'])
query = f"""UPDATE Devices SET dev_NewDevice = 0 WHERE dev_NewDevice = 1 AND date(dev_FirstConnection, '+{str(CLEAR_NEW_FLAG)} hour') < date('now')""" query = f"""UPDATE Devices SET devIsNew = 0 WHERE devIsNew = 1 AND date(devFirstConnection, '+{str(CLEAR_NEW_FLAG)} hour') < date('now')"""
# select * from Devices where dev_NewDevice = 1 AND date(dev_FirstConnection, '+3 hour' ) < date('now') # select * from Devices where devIsNew = 1 AND date(devFirstConnection, '+3 hour' ) < date('now')
mylog('verbose', [f'[{pluginName}] Query: {query} ']) mylog('verbose', [f'[{pluginName}] Query: {query} '])
cursor.execute(query) cursor.execute(query)

View File

@@ -49,7 +49,7 @@
{ {
"name": "prev_ip", "name": "prev_ip",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' " "value": "SELECT devLastIP FROM Devices WHERE devMac = 'Internet' "
}, },
{ {
"name": "DDNS_UPDATE_URL", "name": "DDNS_UPDATE_URL",

View File

@@ -1,967 +0,0 @@
{
"code_name": "events_notifications",
"plugin_type": "flow",
"template_type": "database-entry",
"unique_prefix": "EVNTNTF",
"enabled": true,
"data_source": "template",
"show_ui": false,
"localized": ["display_name", "description", "icon"],
"display_name": [
{
"language_code": "en_us",
"string": "Known Devices"
}
],
"description": [
{
"language_code": "en_us",
"string": "The template used for known devices."
}
],
"icon": [
{
"language_code": "en_us",
"string": "<i class=\"fa fa-check\"></i>"
}
],
"params": [
{
"name": "target_macs",
"type": "setting",
"value": "KNWN_target_macs"
},
{
"name": "dev_AlertDeviceDown",
"type": "setting",
"value": "KNWN_dev_AlertDeviceDown"
},
{
"name": "dev_AlertEvents",
"type": "setting",
"value": "KNWN_dev_AlertEvents"
},
{
"name": "trigger_ids",
"type": "array",
"value": "trigger.Object_PrimaryID"
},
{
"name": "trigger_objects",
"type": "array",
"value": "trigger"
}
],
"settings": [
{
"function": "FLOW",
"type": "json",
"default_value": [
{
"name": "send_notification",
"trigger": [
{
"object_event": "new",
"object_filter": "",
"object": "Events_Notifications"
}
],
"steps": [
{
"step_type": "wait",
"params": [
{
"days": 0,
"hours": 0,
"minutes": 0,
"seconds": 30
}
]
},
{
"step_type": "condition",
"params": [
{
"left": {
"value": "triggers[0].object['dev_DeviceID']",
"use_quotes": true,
"js_template": "'{value}'.toString()"
},
"operator": {
"value": "==",
"data_type": "string"
},
"right": {
"value": "device_id_param",
"use_quotes": false,
"js_template": "'{value}'.toString()"
}
}
]
},
{
"step_type": "condition",
"params": [
{
"left": {
"value": "check_event_repetition(device_id_param, event_type_param, repetition_count_param)",
"use_quotes": false,
"js_template": "{value}"
},
"operator": {
"value": "==",
"data_type": "boolean"
},
"right": {
"value": true,
"use_quotes": false,
"js_template": "{value}"
}
}
]
},
{
"step_type": "action",
"params": [
{
"type": "run_plugin",
"params": {
"unique_prefix": "webhook"
}
}
]
},
{
"step_type": "action",
"params": [
{
"type": "run_plugin",
"params": {
"unique_prefix": "mqtt"
}
}
]
}
]
}
],
"options": [
{
"name": [
{
"language_code": "en_us",
"string": "Device ID Parameter"
}
],
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [],
"transformers": []
}
]
},
"default_value": "1",
"localized": ["name"]
},
{
"name": [
{
"language_code": "en_us",
"string": "Event Type Parameter"
}
],
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [],
"transformers": []
}
]
},
"default_value": "device_down",
"localized": ["name"]
},
{
"name": [
{
"language_code": "en_us",
"string": "Repetition Count Parameter"
}
],
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 3,
"localized": ["name"]
}
],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Plugin flow"
}
],
"description": [
{
"language_code": "en_us",
"string": "This flow sends a notification after 30s every time a new event is logged."
}
]
},
{
"function": "target_macs",
"type": "list.readonly",
"maxLength": 50,
"default_value": [],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Target devices"
}
],
"description": [
{
"language_code": "en_us",
"string": "The MAC address of the devices to update. Uneditable. This parameter is dynamically updated via a Flow."
}
]
},
{
"function": "CMD",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "UPDATE SQL"
}
],
"description": [
{
"language_code": "en_us",
"string": "This SQL query is used to update target devices."
}
]
},
{
"function": "dev_Name",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "(unknown)",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Name"
}
],
"description": [
{
"language_code": "en_us",
"string": "The name of the device. Uneditable as internal functionality is dependent on specific new device names."
}
]
},
{
"function": "dev_Owner",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "House",
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Owner"
}
],
"description": [
{
"language_code": "en_us",
"string": "The owner of the device."
}
]
},
{
"function": "dev_DeviceType",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Type"
}
],
"description": [
{
"language_code": "en_us",
"string": "The type of the device."
}
]
},
{
"function": "dev_Vendor",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 250,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Vendor"
}
],
"description": [
{
"language_code": "en_us",
"string": "The vendor of the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_Favorite",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Favorite Device"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device is marked as a favorite."
}
]
},
{
"function": "dev_Group",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 10,
"default_value": "",
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Group"
}
],
"description": [
{
"language_code": "en_us",
"string": "The group to which the device belongs."
}
]
},
{
"function": "dev_Comments",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Comments"
}
],
"description": [
{
"language_code": "en_us",
"string": "Additional comments or notes about the device."
}
]
},
{
"function": "dev_FirstConnection",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "First Connection"
}
],
"description": [
{
"language_code": "en_us",
"string": "The date and time of the first connection with the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_LastConnection",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Last Connection"
}
],
"description": [
{
"language_code": "en_us",
"string": "The date and time of the last connection with the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_LastIP",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Last IP"
}
],
"description": [
{
"language_code": "en_us",
"string": "The last known IP address of the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_StaticIP",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Static IP"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device has a static IP address."
}
]
},
{
"function": "dev_ScanCycle",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Scan Cycle"
}
],
"description": [
{
"language_code": "en_us",
"string": "The default value of the <code>Scan device</code> dropdown. Enable if newly discovered devices should be scanned."
}
]
},
{
"function": "dev_LogEvents",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Log Events"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether events related to the device shouldbe logged."
}
]
},
{
"function": "dev_AlertEvents",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": true
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Alert Events"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert Events</code> checkbox. Down and New Device notifications are always sent unless unselected in <code>NTFPRCS_INCLUDED_SECTIONS</code>."
}
]
},
{
"function": "dev_AlertDeviceDown",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Alert Device Down"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether an alert should be triggered when the device goes down. The default value of the <code>Alert Down</code> checkbox."
}
]
},
{
"function": "dev_SkipRepeated",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Skip Repeated"
}
],
"description": [
{
"language_code": "en_us",
"string": "The default value of the <code>Skip repeated notifications for</code> dropdown. Enter number of <b>hours</b> for which repeated notifications should be ignored for. If you enter <code>0</code> then you get notified on all events."
}
]
},
{
"function": "dev_LastNotification",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Last Notification"
}
],
"description": [
{
"language_code": "en_us",
"string": "The date and time of the last notification sent for the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_PresentLastScan",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Present Last Scan"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device should be marked as present after detected in a scan."
}
]
},
{
"function": "dev_NewDevice",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "New Device"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device is considered a new device. The default value of the <code>New Device</code> checkbox."
}
]
},
{
"function": "dev_Location",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 250,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Location"
}
],
"description": [
{
"language_code": "en_us",
"string": "The location of the device."
}
]
},
{
"function": "dev_Archived",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Archived"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device is archived. The default value of the <code>Archived</code> checkbox."
}
]
},
{
"function": "dev_Network_Node_MAC_ADDR",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Network Node MAC Address"
}
],
"description": [
{
"language_code": "en_us",
"string": "The MAC address of the network node."
}
]
},
{
"function": "dev_Network_Node_port",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Network Node Port"
}
],
"description": [
{
"language_code": "en_us",
"string": "The port number of the network node. Uneditable."
}
]
},
{
"function": "dev_Icon",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Icon"
}
],
"description": [
{
"language_code": "en_us",
"string": "The icon associated with the device. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentation on icons</a> for more details."
}
]
}
],
"required": [
"dev_MAC",
"dev_Name",
"dev_Owner",
"dev_FirstConnection",
"dev_LastConnection",
"dev_LastIP",
"dev_StaticIP",
"dev_ScanCycle",
"dev_LogEvents",
"dev_AlertEvents",
"dev_AlertDeviceDown",
"dev_SkipRepeated",
"dev_LastNotification",
"dev_PresentLastScan",
"dev_NewDevice",
"dev_Location",
"dev_Archived",
"dev_Network_Node_MAC_ADDR",
"dev_Network_Node_port",
"dev_Icon"
],
"additionalProperties": false
}

View File

@@ -1 +0,0 @@
This plugin will not be loaded

View File

@@ -51,7 +51,7 @@
{ {
"name": "prev_ip", "name": "prev_ip",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' " "value": "SELECT devLastIP FROM Devices WHERE devMac = 'Internet' "
}, },
{ {
"name": "INTRNT_DIG_GET_IP_ARG", "name": "INTRNT_DIG_GET_IP_ARG",

View File

@@ -1,11 +0,0 @@
## Overview
A simple template-based plugin for known devices. You can change to overwrite values for known devices.
### Usage
- Head to **Settings** > **Known Devices** to adjust the default values.
### Notes
- This plugin generates editable settings that are then used in the `device.py` script to initialize new values. TO FIX

View File

@@ -1,883 +0,0 @@
{
"code_name": "known_template",
"template_type": "database-entry",
"unique_prefix": "KNWN",
"plugin_type": "system",
"enabled": true,
"data_source": "template",
"show_ui": false,
"localized": ["display_name", "description", "icon"],
"display_name": [
{
"language_code": "en_us",
"string": "Known Devices"
}
],
"description": [
{
"language_code": "en_us",
"string": "The template used for known devices."
}
],
"icon": [
{
"language_code": "en_us",
"string": "<i class=\"fa fa-check\"></i>"
}
],
"params": [
{
"name": "target_macs",
"type": "setting",
"value": "KNWN_target_macs"
},
{
"name": "dev_AlertDeviceDown",
"type": "setting",
"value": "KNWN_dev_AlertDeviceDown"
},
{
"name": "dev_AlertEvents",
"type": "setting",
"value": "KNWN_dev_AlertEvents"
},
{
"name": "trigger_ids",
"type": "array",
"value": "trigger.Object_PrimaryID"
},
{
"name": "trigger_objects",
"type": "array",
"value": "trigger"
}
],
"settings": [
{
"function": "FLOW",
"type": "json",
"default_value": [
{
"name": "apply_template",
"trigger": [
{
"object_event": "new",
"object_filter": "",
"object": "Devices"
}
],
"steps": [
{
"step_type": "wait",
"params": [
{
"days": 3,
"hours": 0,
"minutes": 0,
"seconds": 0
}
]
},
{
"step_type": "condition",
"params": [
{
"left": {
"value": "triggers[0].object['dev_NewDevice']",
"use_quotes": true,
"js_template": "'{value}'.toString()"
},
"operator": {
"value": "==",
"data_type": "boolean"
},
"right": {
"value": true,
"use_quotes": false,
"js_template": "'{value}'.toString()"
}
}
]
},
{
"step_type": "action",
"params": [
{
"type": "plugin",
"params": {
"unique_prefix": "KNWN",
"overrides": [
{
"object_path": "settings.0",
"key": "function",
"value": "target_macs",
"target_property": "default_value",
"desired_value": "triggers.keys"
}
]
}
}
]
}
]
}
],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Plugin flow"
}
],
"description": [
{
"language_code": "en_us",
"string": "This flow makes sure the template is applied to devices that are older than 3 days."
}
]
},
{
"function": "target_macs",
"type": "list.readonly",
"maxLength": 50,
"default_value": [],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Target devices"
}
],
"description": [
{
"language_code": "en_us",
"string": "The MAC address of the devices to update. Uneditable. This parameter is dynamically updated via a Flow."
}
]
},
{
"function": "CMD",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "UPDATE SQL"
}
],
"description": [
{
"language_code": "en_us",
"string": "This SQL query is used to update target devices."
}
]
},
{
"function": "dev_Name",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "(unknown)",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Name"
}
],
"description": [
{
"language_code": "en_us",
"string": "The name of the device. Uneditable as internal functionality is dependent on specific new device names."
}
]
},
{
"function": "dev_Owner",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "House",
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Owner"
}
],
"description": [
{
"language_code": "en_us",
"string": "The owner of the device."
}
]
},
{
"function": "dev_DeviceType",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 30,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Type"
}
],
"description": [
{
"language_code": "en_us",
"string": "The type of the device."
}
]
},
{
"function": "dev_Vendor",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 250,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Vendor"
}
],
"description": [
{
"language_code": "en_us",
"string": "The vendor of the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_Favorite",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Favorite Device"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device is marked as a favorite."
}
]
},
{
"function": "dev_Group",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 10,
"default_value": "",
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Group"
}
],
"description": [
{
"language_code": "en_us",
"string": "The group to which the device belongs."
}
]
},
{
"function": "dev_Comments",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Comments"
}
],
"description": [
{
"language_code": "en_us",
"string": "Additional comments or notes about the device."
}
]
},
{
"function": "dev_FirstConnection",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "First Connection"
}
],
"description": [
{
"language_code": "en_us",
"string": "The date and time of the first connection with the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_LastConnection",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Last Connection"
}
],
"description": [
{
"language_code": "en_us",
"string": "The date and time of the last connection with the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_LastIP",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Last IP"
}
],
"description": [
{
"language_code": "en_us",
"string": "The last known IP address of the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_StaticIP",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Static IP"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device has a static IP address."
}
]
},
{
"function": "dev_ScanCycle",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"override_value": {
"override": true
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Scan Cycle"
}
],
"description": [
{
"language_code": "en_us",
"string": "The default value of the <code>Scan device</code> dropdown. Enable if newly discovered devices should be scanned."
}
]
},
{
"function": "dev_LogEvents",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": false
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Log Events"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether events related to the device shouldbe logged."
}
]
},
{
"function": "dev_AlertEvents",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"override_value": {
"override": true
},
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Alert Events"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert All Events</code> checkbox."
}
]
},
{
"function": "dev_AlertDeviceDown",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Alert Device Down"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether an alert should be triggered when the device goes down. The default value of the <code>Alert Down</code> checkbox."
}
]
},
{
"function": "dev_SkipRepeated",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Skip Repeated"
}
],
"description": [
{
"language_code": "en_us",
"string": "The default value of the <code>Skip repeated notifications for</code> dropdown. Enter number of <b>hours</b> for which repeated notifications should be ignored for. If you enter <code>0</code> then you get notified on all events."
}
]
},
{
"function": "dev_LastNotification",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"format": "date-time",
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Last Notification"
}
],
"description": [
{
"language_code": "en_us",
"string": "The date and time of the last notification sent for the device. Uneditable - Autodetected."
}
]
},
{
"function": "dev_PresentLastScan",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 1,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Present Last Scan"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device should be marked as present after detected in a scan."
}
]
},
{
"function": "dev_NewDevice",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": true,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "New Device"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device is considered a new device. The default value of the <code>New Device</code> checkbox."
}
]
},
{
"function": "dev_Location",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"maxLength": 250,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Location"
}
],
"description": [
{
"language_code": "en_us",
"string": "The location of the device."
}
]
},
{
"function": "dev_Archived",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Archived"
}
],
"description": [
{
"language_code": "en_us",
"string": "Indicates whether the device is archived. The default value of the <code>Archived</code> checkbox."
}
]
},
{
"function": "dev_Network_Node_MAC_ADDR",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Network Node MAC Address"
}
],
"description": [
{
"language_code": "en_us",
"string": "The MAC address of the network node."
}
]
},
{
"function": "dev_Network_Node_port",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": 0,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Network Node Port"
}
],
"description": [
{
"language_code": "en_us",
"string": "The port number of the network node. Uneditable."
}
]
},
{
"function": "dev_Icon",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Icon"
}
],
"description": [
{
"language_code": "en_us",
"string": "The icon associated with the device. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentation on icons</a> for more details."
}
]
}
],
"required": [
"dev_MAC",
"dev_Name",
"dev_Owner",
"dev_FirstConnection",
"dev_LastConnection",
"dev_LastIP",
"dev_StaticIP",
"dev_ScanCycle",
"dev_LogEvents",
"dev_AlertEvents",
"dev_AlertDeviceDown",
"dev_SkipRepeated",
"dev_LastNotification",
"dev_PresentLastScan",
"dev_NewDevice",
"dev_Location",
"dev_Archived",
"dev_Network_Node_MAC_ADDR",
"dev_Network_Node_port",
"dev_Icon"
],
"additionalProperties": false
}

View File

@@ -1 +0,0 @@
This plugin will not be loaded

View File

@@ -30,7 +30,7 @@
{ {
"name": "ips", "name": "ips",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC", "value": "SELECT devLastIP from DEVICES order by devMac",
"timeoutMultiplier": true "timeoutMultiplier": true
}, },
{ {

View File

@@ -38,7 +38,7 @@
{ {
"name": "ips", "name": "ips",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC", "value": "SELECT devLastIP from DEVICES order by devMac",
"timeoutMultiplier": true "timeoutMultiplier": true
} }
], ],

View File

@@ -60,19 +60,19 @@ def main():
# execute_name_lookup('192.168.1.121', timeout) # execute_name_lookup('192.168.1.121', timeout)
for device in unknown_devices: for device in unknown_devices:
domain_name, dns_server = execute_name_lookup(device['dev_LastIP'], timeout) domain_name, dns_server = execute_name_lookup(device['devLastIP'], timeout)
if domain_name != '': if domain_name != '':
plugin_objects.add_object( plugin_objects.add_object(
# "MAC", "IP", "Server", "Name" # "MAC", "IP", "Server", "Name"
primaryId = device['dev_MAC'], primaryId = device['devMac'],
secondaryId = device['dev_LastIP'], secondaryId = device['devLastIP'],
watched1 = dns_server, watched1 = dns_server,
watched2 = domain_name, watched2 = domain_name,
watched3 = '', watched3 = '',
watched4 = '', watched4 = '',
extra = '', extra = '',
foreignKey = device['dev_MAC']) foreignKey = device['devMac'])
plugin_objects.write_result_file() plugin_objects.write_result_file()

View File

@@ -266,7 +266,7 @@
] ]
}, },
{ {
"function": "dev_MAC", "function": "devMac",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -295,7 +295,7 @@
] ]
}, },
{ {
"function": "dev_Name", "function": "devName",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -324,7 +324,7 @@
] ]
}, },
{ {
"function": "dev_Owner", "function": "devOwner",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -338,7 +338,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT dev_Owner as id, dev_Owner as name FROM (SELECT dev_Owner FROM Devices UNION SELECT 'House' ) AS all_devices ORDER BY id;" "value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT devOwner as id, devOwner as name FROM (SELECT devOwner FROM Devices UNION SELECT 'House' ) AS all_devices ORDER BY id;"
} }
], ],
"localized": ["name", "description"], "localized": ["name", "description"],
@@ -356,7 +356,7 @@
] ]
}, },
{ {
"function": "dev_DeviceType", "function": "devType",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -370,7 +370,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "SELECT DISTINCT 9 as ord, dev_DeviceType as id, dev_DeviceType as name FROM Devices WHERE dev_DeviceType NOT IN ('', 'Smartphone', 'Tablet', 'Laptop', 'Mini PC', 'PC', 'Printer', 'Server', 'Singleboard Computer (SBC)', 'NAS', 'Domotic', 'IP Camera', 'Game Console', 'SmartTV', 'TV Decoder', 'Virtual Assistance', 'Clock', 'House Appliance', 'Phone', 'Radio', 'AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router', 'USB LAN Adapter', 'USB WIFI Adapter') UNION SELECT 0 as ord, '', '❌None' UNION SELECT 1 as ord, '-----', '-- 📱Handhelds --' UNION SELECT 1 as ord, 'Smartphone', 'Smartphone' UNION SELECT 1 as ord, 'Tablet', 'Tablet' UNION SELECT 2 as ord, '-----', '-- 💻Computers --' UNION SELECT 2 as ord, 'Laptop', 'Laptop' UNION SELECT 2 as ord, 'Mini PC', 'Mini PC' UNION SELECT 2 as ord, 'PC', 'PC' UNION SELECT 2 as ord, 'Printer', 'Printer' UNION SELECT 2 as ord, 'Server', 'Server' UNION SELECT 2 as ord, 'Singleboard Computer (SBC)', 'Singleboard Computer (SBC)' UNION SELECT 2 as ord, 'NAS', 'NAS' UNION SELECT 3 as ord, '-----', '-- 🏠Smart home --' UNION SELECT 3 as ord, 'Domotic', 'Domotic' UNION SELECT 3 as ord, 'IP Camera', 'IP Camera' UNION SELECT 3 as ord, 'Game Console', 'Game Console' UNION SELECT 3 as ord, 'SmartTV', 'SmartTV' UNION SELECT 3 as ord, 'TV Decoder', 'TV Decoder' UNION SELECT 3 as ord, 'Virtual Assistance', 'Virtual Assistance' UNION SELECT 4 as ord, '-----', '-- Wired --' UNION SELECT 4 as ord, 'Clock', 'Clock' UNION SELECT 4 as ord, 'House Appliance', 'House Appliance' UNION SELECT 4 as ord, 'Phone', 'Phone' UNION SELECT 4 as ord, 'Radio', 'Radio' UNION SELECT 5 as ord, '-----', '-- 📡Network nodes --' UNION SELECT 5 as ord, 'AP', 'AP' UNION SELECT 5 as ord, 'Gateway', 'Gateway' UNION SELECT 5 as ord, 'Firewall', 'Firewall' UNION SELECT 5 as ord, 'Hypervisor', 'Hypervisor' UNION SELECT 5 as ord, 'Powerline', 'Powerline' UNION SELECT 5 as ord, 'Switch', 'Switch' UNION SELECT 5 as ord, 'WLAN', 'WLAN' UNION SELECT 5 as ord, 'PLC', 'PLC' UNION SELECT 5 as ord, 'Router', 'Router' UNION SELECT 5 as ord, 'USB LAN Adapter', 'USB LAN Adapter' UNION SELECT 5 as ord, 'USB WIFI Adapter', 'USB WIFI Adapter' UNION SELECT 9 as ord, '-----', '-- ⚙Custom --' UNION SELECT 10 as ord, '-----', '-----' UNION SELECT 10 as ord, 'Other', 'Other' ORDER BY 1,2;" "value": "SELECT DISTINCT 9 as ord, devType as id, devType as name FROM Devices WHERE devType NOT IN ('', 'Smartphone', 'Tablet', 'Laptop', 'Mini PC', 'PC', 'Printer', 'Server', 'Singleboard Computer (SBC)', 'NAS', 'Domotic', 'IP Camera', 'Game Console', 'SmartTV', 'TV Decoder', 'Virtual Assistance', 'Clock', 'House Appliance', 'Phone', 'Radio', 'AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router', 'USB LAN Adapter', 'USB WIFI Adapter') UNION SELECT 0 as ord, '', '❌None' UNION SELECT 1 as ord, '-----', '-- 📱Handhelds --' UNION SELECT 1 as ord, 'Smartphone', 'Smartphone' UNION SELECT 1 as ord, 'Tablet', 'Tablet' UNION SELECT 2 as ord, '-----', '-- 💻Computers --' UNION SELECT 2 as ord, 'Laptop', 'Laptop' UNION SELECT 2 as ord, 'Mini PC', 'Mini PC' UNION SELECT 2 as ord, 'PC', 'PC' UNION SELECT 2 as ord, 'Printer', 'Printer' UNION SELECT 2 as ord, 'Server', 'Server' UNION SELECT 2 as ord, 'Singleboard Computer (SBC)', 'Singleboard Computer (SBC)' UNION SELECT 2 as ord, 'NAS', 'NAS' UNION SELECT 3 as ord, '-----', '-- 🏠Smart home --' UNION SELECT 3 as ord, 'Domotic', 'Domotic' UNION SELECT 3 as ord, 'IP Camera', 'IP Camera' UNION SELECT 3 as ord, 'Game Console', 'Game Console' UNION SELECT 3 as ord, 'SmartTV', 'SmartTV' UNION SELECT 3 as ord, 'TV Decoder', 'TV Decoder' UNION SELECT 3 as ord, 'Virtual Assistance', 'Virtual Assistance' UNION SELECT 4 as ord, '-----', '-- Wired --' UNION SELECT 4 as ord, 'Clock', 'Clock' UNION SELECT 4 as ord, 'House Appliance', 'House Appliance' UNION SELECT 4 as ord, 'Phone', 'Phone' UNION SELECT 4 as ord, 'Radio', 'Radio' UNION SELECT 5 as ord, '-----', '-- 📡Network nodes --' UNION SELECT 5 as ord, 'AP', 'AP' UNION SELECT 5 as ord, 'Gateway', 'Gateway' UNION SELECT 5 as ord, 'Firewall', 'Firewall' UNION SELECT 5 as ord, 'Hypervisor', 'Hypervisor' UNION SELECT 5 as ord, 'Powerline', 'Powerline' UNION SELECT 5 as ord, 'Switch', 'Switch' UNION SELECT 5 as ord, 'WLAN', 'WLAN' UNION SELECT 5 as ord, 'PLC', 'PLC' UNION SELECT 5 as ord, 'Router', 'Router' UNION SELECT 5 as ord, 'USB LAN Adapter', 'USB LAN Adapter' UNION SELECT 5 as ord, 'USB WIFI Adapter', 'USB WIFI Adapter' UNION SELECT 9 as ord, '-----', '-- ⚙Custom --' UNION SELECT 10 as ord, '-----', '-----' UNION SELECT 10 as ord, 'Other', 'Other' ORDER BY 1,2;"
}, },
{ {
"name": "uilang", "name": "uilang",
@@ -393,7 +393,7 @@
] ]
}, },
{ {
"function": "dev_Vendor", "function": "devVendor",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -422,7 +422,7 @@
] ]
}, },
{ {
"function": "dev_Favorite", "function": "devFavorite",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -450,7 +450,7 @@
] ]
}, },
{ {
"function": "dev_Group", "function": "devGroup",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -464,7 +464,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT dev_Group as id, dev_Group as name FROM (SELECT dev_Group FROM Devices WHERE dev_Group <> '' UNION SELECT 'Personal' UNION SELECT 'Always on' UNION SELECT 'Friends' UNION SELECT 'Others' ) AS all_devices ORDER BY id;" "value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT devGroup as id, devGroup as name FROM (SELECT devGroup FROM Devices WHERE devGroup <> '' UNION SELECT 'Personal' UNION SELECT 'Always on' UNION SELECT 'Friends' UNION SELECT 'Others' ) AS all_devices ORDER BY id;"
} }
], ],
"localized": ["name", "description"], "localized": ["name", "description"],
@@ -482,7 +482,7 @@
] ]
}, },
{ {
"function": "dev_Comments", "function": "devComments",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -506,7 +506,7 @@
] ]
}, },
{ {
"function": "dev_FirstConnection", "function": "devFirstConnection",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -535,7 +535,7 @@
] ]
}, },
{ {
"function": "dev_LastConnection", "function": "devLastConnection",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -564,7 +564,7 @@
] ]
}, },
{ {
"function": "dev_LastIP", "function": "devLastIP",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -593,7 +593,7 @@
] ]
}, },
{ {
"function": "dev_StaticIP", "function": "devStaticIP",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -621,7 +621,7 @@
] ]
}, },
{ {
"function": "dev_ScanCycle", "function": "devScan",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -649,7 +649,7 @@
] ]
}, },
{ {
"function": "dev_LogEvents", "function": "devLogEvents",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -677,7 +677,7 @@
] ]
}, },
{ {
"function": "dev_AlertEvents", "function": "devAlertEvents",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -705,7 +705,7 @@
] ]
}, },
{ {
"function": "dev_AlertDeviceDown", "function": "devAlertDown",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -733,7 +733,7 @@
] ]
}, },
{ {
"function": "dev_SkipRepeated", "function": "devSkipRepeated",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -764,7 +764,7 @@
] ]
}, },
{ {
"function": "dev_LastNotification", "function": "devLastNotification",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -793,7 +793,7 @@
] ]
}, },
{ {
"function": "dev_PresentLastScan", "function": "devPresentLastScan",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -821,7 +821,7 @@
] ]
}, },
{ {
"function": "dev_NewDevice", "function": "devIsNew",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -849,7 +849,7 @@
] ]
}, },
{ {
"function": "dev_Location", "function": "devLocation",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -863,7 +863,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "SELECT DISTINCT '' AS id, '❌None' AS name UNION SELECT dev_Location AS id, dev_Location AS name FROM Devices WHERE dev_Location NOT IN ('', 'null') AND dev_Location IS NOT NULL UNION SELECT 'Bathroom' AS id, 'Bathroom' AS name UNION SELECT 'Bedroom', 'Bedroom' UNION SELECT 'Dining room', 'Dining room' UNION SELECT 'Hall', 'Hall' UNION SELECT 'Kitchen', 'Kitchen' UNION SELECT 'Laundry', 'Laundry' UNION SELECT 'Living room', 'Living room' UNION SELECT 'Study', 'Study' UNION SELECT 'Attic', 'Attic' UNION SELECT 'Basement', 'Basement' UNION SELECT 'Garage', 'Garage' UNION SELECT 'Back yard', 'Back yard' UNION SELECT 'Garden', 'Garden' UNION SELECT 'Terrace', 'Terrace' ORDER BY id;" "value": "SELECT DISTINCT '' AS id, '❌None' AS name UNION SELECT devLocation AS id, devLocation AS name FROM Devices WHERE devLocation NOT IN ('', 'null') AND devLocation IS NOT NULL UNION SELECT 'Bathroom' AS id, 'Bathroom' AS name UNION SELECT 'Bedroom', 'Bedroom' UNION SELECT 'Dining room', 'Dining room' UNION SELECT 'Hall', 'Hall' UNION SELECT 'Kitchen', 'Kitchen' UNION SELECT 'Laundry', 'Laundry' UNION SELECT 'Living room', 'Living room' UNION SELECT 'Study', 'Study' UNION SELECT 'Attic', 'Attic' UNION SELECT 'Basement', 'Basement' UNION SELECT 'Garage', 'Garage' UNION SELECT 'Back yard', 'Back yard' UNION SELECT 'Garden', 'Garden' UNION SELECT 'Terrace', 'Terrace' ORDER BY id;"
} }
], ],
"localized": ["name", "description"], "localized": ["name", "description"],
@@ -881,7 +881,7 @@
] ]
}, },
{ {
"function": "dev_Archived", "function": "devIsArchived",
"type": { "type": {
"dataType": "integer", "dataType": "integer",
"elements": [ "elements": [
@@ -909,7 +909,7 @@
] ]
}, },
{ {
"function": "dev_Network_Node_MAC_ADDR", "function": "devParentMAC",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -922,7 +922,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "SELECT '❌None' as name, '' as id UNION SELECT Dev_Name as name, dev_MAC as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(dev_DeviceType) || '%' AND dev_DeviceType <> '')" "value": "SELECT '❌None' as name, '' as id UNION SELECT devName as name, devMac as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(devType) || '%' AND devType <> '')"
}, },
{ {
"name": "target_macs", "name": "target_macs",
@@ -945,7 +945,7 @@
] ]
}, },
{ {
"function": "dev_Network_Node_port", "function": "devParentPort",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -973,7 +973,7 @@
] ]
}, },
{ {
"function": "dev_Icon", "function": "devIcon",
"type": { "type": {
"dataType": "string", "dataType": "string",
"elements": [ "elements": [
@@ -982,7 +982,7 @@
"elementOptions": [ "elementOptions": [
{ "cssClasses": "input-group-addon iconPreview" }, { "cssClasses": "input-group-addon iconPreview" },
{ "getStringKey": "Gen_SelectToPreview" }, { "getStringKey": "Gen_SelectToPreview" },
{ "customId": "NEWDEV_dev_Icon_preview" } { "customId": "NEWDEV_devIcon_preview" }
], ],
"transformers": [] "transformers": []
}, },
@@ -994,7 +994,7 @@
{ {
"onChange": "updateIconPreview(this)" "onChange": "updateIconPreview(this)"
}, },
{ "customParams": "NEWDEV_dev_Icon,NEWDEV_dev_Icon_preview" } { "customParams": "NEWDEV_devIcon,NEWDEV_devIcon_preview" }
], ],
"transformers": [] "transformers": []
} }
@@ -1006,7 +1006,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT Dev_Icon AS name, Dev_Icon AS id FROM Devices WHERE Dev_Icon <> '') AS combined_results;" "value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT devIcon AS name, devIcon AS id FROM Devices WHERE devIcon <> '') AS combined_results;"
} }
], ],
"localized": ["name", "description"], "localized": ["name", "description"],
@@ -1025,27 +1025,6 @@
} }
], ],
"required": [ "required": [
"dev_MAC",
"dev_Name",
"dev_Owner",
"dev_FirstConnection",
"dev_LastConnection",
"dev_LastIP",
"dev_StaticIP",
"dev_ScanCycle",
"dev_LogEvents",
"dev_AlertEvents",
"dev_AlertDeviceDown",
"dev_SkipRepeated",
"dev_LastNotification",
"dev_PresentLastScan",
"dev_NewDevice",
"dev_Location",
"dev_Archived",
"dev_Network_Node_MAC_ADDR",
"dev_Network_Node_port",
"dev_Icon",
"LESS_NAME_CLEANUP"
], ],
"additionalProperties": false "additionalProperties": false
} }

View File

@@ -50,13 +50,13 @@
{ {
"name": "ips", "name": "ips",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC", "value": "SELECT devLastIP from DEVICES order by devMac",
"timeoutMultiplier": true "timeoutMultiplier": true
}, },
{ {
"name": "macs", "name": "macs",
"type": "sql", "type": "sql",
"value": "SELECT dev_MAC from DEVICES order by dev_MAC" "value": "SELECT devMac from DEVICES order by devMac"
}, },
{ {
"name": "timeout", "name": "timeout",

View File

@@ -125,7 +125,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "You can specify a SQL where condition to filter out New Devices from notifications. For example <code>AND dev_LastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>." "string": "You can specify a SQL where condition to filter out New Devices from notifications. For example <code>AND devLastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>."
} }
] ]
}, },
@@ -149,7 +149,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "You can specify a SQL where condition to filter out Events from notifications. For example <code>AND dev_LastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>." "string": "You can specify a SQL where condition to filter out Events from notifications. For example <code>AND devLastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>."
} }
] ]
} }

View File

@@ -38,7 +38,7 @@
{ {
"name": "ips", "name": "ips",
"type": "sql", "type": "sql",
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC", "value": "SELECT devLastIP from DEVICES order by devMac",
"timeoutMultiplier": true "timeoutMultiplier": true
} }
], ],

View File

@@ -59,19 +59,19 @@ def main():
mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}']) mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
for device in unknown_devices: for device in unknown_devices:
domain_name, dns_server = execute_nslookup(device['dev_LastIP'], timeout) domain_name, dns_server = execute_nslookup(device['devLastIP'], timeout)
if domain_name != '': if domain_name != '':
plugin_objects.add_object( plugin_objects.add_object(
# "MAC", "IP", "Server", "Name" # "MAC", "IP", "Server", "Name"
primaryId = device['dev_MAC'], primaryId = device['devMac'],
secondaryId = device['dev_LastIP'], secondaryId = device['devLastIP'],
watched1 = dns_server, watched1 = dns_server,
watched2 = domain_name, watched2 = domain_name,
watched3 = '', watched3 = '',
watched4 = '', watched4 = '',
extra = '', extra = '',
foreignKey = device['dev_MAC']) foreignKey = device['devMac'])
plugin_objects.write_result_file() plugin_objects.write_result_file()

View File

@@ -252,7 +252,7 @@ def main():
# log result # log result
plugin_objects.write_result_file() plugin_objects.write_result_file()
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST name from MAC: {device_handler.getValueWithMac('dev_Name','00:e2:59:00:a0:8e')}']) #mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST name from MAC: {device_handler.getValueWithMac('devName','00:e2:59:00:a0:8e')}'])
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST MAC from IP: {get_mac_from_IP('192.168.0.1')} also {ietf2ieee_mac_formater(get_mac_from_IP('192.168.0.1'))}']) #mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST MAC from IP: {get_mac_from_IP('192.168.0.1')} also {ietf2ieee_mac_formater(get_mac_from_IP('192.168.0.1'))}'])
end_time = time.time() end_time = time.time()
mylog('verbose', [f'[{pluginName}] execution completed in {end_time - start_time:.2f} seconds']) mylog('verbose', [f'[{pluginName}] execution completed in {end_time - start_time:.2f} seconds'])
@@ -423,7 +423,7 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
odevice_data_reordered = [ MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE] odevice_data_reordered = [ MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE]
odevice_data_reordered[MAC]=odevice_data[cMAC] odevice_data_reordered[MAC]=odevice_data[cMAC]
odevice_data_reordered[IP]=odevice_data[cIP] odevice_data_reordered[IP]=odevice_data[cIP]
real_naxname = device_handler.getValueWithMac('dev_Name',ieee2ietf_mac_formater(odevice_data[cMAC])) real_naxname = device_handler.getValueWithMac('devName',ieee2ietf_mac_formater(odevice_data[cMAC]))
# #
# if the name stored in Nax for a device is empty or the MAC addres or has some parenthhesis or is the same as in omada # if the name stored in Nax for a device is empty or the MAC addres or has some parenthhesis or is the same as in omada

View File

@@ -31,9 +31,10 @@ The plugin operates in three different modes based on the configuration settings
#### Node (Source) Settings `[n]` #### Node (Source) Settings `[n]`
- **API Token** `[n,h]`: `API_TOKEN` (has to be same across all nodes)
- **When to Run** `[n,h]`: `SYNC_RUN` - **When to Run** `[n,h]`: `SYNC_RUN`
- **Schedule** `[n,h]`: `SYNC_RUN_SCHD` - **Schedule** `[n,h]`: `SYNC_RUN_SCHD`
- **API Token** `[n,h]`: `SYNC_api_token`
- **Encryption Key** `[n,h]`: `SYNC_encryption_key` - **Encryption Key** `[n,h]`: `SYNC_encryption_key`
- **Node Name** `[n]`: `SYNC_node_name` - **Node Name** `[n]`: `SYNC_node_name`
- **Hub URL** `[n]`: `SYNC_hub_url` - **Hub URL** `[n]`: `SYNC_hub_url`
@@ -42,9 +43,10 @@ The plugin operates in three different modes based on the configuration settings
#### Hub (Target) Settings `[h]` #### Hub (Target) Settings `[h]`
- **API Token** `[n,h]`: `API_TOKEN` (has to be same across all nodes)
- **When to Run** `[n,h]`: `SYNC_RUN` - **When to Run** `[n,h]`: `SYNC_RUN`
- **Schedule** `[n,h]`: `SYNC_RUN_SCHD` - **Schedule** `[n,h]`: `SYNC_RUN_SCHD`
- **API Token** `[n,h]`: `SYNC_api_token`
- **Encryption Key** `[n,h]`: `SYNC_encryption_key` - **Encryption Key** `[n,h]`: `SYNC_encryption_key`
- **Nodes to Pull From** `[h]`: `SYNC_nodes` - **Nodes to Pull From** `[h]`: `SYNC_nodes`

View File

@@ -110,46 +110,6 @@
} }
] ]
}, },
{
"function": "api_token",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementHasInputValue": 1,
"elementOptions": [{ "cssClasses": "col-xs-12" }],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "getStringKey": "Gen_Generate" },
{ "customParams": "SYNC_api_token" },
{ "onClick": "generateApiToken(this, 20)" },
{ "cssClasses": "col-xs-12" }
],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "API token [n,h]"
}
],
"description": [
{
"language_code": "en_us",
"string": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. The API token needs to be the same on the hub and on the nodes."
}
]
},
{ {
"function": "encryption_key", "function": "encryption_key",
"type": { "type": {

View File

@@ -11,7 +11,7 @@ function checkAuthorization($method) {
// Retrieve the authorization header // Retrieve the authorization header
$headers = apache_request_headers(); $headers = apache_request_headers();
$auth_header = $headers['Authorization'] ?? ''; $auth_header = $headers['Authorization'] ?? '';
$expected_token = 'Bearer ' . getSettingValue('SYNC_api_token'); $expected_token = 'Bearer ' . getSettingValue('API_TOKEN');
// Verify the authorization token // Verify the authorization token
if ($auth_header !== $expected_token) { if ($auth_header !== $expected_token) {

View File

@@ -42,7 +42,7 @@ def main():
# Retrieve configuration settings # Retrieve configuration settings
plugins_to_sync = get_setting_value('SYNC_plugins') plugins_to_sync = get_setting_value('SYNC_plugins')
api_token = get_setting_value('SYNC_api_token') api_token = get_setting_value('API_TOKEN')
encryption_key = get_setting_value('SYNC_encryption_key') encryption_key = get_setting_value('SYNC_encryption_key')
hub_url = get_setting_value('SYNC_hub_url') hub_url = get_setting_value('SYNC_hub_url')
node_name = get_setting_value('SYNC_node_name') node_name = get_setting_value('SYNC_node_name')
@@ -165,7 +165,7 @@ def main():
conn = sqlite3.connect(fullDbPath) conn = sqlite3.connect(fullDbPath)
cursor = conn.cursor() cursor = conn.cursor()
# Collect all unique dev_MAC values from the JSON files # Collect all unique devMac values from the JSON files
unique_mac_addresses = set() unique_mac_addresses = set()
device_data = [] device_data = []
@@ -188,9 +188,9 @@ def main():
with open(file_path, 'r') as f: with open(file_path, 'r') as f:
data = json.load(f) data = json.load(f)
for device in data['data']: for device in data['data']:
if device['dev_MAC'] not in unique_mac_addresses: if device['devMac'] not in unique_mac_addresses:
device['dev_SyncHubNodeName'] = tmp_SyncHubNodeName device['devSyncHubNode'] = tmp_SyncHubNodeName
unique_mac_addresses.add(device['dev_MAC']) unique_mac_addresses.add(device['devMac'])
device_data.append(device) device_data.append(device)
# Rename the file to "processed_" + current name # Rename the file to "processed_" + current name
@@ -204,27 +204,27 @@ def main():
os.rename(file_path, new_file_path) os.rename(file_path, new_file_path)
if len(device_data) > 0: if len(device_data) > 0:
# Retrieve existing dev_MAC values from the Devices table # Retrieve existing devMac values from the Devices table
placeholders = ', '.join('?' for _ in unique_mac_addresses) placeholders = ', '.join('?' for _ in unique_mac_addresses)
cursor.execute(f'SELECT dev_MAC FROM Devices WHERE dev_MAC IN ({placeholders})', tuple(unique_mac_addresses)) cursor.execute(f'SELECT devMac FROM Devices WHERE devMac IN ({placeholders})', tuple(unique_mac_addresses))
existing_mac_addresses = set(row[0] for row in cursor.fetchall()) existing_mac_addresses = set(row[0] for row in cursor.fetchall())
# insert devices into the lats_result.log to manage state # insert devices into the lats_result.log to manage state
for device in device_data: for device in device_data:
if device['dev_PresentLastScan'] == 1: if device['devPresentLastScan'] == 1:
plugin_objects.add_object( plugin_objects.add_object(
primaryId = device['dev_MAC'], primaryId = device['devMac'],
secondaryId = device['dev_LastIP'], secondaryId = device['devLastIP'],
watched1 = device['dev_Name'], watched1 = device['devName'],
watched2 = device['dev_Vendor'], watched2 = device['devVendor'],
watched3 = device['dev_SyncHubNodeName'], watched3 = device['devSyncHubNode'],
watched4 = device['dev_GUID'], watched4 = device['devGUID'],
extra = '', extra = '',
foreignKey = device['dev_GUID']) foreignKey = device['devGUID'])
# Filter out existing devices # Filter out existing devices
new_devices = [device for device in device_data if device['dev_MAC'] not in existing_mac_addresses] new_devices = [device for device in device_data if device['devMac'] not in existing_mac_addresses]
# Remove 'rowid' key if it exists # Remove 'rowid' key if it exists
for device in new_devices: for device in new_devices:

View File

@@ -385,7 +385,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "Columns and their order that are shown on the Devices page. Drag and drop the order of columns, click <code>x</code> to remove columns. You can also click into the field to selectivelly add fields." "string": "Columns and their order that are shown on the Devices page. Drag and drop the order of columns, click <code>x</code> to remove columns. You can also click into the field to selectivelly add fields. The <code>Name</code> and <code>Status</code> fields are required."
} }
] ]
}, },

View File

@@ -85,14 +85,14 @@ def update_vendors (dbPath, plugin_objects):
# Get devices without a vendor # Get devices without a vendor
sql.execute ("""SELECT sql.execute ("""SELECT
dev_MAC, devMac,
dev_LastIP, devLastIP,
dev_Name, devName,
dev_Vendor devVendor
FROM Devices FROM Devices
WHERE dev_Vendor = '(unknown)' WHERE devVendor = '(unknown)'
OR dev_Vendor = '' OR devVendor = ''
OR dev_Vendor IS NULL OR devVendor IS NULL
""") """)
devices = sql.fetchall() devices = sql.fetchall()
conn.commit() conn.commit()

View File

@@ -40,17 +40,12 @@
{ {
"name": "macs", "name": "macs",
"type": "sql", "type": "sql",
"value": "SELECT dev_MAC from DEVICES" "value": "SELECT devMac from DEVICES"
}, },
{ {
"name": "urls", "name": "urls",
"type": "setting", "type": "setting",
"value": "WEBMON_urls_to_check" "value": "WEBMON_urls_to_check"
},
{
"name": "internet_ip",
"type": "setting",
"value": "WEBMON_SQL_internet_ip"
} }
], ],
"database_column_definitions": [ "database_column_definitions": [
@@ -677,42 +672,6 @@
"string": "Servicios para ver. Ingrese la URL completa, por ejemplo, <code>https://google.com</code>. Los valores de esta configuración se usarán para reemplazar el comodín <code>{urls}</code> en la configuración < code>WEBMON_CMD</code>." "string": "Servicios para ver. Ingrese la URL completa, por ejemplo, <code>https://google.com</code>. Los valores de esta configuración se usarán para reemplazar el comodín <code>{urls}</code> en la configuración < code>WEBMON_CMD</code>."
} }
] ]
},
{
"function": "SQL_internet_ip",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet'",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Helper variable"
},
{
"language_code": "es_es",
"string": "Variable de ayuda"
}
],
"description": [
{
"language_code": "en_us",
"string": "Unused setting - for demonstration only. Getting the IP address of the Router / Internet."
},
{
"language_code": "es_es",
"string": "Configuración no utilizada: solo para demostración. Obtener la dirección IP del enrutador / Internet."
}
]
} }
] ]
} }

View File

@@ -64,9 +64,9 @@
}, },
"down_reconnected": [ "down_reconnected": [
{ {
"dev_Name": "Phone - Pixel", "devName": "Phone - Pixel",
"eve_MAC": "74:ac:74:ac:74:ac", "eve_MAC": "74:ac:74:ac:74:ac",
"dev_Vendor": "Google", "devVendor": "Google",
"eve_IP": "192.168.1.167", "eve_IP": "192.168.1.167",
"DownTime": "2024-05-26 09:06:56+10:00", "DownTime": "2024-05-26 09:06:56+10:00",
"ConnectedTime": "2024-05-26 09:13:24+10:00" "ConnectedTime": "2024-05-26 09:13:24+10:00"
@@ -75,9 +75,9 @@
"down_reconnected_meta": { "down_reconnected_meta": {
"title": "🔁 Reconnected down devices", "title": "🔁 Reconnected down devices",
"columnNames": [ "columnNames": [
"dev_Name", "devName",
"eve_MAC", "eve_MAC",
"dev_Vendor", "devVendor",
"eve_IP", "eve_IP",
"DownTime", "DownTime",
"ConnectedTime" "ConnectedTime"

View File

@@ -30,5 +30,5 @@ source myenv/bin/activate
update-alternatives --install /usr/bin/python python /usr/bin/python3 10 update-alternatives --install /usr/bin/python python /usr/bin/python3 10
# install packages thru pip3 # install packages thru pip3
pip3 install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros pip3 install graphene flask netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros

View File

@@ -19,6 +19,7 @@ import sys
import time import time
import datetime import datetime
import multiprocessing import multiprocessing
import subprocess
# Register NetAlertX modules # Register NetAlertX modules
import conf import conf
@@ -34,7 +35,6 @@ from notification import Notification_obj
from plugin import run_plugin_scripts, check_and_run_user_event from plugin import run_plugin_scripts, check_and_run_user_event
from device import update_devices_names from device import update_devices_names
#=============================================================================== #===============================================================================
#=============================================================================== #===============================================================================
# MAIN # MAIN
@@ -78,6 +78,11 @@ def main ():
#=============================================================================== #===============================================================================
# This is the main loop of NetAlertX # This is the main loop of NetAlertX
#=============================================================================== #===============================================================================
mylog('debug', '[MAIN] Starting GraphQL server')
# Path to your `graphql_server.py` file
flask_app_path = applicationPath + '/server/graphql_server.py'
mylog('debug', '[MAIN] Starting loop') mylog('debug', '[MAIN] Starting loop')

View File

@@ -7,6 +7,9 @@ from const import (apiPath, sql_appevents, sql_devices_all, sql_events_pending_a
from logger import mylog from logger import mylog
from helper import write_file from helper import write_file
# Import the start_server function
from graphql_server.graphql_server_start import start_server
apiEndpoints = [] apiEndpoints = []
#=============================================================================== #===============================================================================
@@ -42,6 +45,9 @@ def update_api(db, all_plugins, isNotification = False, updateOnlyDataSources =
if updateOnlyDataSources == [] or dsSQL[0] in updateOnlyDataSources: if updateOnlyDataSources == [] or dsSQL[0] in updateOnlyDataSources:
api_endpoint_class(db, dsSQL[1], folder + 'table_' + dsSQL[0] + '.json') api_endpoint_class(db, dsSQL[1], folder + 'table_' + dsSQL[0] + '.json')
# Start the GraphQL server
start_server()
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------

View File

@@ -82,13 +82,13 @@ class AppEvent_obj:
{sql_generateGuid}, {sql_generateGuid},
DATETIME('now'), DATETIME('now'),
'Devices', 'Devices',
NEW.dev_MAC, NEW.devMac,
NEW.dev_LastIP, NEW.devLastIP,
CASE WHEN NEW.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END, CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
'dev_PresentLastScan', 'devPresentLastScan',
NEW.dev_NewDevice, NEW.devIsNew,
NEW.dev_Archived, NEW.devIsArchived,
NEW.dev_MAC, NEW.devMac,
'create' 'create'
); );
END; END;
@@ -112,13 +112,13 @@ class AppEvent_obj:
{sql_generateGuid}, {sql_generateGuid},
DATETIME('now'), DATETIME('now'),
'Devices', 'Devices',
NEW.dev_MAC, NEW.devMac,
NEW.dev_LastIP, NEW.devLastIP,
CASE WHEN NEW.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END, CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
'dev_PresentLastScan', 'devPresentLastScan',
NEW.dev_NewDevice, NEW.devIsNew,
NEW.dev_Archived, NEW.devIsArchived,
NEW.dev_MAC, NEW.devMac,
'update' 'update'
); );
END; END;
@@ -136,13 +136,13 @@ class AppEvent_obj:
{sql_generateGuid}, {sql_generateGuid},
DATETIME('now'), DATETIME('now'),
'Devices', 'Devices',
OLD.dev_MAC, OLD.devMac,
OLD.dev_LastIP, OLD.devLastIP,
CASE WHEN OLD.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END, CASE WHEN OLD.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
'dev_PresentLastScan', 'devPresentLastScan',
OLD.dev_NewDevice, OLD.devIsNew,
OLD.dev_Archived, OLD.devIsArchived,
OLD.dev_MAC, OLD.devMac,
'delete' 'delete'
); );
END; END;

View File

@@ -43,4 +43,4 @@ REPORT_DASHBOARD_URL = 'http://netalertx/'
# ------------------------------------------- # -------------------------------------------
# API # API
API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0' API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE devPresentLastScan = 0'

View File

@@ -30,8 +30,8 @@ vendorsPathNewest = '/usr/share/arp-scan/ieee-oui_all_filtered.txt'
sql_devices_all = """select rowid, * from Devices""" sql_devices_all = """select rowid, * from Devices"""
sql_appevents = """select * from AppEvents""" sql_appevents = """select * from AppEvents"""
sql_devices_stats = """SELECT Online_Devices as online, Down_Devices as down, All_Devices as 'all', Archived_Devices as archived, sql_devices_stats = """SELECT Online_Devices as online, Down_Devices as down, All_Devices as 'all', Archived_Devices as archived,
(select count(*) from Devices a where dev_NewDevice = 1 ) as new, (select count(*) from Devices a where devIsNew = 1 ) as new,
(select count(*) from Devices a where dev_Name = '(unknown)' or dev_Name = '(name not found)' ) as unknown (select count(*) from Devices a where devName = '(unknown)' or devName = '(name not found)' ) as unknown
from Online_History order by Scan_Date desc limit 1""" from Online_History order by Scan_Date desc limit 1"""
sql_events_pending_alert = "SELECT * FROM Events where eve_PendingAlertEmail is not 0" sql_events_pending_alert = "SELECT * FROM Events where eve_PendingAlertEmail is not 0"
sql_settings = "SELECT * FROM Settings" sql_settings = "SELECT * FROM Settings"
@@ -42,14 +42,14 @@ sql_online_history = "SELECT * FROM Online_History"
sql_plugins_events = "SELECT * FROM Plugins_Events" sql_plugins_events = "SELECT * FROM Plugins_Events"
sql_plugins_history = "SELECT * FROM Plugins_History ORDER BY DateTimeChanged DESC" sql_plugins_history = "SELECT * FROM Plugins_History ORDER BY DateTimeChanged DESC"
sql_new_devices = """SELECT * FROM ( sql_new_devices = """SELECT * FROM (
SELECT eve_IP as dev_LastIP, eve_MAC as dev_MAC SELECT eve_IP as devLastIP, eve_MAC as devMac
FROM Events_Devices FROM Events_Devices
WHERE eve_PendingAlertEmail = 1 WHERE eve_PendingAlertEmail = 1
AND eve_EventType = 'New Device' AND eve_EventType = 'New Device'
ORDER BY eve_DateTime ) t1 ORDER BY eve_DateTime ) t1
LEFT JOIN LEFT JOIN
( SELECT dev_Name, dev_MAC as dev_MAC_t2 FROM Devices) t2 ( SELECT devName, devMac as devMac_t2 FROM Devices) t2
ON t1.dev_MAC = t2.dev_MAC_t2""" ON t1.devMac = t2.devMac_t2"""
sql_generateGuid = ''' sql_generateGuid = '''

View File

@@ -81,149 +81,306 @@ class DB():
""" """
Check the current tables in the DB and upgrade them if neccessary Check the current tables in the DB and upgrade them if neccessary
""" """
# indicates, if Online_History table is available self.sql.execute("""
onlineHistoryAvailable = self.sql.execute(""" CREATE TABLE IF NOT EXISTS "Online_History" (
SELECT name FROM sqlite_master WHERE type='table'
AND name='Online_History';
""").fetchall() != []
# Check if it is incompatible (Check if table has all required columns)
isIncompatible = False
if onlineHistoryAvailable :
isIncompatible = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Archived_Devices'
""").fetchone()[0] == 0
# Drop table if available, but incompatible
if onlineHistoryAvailable and isIncompatible:
mylog('none','[upgradeDB] Table is incompatible, Dropping the Online_History table')
self.sql.execute("DROP TABLE Online_History;")
onlineHistoryAvailable = False
if onlineHistoryAvailable == False :
self.sql.execute("""
CREATE TABLE "Online_History" (
"Index" INTEGER, "Index" INTEGER,
"Scan_Date" TEXT, "Scan_Date" TEXT,
"Online_Devices" INTEGER, "Online_Devices" INTEGER,
"Down_Devices" INTEGER, "Down_Devices" INTEGER,
"All_Devices" INTEGER, "All_Devices" INTEGER,
"Archived_Devices" INTEGER, "Archived_Devices" INTEGER,
"Offline_Devices" INTEGER,
PRIMARY KEY("Index" AUTOINCREMENT) PRIMARY KEY("Index" AUTOINCREMENT)
); );
""") """)
# Offline_Devices column # -------------------------------------------------------------------
Offline_Devices_missing = self.sql.execute (""" # DevicesNew - cleanup after 6/6/2025
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Offline_Devices'
# check if migration already done based on devMac
devMac_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devMac'
""").fetchone()[0] == 0 """).fetchone()[0] == 0
if devMac_missing:
# SQL to create Devices table with indexes
sql_create_devices_new_tmp = """
CREATE TABLE IF NOT EXISTS Devices_tmp (
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
devName STRING (50) NOT NULL DEFAULT "(unknown)",
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
devType STRING (30),
devVendor STRING (250),
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
devGroup STRING (10),
devComments TEXT,
devFirstConnection DATETIME NOT NULL,
devLastConnection DATETIME NOT NULL,
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
devScan INTEGER DEFAULT (1) NOT NULL,
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
devLastNotification DATETIME,
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
devLocation STRING (250) COLLATE NOCASE,
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
devParentMAC TEXT,
devParentPort INTEGER,
devIcon TEXT,
devGUID TEXT,
devSite TEXT,
devSSID TEXT,
devSyncHubNode TEXT,
devSourcePlugin TEXT
);
if Offline_Devices_missing : CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices_tmp (devPresentLastScan);
mylog('verbose', ["[upgradeDB] Adding Offline_Devices to the Online_History table"]) CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices_tmp (devFirstConnection);
self.sql.execute(""" CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices_tmp (devAlertDown);
ALTER TABLE "Online_History" ADD "Offline_Devices" INTEGER CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices_tmp (devStaticIP);
""") CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices_tmp (devScan);
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices_tmp (devFavorite);
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices_tmp (devLastIP);
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices_tmp (devIsNew);
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices_tmp (devIsArchived);
"""
# Execute the creation of the Devices table and indexes
# ------------------------------------------------------------------------- self.sql.executescript(sql_create_devices_new_tmp)
# Alter Devices table
# -------------------------------------------------------------------------
# dev_Network_Node_MAC_ADDR column
dev_Network_Node_MAC_ADDR_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_MAC_ADDR'
""").fetchone()[0] == 0
if dev_Network_Node_MAC_ADDR_missing :
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_MAC_ADDR to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_Network_Node_MAC_ADDR" TEXT
""")
# dev_Network_Node_port column
dev_Network_Node_port_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_port'
""").fetchone()[0] == 0
if dev_Network_Node_port_missing :
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_port to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER
""")
# dev_Icon column
dev_Icon_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon'
""").fetchone()[0] == 0
if dev_Icon_missing :
mylog('verbose', ["[upgradeDB] Adding dev_Icon to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_Icon" TEXT
""")
# dev_GUID column
dev_GUID_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_GUID'
""").fetchone()[0] == 0
if dev_GUID_missing :
mylog('verbose', ["[upgradeDB] Adding dev_GUID to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_GUID" TEXT
""")
# dev_NetworkSite column
dev_NetworkSite_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_NetworkSite'
""").fetchone()[0] == 0
if dev_NetworkSite_missing :
mylog('verbose', ["[upgradeDB] Adding dev_NetworkSite to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_NetworkSite" TEXT
""")
# dev_SSID column
dev_SSID_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SSID'
""").fetchone()[0] == 0
if dev_SSID_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SSID to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SSID" TEXT
""")
# SQL query to update missing dev_GUID
self.sql.execute(f'''
UPDATE Devices
SET dev_GUID = {sql_generateGuid}
WHERE dev_GUID IS NULL
''')
# dev_SyncHubNodeName column
dev_SyncHubNodeName_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SyncHubNodeName'
""").fetchone()[0] == 0
if dev_SyncHubNodeName_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SyncHubNodeName to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
""")
# dev_SourcePlugin column
dev_SourcePlugin_missing = self.sql.execute (""" # copy over data
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin' sql_copy_from_devices = """
""").fetchone()[0] == 0 INSERT OR IGNORE INTO Devices_tmp (
devMac,
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
)
SELECT
dev_MAC AS devMac,
dev_Name AS devName,
dev_Owner AS devOwner,
dev_DeviceType AS devType,
dev_Vendor AS devVendor,
dev_Favorite AS devFavorite,
dev_Group AS devGroup,
dev_Comments AS devComments,
dev_FirstConnection AS devFirstConnection,
dev_LastConnection AS devLastConnection,
dev_LastIP AS devLastIP,
dev_StaticIP AS devStaticIP,
dev_ScanCycle AS devScan,
dev_LogEvents AS devLogEvents,
dev_AlertEvents AS devAlertEvents,
dev_AlertDeviceDown AS devAlertDown,
dev_SkipRepeated AS devSkipRepeated,
dev_LastNotification AS devLastNotification,
dev_PresentLastScan AS devPresentLastScan,
dev_NewDevice AS devIsNew,
dev_Location AS devLocation,
dev_Archived AS devIsArchived,
dev_Network_Node_MAC_ADDR AS devParentMAC,
dev_Network_Node_port AS devParentPort,
dev_Icon AS devIcon,
dev_GUID AS devGUID,
dev_NetworkSite AS devSite,
dev_SSID AS devSSID,
dev_SyncHubNodeName AS devSyncHubNode,
dev_SourcePlugin AS devSourcePlugin
FROM Devices;
"""
self.sql.execute(sql_copy_from_devices)
self.sql.execute(""" DROP TABLE Devices;""")
# SQL to create Devices table with indexes
sql_create_devices_new = """
CREATE TABLE IF NOT EXISTS Devices (
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
devName STRING (50) NOT NULL DEFAULT "(unknown)",
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
devType STRING (30),
devVendor STRING (250),
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
devGroup STRING (10),
devComments TEXT,
devFirstConnection DATETIME NOT NULL,
devLastConnection DATETIME NOT NULL,
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
devScan INTEGER DEFAULT (1) NOT NULL,
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
devLastNotification DATETIME,
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
devLocation STRING (250) COLLATE NOCASE,
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
devParentMAC TEXT,
devParentPort INTEGER,
devIcon TEXT,
devGUID TEXT,
devSite TEXT,
devSSID TEXT,
devSyncHubNode TEXT,
devSourcePlugin TEXT
);
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices (devPresentLastScan);
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices (devFirstConnection);
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices (devAlertDown);
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices (devStaticIP);
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices (devScan);
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices (devFavorite);
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices (devLastIP);
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices (devIsNew);
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices (devIsArchived);
"""
# Execute the creation of the Devices table and indexes
self.sql.executescript(sql_create_devices_new)
# copy over data
sql_copy_from_devices_tmp = """
INSERT OR IGNORE INTO Devices (
devMac,
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
)
SELECT
devMac,
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
FROM Devices_tmp;
"""
self.sql.execute(sql_copy_from_devices_tmp)
self.sql.execute(""" DROP TABLE Devices_tmp;""")
# VIEWS
self.sql.execute(""" DROP VIEW IF EXISTS Events_Devices;""")
self.sql.execute(""" CREATE VIEW Events_Devices AS
SELECT *
FROM Events
LEFT JOIN Devices ON eve_MAC = devMac;
""")
self.sql.execute(""" DROP VIEW IF EXISTS LatestEventsPerMAC;""")
self.sql.execute("""CREATE VIEW LatestEventsPerMAC AS
WITH RankedEvents AS (
SELECT
e.*,
ROW_NUMBER() OVER (PARTITION BY e.eve_MAC ORDER BY e.eve_DateTime DESC) AS row_num
FROM Events AS e
)
SELECT
e.*,
d.*,
c.*
FROM RankedEvents AS e
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
WHERE e.row_num = 1;""")
self.sql.execute(""" DROP VIEW IF EXISTS Sessions_Devices;""")
self.sql.execute("""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;""")
if dev_SourcePlugin_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
""")
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Settings table setup # Settings table setup
@@ -284,96 +441,7 @@ class DB():
"par_Value" TEXT "par_Value" TEXT
); );
""") """)
# -------------------------------------------------------------------------
# Nmap_Scan table setup DEPRECATED after 9/9/2024
# -------------------------------------------------------------------------
# indicates, if Nmap_Scan table is available
nmapScanMissing = self.sql.execute("""
SELECT name FROM sqlite_master WHERE type='table'
AND name='Nmap_Scan';
""").fetchone() == None
if nmapScanMissing == False:
# move data into the PLugins_Objects table
self.sql.execute("""INSERT INTO Plugins_Objects (
Plugin,
Object_PrimaryID,
Object_SecondaryID,
DateTimeCreated,
DateTimeChanged,
Watched_Value1,
Watched_Value2,
Watched_Value3,
Watched_Value4,
Status,
Extra,
UserData,
ForeignKey
)
SELECT
'NMAP' AS Plugin,
MAC AS Object_PrimaryID,
Port AS Object_SecondaryID,
Time AS DateTimeCreated,
DATETIME('now') AS DateTimeChanged,
State AS Watched_Value1,
Service AS Watched_Value2,
'' AS Watched_Value3,
'' AS Watched_Value4,
'watched-not-changed' AS Status,
Extra AS Extra,
Extra AS UserData,
MAC AS ForeignKey
FROM Nmap_Scan;""")
# Delete the Nmap_Scan table
self.sql.execute("DROP TABLE Nmap_Scan;")
nmapScanMissing = True
# -------------------------------------------------------------------------
# Nmap_Scan table setup DEPRECATED after 9/9/2024 cleanup above
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# Icon format migration table setup DEPRECATED after 9/9/2024 cleanup below
# -------------------------------------------------------------------------
sql_Icons = """ UPDATE Devices SET dev_Icon = '<i class="fa fa-' || dev_Icon || '"></i>'
WHERE dev_Icon NOT LIKE '<i class="fa fa-%'
AND dev_Icon NOT LIKE '<svg%'
AND dev_Icon NOT LIKE 'PGkg%'
AND dev_Icon NOT LIKE 'PHN%'
AND dev_Icon NOT IN ('', 'null')
"""
self.sql.execute(sql_Icons)
self.commitDB()
# Base64 conversion
self.sql.execute("SELECT dev_MAC, dev_Icon FROM Devices WHERE dev_Icon like '<%' ")
icons = self.sql.fetchall()
# Loop through the icons, encode them, and update the database
for icon_tuple in icons:
icon = icon_tuple[1]
# Encode the icon as base64
encoded_icon = base64.b64encode(icon.encode('utf-8')).decode('ascii')
# Update the database with the encoded icon
sql_update = f"""
UPDATE Devices
SET dev_Icon = '{encoded_icon}'
WHERE dev_MAC = '{icon_tuple[0]}'
"""
self.sql.execute(sql_update)
# -------------------------------------------------------------------------
# Icon format migration table setup DEPRECATED after 9/9/2024 cleanup above
# -------------------------------------------------------------------------
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Plugins tables setup # Plugins tables setup
@@ -395,10 +463,18 @@ class DB():
Extra TEXT NOT NULL, Extra TEXT NOT NULL,
UserData TEXT NOT NULL, UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL, ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT) PRIMARY KEY("Index" AUTOINCREMENT)
); """ ); """
self.sql.execute(sql_Plugins_Objects) self.sql.execute(sql_Plugins_Objects)
# -----------------------------------------
# REMOVE after 6/6/2025 - START
# -----------------------------------------
# syncHubNodeName column # syncHubNodeName column
plug_SyncHubNodeName_missing = self.sql.execute (""" plug_SyncHubNodeName_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='SyncHubNodeName' SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='SyncHubNodeName'
@@ -421,6 +497,10 @@ class DB():
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal2" TEXT') self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal2" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal3" TEXT') self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal3" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal4" TEXT') self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal4" TEXT')
# -----------------------------------------
# REMOVE after 6/6/2025 - END
# -----------------------------------------
# Plugin execution results # Plugin execution results
sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events( sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events(
@@ -438,10 +518,19 @@ class DB():
Extra TEXT NOT NULL, Extra TEXT NOT NULL,
UserData TEXT NOT NULL, UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL, ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT) PRIMARY KEY("Index" AUTOINCREMENT)
); """ ); """
self.sql.execute(sql_Plugins_Events) self.sql.execute(sql_Plugins_Events)
# -----------------------------------------
# REMOVE after 6/6/2025 - START
# -----------------------------------------
# syncHubNodeName column # syncHubNodeName column
plug_SyncHubNodeName_missing = self.sql.execute (""" plug_SyncHubNodeName_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='SyncHubNodeName' SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='SyncHubNodeName'
@@ -464,6 +553,10 @@ class DB():
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal2" TEXT') self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal2" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal3" TEXT') self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal3" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal4" TEXT') self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal4" TEXT')
# -----------------------------------------
# REMOVE after 6/6/2025 - END
# -----------------------------------------
# Plugin execution history # Plugin execution history
@@ -482,9 +575,18 @@ class DB():
Extra TEXT NOT NULL, Extra TEXT NOT NULL,
UserData TEXT NOT NULL, UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL, ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT) PRIMARY KEY("Index" AUTOINCREMENT)
); """ ); """
self.sql.execute(sql_Plugins_History) self.sql.execute(sql_Plugins_History)
# -----------------------------------------
# REMOVE after 6/6/2025 - START
# -----------------------------------------
# syncHubNodeName column # syncHubNodeName column
plug_SyncHubNodeName_missing = self.sql.execute (""" plug_SyncHubNodeName_missing = self.sql.execute ("""
@@ -509,6 +611,9 @@ class DB():
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal3" TEXT') self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal3" TEXT')
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal4" TEXT') self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal4" TEXT')
# -----------------------------------------
# REMOVE after 6/6/2025 - END
# -----------------------------------------
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Plugins_Language_Strings table setup # Plugins_Language_Strings table setup
@@ -573,7 +678,7 @@ class DB():
d.*, d.*,
c.* c.*
FROM RankedEvents AS e FROM RankedEvents AS e
LEFT JOIN Devices AS d ON e.eve_MAC = d.dev_MAC LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
WHERE e.row_num = 1; WHERE e.row_num = 1;
""") """)

View File

@@ -25,16 +25,16 @@ class Device_obj:
# Get all with unknown names # Get all with unknown names
def getUnknown(self): def getUnknown(self):
self.db.sql.execute(""" self.db.sql.execute("""
SELECT * FROM Devices WHERE dev_Name in ("(unknown)", "(name not found)", "" ) SELECT * FROM Devices WHERE devName in ("(unknown)", "(name not found)", "" )
""") """)
return self.db.sql.fetchall() return self.db.sql.fetchall()
# Get specific column value based on dev_MAC # Get specific column value based on devMac
def getValueWithMac(self, column_name, dev_MAC): def getValueWithMac(self, column_name, devMac):
query = f"SELECT {column_name} FROM Devices WHERE dev_MAC = ?" query = f"SELECT {column_name} FROM Devices WHERE devMac = ?"
self.db.sql.execute(query, (dev_MAC,)) self.db.sql.execute(query, (devMac,))
result = self.db.sql.fetchone() result = self.db.sql.fetchone()
@@ -102,12 +102,12 @@ def print_scan_stats(db):
query = """ query = """
SELECT SELECT
(SELECT COUNT(*) FROM CurrentScan) AS devices_detected, (SELECT COUNT(*) FROM CurrentScan) AS devices_detected,
(SELECT COUNT(*) FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE dev_MAC = cur_MAC)) AS new_devices, (SELECT COUNT(*) FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE devMac = cur_MAC)) AS new_devices,
(SELECT COUNT(*) FROM Devices WHERE dev_AlertDeviceDown != 0 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS down_alerts, (SELECT COUNT(*) FROM Devices WHERE devAlertDown != 0 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS down_alerts,
(SELECT COUNT(*) FROM Devices WHERE dev_AlertDeviceDown != 0 AND dev_PresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS new_down_alerts, (SELECT COUNT(*) FROM Devices WHERE devAlertDown != 0 AND devPresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS new_down_alerts,
(SELECT COUNT(*) FROM Devices WHERE dev_PresentLastScan = 0) AS new_connections, (SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0) AS new_connections,
(SELECT COUNT(*) FROM Devices WHERE dev_PresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS disconnections, (SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS disconnections,
(SELECT COUNT(*) FROM Devices, CurrentScan WHERE dev_MAC = cur_MAC AND dev_LastIP <> cur_IP) AS ip_changes, (SELECT COUNT(*) FROM Devices, CurrentScan WHERE devMac = cur_MAC AND devLastIP <> cur_IP) AS ip_changes,
cur_ScanMethod, cur_ScanMethod,
COUNT(*) AS scan_method_count COUNT(*) AS scan_method_count
FROM CurrentScan FROM CurrentScan
@@ -175,7 +175,7 @@ def create_new_devices (db):
SELECT cur_MAC, cur_IP, '{startTime}', 'New Device', cur_Vendor, 1 SELECT cur_MAC, cur_IP, '{startTime}', 'New Device', cur_Vendor, 1
FROM CurrentScan FROM CurrentScan
WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE NOT EXISTS (SELECT 1 FROM Devices
WHERE dev_MAC = cur_MAC) WHERE devMac = cur_MAC)
""" """
@@ -197,33 +197,33 @@ def create_new_devices (db):
mylog('debug','[New Devices] 2 Create devices') mylog('debug','[New Devices] 2 Create devices')
# default New Device values preparation # default New Device values preparation
newDevColumns = """dev_AlertEvents, newDevColumns = """devAlertEvents,
dev_AlertDeviceDown, devAlertDown,
dev_PresentLastScan, devPresentLastScan,
dev_Archived, devIsArchived,
dev_NewDevice, devIsNew,
dev_SkipRepeated, devSkipRepeated,
dev_ScanCycle, devScan,
dev_Owner, devOwner,
dev_Favorite, devFavorite,
dev_Group, devGroup,
dev_Comments, devComments,
dev_LogEvents, devLogEvents,
dev_Location""" devLocation"""
newDevDefaults = f"""{get_setting_value('NEWDEV_dev_AlertEvents')}, newDevDefaults = f"""{get_setting_value('NEWDEV_devAlertEvents')},
{get_setting_value('NEWDEV_dev_AlertDeviceDown')}, {get_setting_value('NEWDEV_devAlertDown')},
{get_setting_value('NEWDEV_dev_PresentLastScan')}, {get_setting_value('NEWDEV_devPresentLastScan')},
{get_setting_value('NEWDEV_dev_Archived')}, {get_setting_value('NEWDEV_devIsArchived')},
{get_setting_value('NEWDEV_dev_NewDevice')}, {get_setting_value('NEWDEV_devIsNew')},
{get_setting_value('NEWDEV_dev_SkipRepeated')}, {get_setting_value('NEWDEV_devSkipRepeated')},
{get_setting_value('NEWDEV_dev_ScanCycle')}, {get_setting_value('NEWDEV_devScan')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Owner'))}', '{sanitize_SQL_input(get_setting_value('NEWDEV_devOwner'))}',
{get_setting_value('NEWDEV_dev_Favorite')}, {get_setting_value('NEWDEV_devFavorite')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Group'))}', '{sanitize_SQL_input(get_setting_value('NEWDEV_devGroup'))}',
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Comments'))}', '{sanitize_SQL_input(get_setting_value('NEWDEV_devComments'))}',
{get_setting_value('NEWDEV_dev_LogEvents')}, {get_setting_value('NEWDEV_devLogEvents')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Location'))}'""" '{sanitize_SQL_input(get_setting_value('NEWDEV_devLocation'))}'"""
# Fetch data from CurrentScan skipping ignored devices by IP and MAC # Fetch data from CurrentScan skipping ignored devices by IP and MAC
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
@@ -238,28 +238,28 @@ def create_new_devices (db):
# Handle NoneType # Handle NoneType
cur_Name = cur_Name.strip() if cur_Name else '(unknown)' cur_Name = cur_Name.strip() if cur_Name else '(unknown)'
cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_dev_DeviceType") cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_devType")
cur_NetworkNodeMAC = cur_NetworkNodeMAC.strip() if cur_NetworkNodeMAC else '' cur_NetworkNodeMAC = cur_NetworkNodeMAC.strip() if cur_NetworkNodeMAC else ''
cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_dev_Network_Node_MAC_ADDR") if cur_MAC != "Internet" else "null") cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_devParentMAC") if cur_MAC != "Internet" else "null")
cur_SyncHubNodeName = cur_SyncHubNodeName if cur_SyncHubNodeName and cur_SyncHubNodeName != "null" else (get_setting_value("SYNC_node_name")) cur_SyncHubNodeName = cur_SyncHubNodeName if cur_SyncHubNodeName and cur_SyncHubNodeName != "null" else (get_setting_value("SYNC_node_name"))
# Preparing the individual insert statement # Preparing the individual insert statement
sqlQuery = f"""INSERT OR IGNORE INTO Devices sqlQuery = f"""INSERT OR IGNORE INTO Devices
( (
dev_MAC, devMac,
dev_name, devName,
dev_Vendor, devVendor,
dev_LastIP, devLastIP,
dev_FirstConnection, devFirstConnection,
dev_LastConnection, devLastConnection,
dev_SyncHubNodeName, devSyncHubNode,
dev_GUID, devGUID,
dev_Network_Node_MAC_ADDR, devParentMAC,
dev_Network_Node_port, devParentPort,
dev_NetworkSite, devSite,
dev_SSID, devSSID,
dev_DeviceType, devType,
dev_SourcePlugin, devSourcePlugin,
{newDevColumns} {newDevColumns}
) )
VALUES VALUES
@@ -297,140 +297,140 @@ def update_devices_data_from_scan (db):
# Update Last Connection # Update Last Connection
mylog('debug', '[Update Devices] 1 Last Connection') mylog('debug', '[Update Devices] 1 Last Connection')
sql.execute(f"""UPDATE Devices SET dev_LastConnection = '{startTime}', sql.execute(f"""UPDATE Devices SET devLastConnection = '{startTime}',
dev_PresentLastScan = 1 devPresentLastScan = 1
WHERE dev_PresentLastScan = 0 WHERE devPresentLastScan = 0
AND EXISTS (SELECT 1 FROM CurrentScan AND EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC) """) WHERE devMac = cur_MAC) """)
# Clean no active devices # Clean no active devices
mylog('debug', '[Update Devices] 2 Clean no active devices') mylog('debug', '[Update Devices] 2 Clean no active devices')
sql.execute("""UPDATE Devices SET dev_PresentLastScan = 0 sql.execute("""UPDATE Devices SET devPresentLastScan = 0
WHERE NOT EXISTS (SELECT 1 FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC) """) WHERE devMac = cur_MAC) """)
# Update IP # Update IP
mylog('debug', '[Update Devices] - cur_IP -> dev_LastIP (always updated)') mylog('debug', '[Update Devices] - cur_IP -> devLastIP (always updated)')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_LastIP = (SELECT cur_IP FROM CurrentScan SET devLastIP = (SELECT cur_IP FROM CurrentScan
WHERE dev_MAC = cur_MAC) WHERE devMac = cur_MAC)
WHERE EXISTS (SELECT 1 FROM CurrentScan WHERE EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC) """) WHERE devMac = cur_MAC) """)
# Update only devices with empty or NULL vendors # Update only devices with empty or NULL vendors
mylog('debug', '[Update Devices] - cur_Vendor -> (if empty) dev_Vendor') mylog('debug', '[Update Devices] - cur_Vendor -> (if empty) devVendor')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_Vendor = ( SET devVendor = (
SELECT cur_Vendor SELECT cur_Vendor
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
) )
WHERE WHERE
(dev_Vendor IS NULL OR dev_Vendor IN ("", "null")) (devVendor IS NULL OR devVendor IN ("", "null"))
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
)""") )""")
# Update only devices with empty or NULL dev_Network_Node_port # Update only devices with empty or NULL devParentPort
mylog('debug', '[Update Devices] - (if not empty) cur_Port -> dev_Network_Node_port') mylog('debug', '[Update Devices] - (if not empty) cur_Port -> devParentPort')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_Network_Node_port = ( SET devParentPort = (
SELECT cur_Port SELECT cur_Port
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
) )
WHERE EXISTS ( WHERE EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_Port IS NOT NULL AND CurrentScan.cur_Port NOT IN ("", "null") AND CurrentScan.cur_Port IS NOT NULL AND CurrentScan.cur_Port NOT IN ("", "null")
)""") )""")
# Update only devices with empty or NULL dev_Network_Node_MAC_ADDR # Update only devices with empty or NULL devParentMAC
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkNodeMAC -> dev_Network_Node_MAC_ADDR') mylog('debug', '[Update Devices] - (if not empty) cur_NetworkNodeMAC -> devParentMAC')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_Network_Node_MAC_ADDR = ( SET devParentMAC = (
SELECT cur_NetworkNodeMAC SELECT cur_NetworkNodeMAC
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
) )
WHERE EXISTS ( WHERE EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_NetworkNodeMAC IS NOT NULL AND CurrentScan.cur_NetworkNodeMAC NOT IN ("", "null") AND CurrentScan.cur_NetworkNodeMAC IS NOT NULL AND CurrentScan.cur_NetworkNodeMAC NOT IN ("", "null")
)""") )""")
# Update only devices with empty or NULL dev_NetworkSite # Update only devices with empty or NULL devSite
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkSite -> (if empty) dev_NetworkSite') mylog('debug', '[Update Devices] - (if not empty) cur_NetworkSite -> (if empty) devSite')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_NetworkSite = ( SET devSite = (
SELECT cur_NetworkSite SELECT cur_NetworkSite
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
) )
WHERE WHERE
(dev_NetworkSite IS NULL OR dev_NetworkSite IN ("", "null")) (devSite IS NULL OR devSite IN ("", "null"))
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_NetworkSite IS NOT NULL AND CurrentScan.cur_NetworkSite NOT IN ("", "null") AND CurrentScan.cur_NetworkSite IS NOT NULL AND CurrentScan.cur_NetworkSite NOT IN ("", "null")
)""") )""")
# Update only devices with empty or NULL dev_SSID # Update only devices with empty or NULL devSSID
mylog('debug', '[Update Devices] - (if not empty) cur_SSID -> (if empty) dev_SSID') mylog('debug', '[Update Devices] - (if not empty) cur_SSID -> (if empty) devSSID')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_SSID = ( SET devSSID = (
SELECT cur_SSID SELECT cur_SSID
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
) )
WHERE WHERE
(dev_SSID IS NULL OR dev_SSID IN ("", "null")) (devSSID IS NULL OR devSSID IN ("", "null"))
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_SSID IS NOT NULL AND CurrentScan.cur_SSID NOT IN ("", "null") AND CurrentScan.cur_SSID IS NOT NULL AND CurrentScan.cur_SSID NOT IN ("", "null")
)""") )""")
# Update only devices with empty or NULL dev_DeviceType # Update only devices with empty or NULL devType
mylog('debug', '[Update Devices] - (if not empty) cur_Type -> (if empty) dev_DeviceType') mylog('debug', '[Update Devices] - (if not empty) cur_Type -> (if empty) devType')
sql.execute("""UPDATE Devices sql.execute("""UPDATE Devices
SET dev_DeviceType = ( SET devType = (
SELECT cur_Type SELECT cur_Type
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
) )
WHERE WHERE
(dev_DeviceType IS NULL OR dev_DeviceType IN ("", "null")) (devType IS NULL OR devType IN ("", "null"))
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_Type IS NOT NULL AND CurrentScan.cur_Type NOT IN ("", "null") AND CurrentScan.cur_Type IS NOT NULL AND CurrentScan.cur_Type NOT IN ("", "null")
)""") )""")
# Update (unknown) or (name not found) Names if available # Update (unknown) or (name not found) Names if available
mylog('debug','[Update Devices] - (if not empty) cur_Name -> (if empty) dev_NAME') mylog('debug','[Update Devices] - (if not empty) cur_Name -> (if empty) devName')
sql.execute (""" UPDATE Devices sql.execute (""" UPDATE Devices
SET dev_NAME = COALESCE(( SET devName = COALESCE((
SELECT cur_Name SELECT cur_Name
FROM CurrentScan FROM CurrentScan
WHERE cur_MAC = dev_MAC WHERE cur_MAC = devMac
AND cur_Name IS NOT NULL AND cur_Name IS NOT NULL
AND cur_Name <> 'null' AND cur_Name <> 'null'
AND cur_Name <> '' AND cur_Name <> ''
), dev_NAME) ), devName)
WHERE (dev_NAME IN ('(unknown)', '(name not found)', '') WHERE (devName IN ('(unknown)', '(name not found)', '')
OR dev_NAME IS NULL) OR devName IS NULL)
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT 1
FROM CurrentScan FROM CurrentScan
WHERE cur_MAC = dev_MAC WHERE cur_MAC = devMac
AND cur_Name IS NOT NULL AND cur_Name IS NOT NULL
AND cur_Name <> 'null' AND cur_Name <> 'null'
AND cur_Name <> '' AND cur_Name <> ''
@@ -439,48 +439,48 @@ def update_devices_data_from_scan (db):
# Update VENDORS # Update VENDORS
recordsToUpdate = [] recordsToUpdate = []
query = """SELECT * FROM Devices query = """SELECT * FROM Devices
WHERE dev_Vendor = '(unknown)' OR dev_Vendor ='' WHERE devVendor = '(unknown)' OR devVendor =''
OR dev_Vendor IS NULL""" OR devVendor IS NULL"""
for device in sql.execute (query) : for device in sql.execute (query) :
vendor = query_MAC_vendor (device['dev_MAC']) vendor = query_MAC_vendor (device['devMac'])
if vendor != -1 and vendor != -2 : if vendor != -1 and vendor != -2 :
recordsToUpdate.append ([vendor, device['dev_MAC']]) recordsToUpdate.append ([vendor, device['devMac']])
if len(recordsToUpdate) > 0: if len(recordsToUpdate) > 0:
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ", recordsToUpdate ) sql.executemany ("UPDATE Devices SET devVendor = ? WHERE devMac = ? ", recordsToUpdate )
# Guess ICONS # Guess ICONS
recordsToUpdate = [] recordsToUpdate = []
query = """SELECT * FROM Devices query = """SELECT * FROM Devices
WHERE dev_Icon in ('', 'null') WHERE devIcon in ('', 'null')
OR dev_Icon IS NULL""" OR devIcon IS NULL"""
default_icon = get_setting_value('NEWDEV_dev_Icon') default_icon = get_setting_value('NEWDEV_devIcon')
for device in sql.execute (query) : for device in sql.execute (query) :
# Conditional logic for dev_Icon guessing # Conditional logic for devIcon guessing
dev_Icon = guess_icon(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_icon) devIcon = guess_icon(device['devVendor'], device['devMac'], device['devLastIP'], device['devName'], default_icon)
recordsToUpdate.append ([dev_Icon, device['dev_MAC']]) recordsToUpdate.append ([devIcon, device['devMac']])
if len(recordsToUpdate) > 0: if len(recordsToUpdate) > 0:
sql.executemany ("UPDATE Devices SET dev_Icon = ? WHERE dev_MAC = ? ", recordsToUpdate ) sql.executemany ("UPDATE Devices SET devIcon = ? WHERE devMac = ? ", recordsToUpdate )
# Guess Type # Guess Type
recordsToUpdate = [] recordsToUpdate = []
query = """SELECT * FROM Devices query = """SELECT * FROM Devices
WHERE dev_DeviceType in ('', 'null') WHERE devType in ('', 'null')
OR dev_DeviceType IS NULL""" OR devType IS NULL"""
default_type = get_setting_value('NEWDEV_dev_DeviceType') default_type = get_setting_value('NEWDEV_devType')
for device in sql.execute (query) : for device in sql.execute (query) :
# Conditional logic for dev_Icon guessing # Conditional logic for devIcon guessing
dev_DeviceType = guess_type(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_type) devType = guess_type(device['devVendor'], device['devMac'], device['devLastIP'], device['devName'], default_type)
recordsToUpdate.append ([dev_DeviceType, device['dev_MAC']]) recordsToUpdate.append ([devType, device['devMac']])
if len(recordsToUpdate) > 0: if len(recordsToUpdate) > 0:
sql.executemany ("UPDATE Devices SET dev_DeviceType = ? WHERE dev_MAC = ? ", recordsToUpdate ) sql.executemany ("UPDATE Devices SET devType = ? WHERE devMac = ? ", recordsToUpdate )
mylog('debug','[Update Devices] Update devices end') mylog('debug','[Update Devices] Update devices end')
@@ -504,7 +504,7 @@ def update_devices_names (db):
foundPholus = 0 foundPholus = 0
# Gen unknown devices # Gen unknown devices
sql.execute ("SELECT * FROM Devices WHERE dev_Name IN ('(unknown)','', '(name not found)') AND dev_LastIP <> '-'") sql.execute ("SELECT * FROM Devices WHERE devName IN ('(unknown)','', '(name not found)') AND devLastIP <> '-'")
unknownDevices = sql.fetchall() unknownDevices = sql.fetchall()
db.commitDB() db.commitDB()
@@ -528,7 +528,7 @@ def update_devices_names (db):
newName = nameNotFound newName = nameNotFound
# Resolve device name with DiG # Resolve device name with DiG
newName = resolve_device_name_dig (device['dev_MAC'], device['dev_LastIP']) newName = resolve_device_name_dig (device['devMac'], device['devLastIP'])
# count # count
if newName != nameNotFound: if newName != nameNotFound:
@@ -536,21 +536,21 @@ def update_devices_names (db):
# Resolve device name with AVAHISCAN plugin data # Resolve device name with AVAHISCAN plugin data
if newName == nameNotFound: if newName == nameNotFound:
newName = get_device_name_mdns(db, device['dev_MAC'], device['dev_LastIP']) newName = get_device_name_mdns(db, device['devMac'], device['devLastIP'])
if newName != nameNotFound: if newName != nameNotFound:
foundmDNSLookup += 1 foundmDNSLookup += 1
# Resolve device name with NSLOOKUP plugin data # Resolve device name with NSLOOKUP plugin data
if newName == nameNotFound: if newName == nameNotFound:
newName = get_device_name_nslookup(db, device['dev_MAC'], device['dev_LastIP']) newName = get_device_name_nslookup(db, device['devMac'], device['devLastIP'])
if newName != nameNotFound: if newName != nameNotFound:
foundNsLookup += 1 foundNsLookup += 1
# Resolve device name with NSLOOKUP plugin data # Resolve device name with NSLOOKUP plugin data
if newName == nameNotFound: if newName == nameNotFound:
newName = get_device_name_nbtlookup(db, device['dev_MAC'], device['dev_LastIP']) newName = get_device_name_nbtlookup(db, device['devMac'], device['devLastIP'])
if newName != nameNotFound: if newName != nameNotFound:
foundNbtLookup += 1 foundNbtLookup += 1
@@ -560,10 +560,10 @@ def update_devices_names (db):
if newName == nameNotFound: if newName == nameNotFound:
# Try MAC matching # Try MAC matching
newName = resolve_device_name_pholus (device['dev_MAC'], device['dev_LastIP'], pholusResults, nameNotFound, False) newName = resolve_device_name_pholus (device['devMac'], device['devLastIP'], pholusResults, nameNotFound, False)
# Try IP matching # Try IP matching
if newName == nameNotFound: if newName == nameNotFound:
newName = resolve_device_name_pholus (device['dev_MAC'], device['dev_LastIP'], pholusResults, nameNotFound, True) newName = resolve_device_name_pholus (device['devMac'], device['devLastIP'], pholusResults, nameNotFound, True)
# count # count
if newName != nameNotFound: if newName != nameNotFound:
@@ -574,22 +574,22 @@ def update_devices_names (db):
notFound += 1 notFound += 1
# if dev_Name is the same as what we will change it to, take no action # if devName is the same as what we will change it to, take no action
# this mitigates a race condition which would overwrite a users edits that occured since the select earlier # this mitigates a race condition which would overwrite a users edits that occured since the select earlier
if device['dev_Name'] != nameNotFound: if device['devName'] != nameNotFound:
recordsNotFound.append (["(name not found)", device['dev_MAC']]) recordsNotFound.append (["(name not found)", device['devMac']])
else: else:
# name was found with DiG or Pholus # name was found with DiG or Pholus
recordsToUpdate.append ([newName, device['dev_MAC']]) recordsToUpdate.append ([newName, device['devMac']])
# Print log # Print log
mylog('verbose', [f'[Update Device Name] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN/Pholus): {len(recordsToUpdate)} ({foundDig}/{foundmDNSLookup}/{foundNsLookup}/{foundNbtLookup}/{foundPholus})'] ) mylog('verbose', [f'[Update Device Name] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN/Pholus): {len(recordsToUpdate)} ({foundDig}/{foundmDNSLookup}/{foundNsLookup}/{foundNbtLookup}/{foundPholus})'] )
mylog('verbose', [f'[Update Device Name] Names Not Found : {notFound}'] ) mylog('verbose', [f'[Update Device Name] Names Not Found : {notFound}'] )
# update not found devices with (name not found) # update not found devices with (name not found)
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsNotFound ) sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsNotFound )
# update names of devices which we were bale to resolve # update names of devices which we were bale to resolve
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsToUpdate ) sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsToUpdate )
db.commitDB() db.commitDB()
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------

View File

@@ -0,0 +1,132 @@
import graphene
from graphene import ObjectType, String, Int, Boolean, Field, List
import json
import sys
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
from logger import mylog
from const import apiPath
# Define a base URL with the user's home directory
folder = apiPath
# Load your JSON data
with open(folder + 'table_devices.json', 'r') as f:
devices_data = json.load(f)["data"]
# mylog('none', [f'[graphql_schema] devices_data {devices_data}'])
# Device ObjectType
class Device(ObjectType):
rowid = Int()
devMac = String() # This should match devMac, not devMac
devName = String() # This should match devName, not devName
devOwner = String() # This should match devOwner, not devOwner
devType = String() # This should match devType, not devType
devVendor = String() # This should match devVendor, not devVendor
devFavorite = Int() # This should match devFavorite, not devFavorite
devGroup = String() # This should match devGroup, not devGroup
devComments = String() # This should match devComments, not devComments
devFirstConnection = String() # This should match devFirstConnection, not devFirstConnection
devLastConnection = String() # This should match devLastConnection, not devLastConnection
devLastIP = String() # This should match devLastIP, not devLastIP
devStaticIP = Int() # This should match devStaticIP, not devStaticIP
devScan = Int() # This should match devScan, not devScan
devLogEvents = Int() # This should match devLogEvents, not devLogEvents
devAlertEvents = Int() # This should match devAlertEvents, not devAlertEvents
devAlertDeviceDown = Int() # This should match devAlertDeviceDown, not devAlertDown
devSkipRepeated = Int() # This should match devSkipRepeated, not devSkipRepeated
devLastNotification = String() # This should match devLastNotification, not devLastNotification
devPresentLastScan = Int() # This should match devPresentLastScan, not devPresentLastScan
devNewDevice = Int() # This should match devNewDevice, not devIsNew
devLocation = String() # This should match devLocation, not devLocation
devArchived = Int() # This should match devArchived, not devIsArchived
devNetworkNodeMACADDR = String() # This should match devNetworkNodeMACADDR, not devParentMAC
devNetworkNodePort = String() # This should match devNetworkNodePort, not devParentPort
devIcon = String() # This should match devIcon, not devIcon
devGUID = String() # This should match devGUID, not devGUID
devNetworkSite = String() # This should match devNetworkSite, not devSite
devSSID = String() # This should match devSSID, not devSSID
devSyncHubNodeName = String() # This should match devSyncHubNodeName, not devSyncHubNode
devSourcePlugin = String() # This should match devSourcePlugin, not devSourcePlugin
# Query ObjectType
class Query(ObjectType):
devices = List(Device)
def resolve_devices(self, info):
# Map the data to match the GraphQL schema's camelCase
mapped_devices = []
for device in devices_data:
mapped_device = {
'rowid': device['rowid'],
'devMac': device['devMac'], # Mapping from snake_case to camelCase
'devName': device['devName'],
'devOwner': device['devOwner'],
'devType': device['devType'],
'devVendor': device['devVendor'],
'devFavorite': device['devFavorite'],
'devGroup': device['devGroup'],
'devComments': device['devComments'],
'devFirstConnection': device['devFirstConnection'],
'devLastConnection': device['devLastConnection'],
'devLastIP': device['devLastIP'],
'devStaticIP': device['devStaticIP'],
'devScan': device['devScan'],
'devLogEvents': device['devLogEvents'],
'devAlertEvents': device['devAlertEvents'],
'devAlertDown': device['devAlertDown'],
'devSkipRepeated': device['devSkipRepeated'],
'devLastNotification': device['devLastNotification'],
'devPresentLastScan': device['devPresentLastScan'],
'devIsNew': device['devIsNew'],
'devLocation': device['devLocation'],
'devIsArchived': device['devIsArchived'],
'devParentMAC': device['devParentMAC'],
'devParentPort': device['devParentPort'],
'devIcon': device['devIcon'],
'devGUID': device['devGUID'],
'devSite': device['devSite'],
'devSSID': device['devSSID'],
'devSyncHubNode': device['devSyncHubNode'],
'devSourcePlugin': device['devSourcePlugin']
}
mapped_devices.append(mapped_device)
return mapped_devices
# Schema Definition
devicesSchema = graphene.Schema(query=Query)
# $.ajax({
# url: 'php/server/query_graphql.php', // The PHP endpoint that proxies to the GraphQL server
# type: 'POST',
# contentType: 'application/json', // Send the data as JSON
# data: JSON.stringify({
# query: `
# query {
# devices {
# devMac
# devName
# devLastConnection
# devArchived
# }
# }
# `, // GraphQL query for plugins
# variables: {} // Optional, pass variables if needed
# }),
# success: function(response) {
# console.log('GraphQL Response:', response);
# // Handle the GraphQL response here
# },
# error: function(xhr, status, error) {
# console.error('AJAX Error:', error);
# // Handle errors here
# }
# });

View File

@@ -0,0 +1,47 @@
import threading
from flask import Flask, request, jsonify
from .graphql_schema import devicesSchema
from graphene import Schema
import sys
# Global variable to track the server thread
server_thread = None
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
from logger import mylog
from helper import get_setting_value
app = Flask(__name__)
GRAPHQL_PORT = get_setting_value("GRAPHQL_PORT")
API_TOKEN = get_setting_value("API_TOKEN")
@app.route("/graphql", methods=["POST"])
def graphql_endpoint():
# Check for API token in headers
token = request.headers.get("Authorization")
if token != f"Bearer {API_TOKEN}":
mylog('none', [f'[graphql_server] Unauthorized access attempt'])
return jsonify({"error": "Unauthorized"}), 401
data = request.get_json()
mylog('none', [f'[graphql_server] data: {data}'])
# Use the schema to execute the GraphQL query
result = devicesSchema.execute(data.get("query"), variables=data.get("variables"))
mylog('none', [f'[graphql_server] result: {result}'])
# Return the data from the query in JSON format
return jsonify(result.data)
def start_server():
"""Function to start the GraphQL server in a background thread."""
mylog('none', [f'[graphql_server] Started'])
# Start the Flask app in a separate thread
thread = threading.Thread(target=lambda: app.run(host="0.0.0.0", port=GRAPHQL_PORT, debug=True, use_reloader=False))
thread.start()

View File

@@ -15,6 +15,8 @@ from pathlib import Path
import requests import requests
import base64 import base64
import hashlib import hashlib
import random
import string
import conf import conf
@@ -904,6 +906,11 @@ def extract_ip_addresses(text):
ip_addresses = re.findall(ip_pattern, text) ip_addresses = re.findall(ip_pattern, text)
return ip_addresses return ip_addresses
def generate_random_string(length):
characters = string.ascii_letters + string.digits
return ''.join(random.choice(characters) for _ in range(length))
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# JSON methods # JSON methods
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------

View File

@@ -12,7 +12,7 @@ import re
import conf import conf
from const import fullConfPath, applicationPath, fullConfFolder from const import fullConfPath, applicationPath, fullConfFolder
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
from logger import mylog from logger import mylog
from api import update_api from api import update_api
from scheduler import schedule_class from scheduler import schedule_class
@@ -148,9 +148,11 @@ def importConfigs (db, all_plugins):
conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General') conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.HRS_TO_KEEP_OFFDEV = ccd('HRS_TO_KEEP_OFFDEV', 0 , c_d, 'Keep offline devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General') conf.HRS_TO_KEEP_OFFDEV = ccd('HRS_TO_KEEP_OFFDEV', 0 , c_d, 'Keep offline devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.CLEAR_NEW_FLAG = ccd('CLEAR_NEW_FLAG', 0 , c_d, 'Clear new flag', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General') conf.CLEAR_NEW_FLAG = ccd('CLEAR_NEW_FLAG', 0 , c_d, 'Clear new flag', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General') conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE devPresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.VERSION = ccd('VERSION', '' , c_d, 'Version', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{ "readonly": "true" }] ,"transformers": []}]}', '', 'General') conf.VERSION = ccd('VERSION', '' , c_d, 'Version', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{ "readonly": "true" }] ,"transformers": []}]}', '', 'General')
conf.NETWORK_DEVICE_TYPES = ccd('NETWORK_DEVICE_TYPES', ['AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet'] , c_d, 'Network device types', '{"dataType":"array","elements":[{"elementType":"input","elementOptions":[{"placeholder":"Enter value"},{"suffix":"_in"},{"cssClasses":"col-sm-10"},{"prefillValue":"null"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":["_in"]},{"separator":""},{"cssClasses":"col-xs-12"},{"onClick":"addList(this,false)"},{"getStringKey":"Gen_Add"}],"transformers":[]},{"elementType":"select", "elementHasInputValue":1,"elementOptions":[{"multiple":"true"},{"readonly":"true"},{"editable":"true"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeAllOptions(this)"},{"getStringKey":"Gen_Remove_All"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeFromList(this)"},{"getStringKey":"Gen_Remove_Last"}],"transformers":[]}]}', '[]', 'General') conf.NETWORK_DEVICE_TYPES = ccd('NETWORK_DEVICE_TYPES', ['AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet'] , c_d, 'Network device types', '{"dataType":"array","elements":[{"elementType":"input","elementOptions":[{"placeholder":"Enter value"},{"suffix":"_in"},{"cssClasses":"col-sm-10"},{"prefillValue":"null"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":["_in"]},{"separator":""},{"cssClasses":"col-xs-12"},{"onClick":"addList(this,false)"},{"getStringKey":"Gen_Add"}],"transformers":[]},{"elementType":"select", "elementHasInputValue":1,"elementOptions":[{"multiple":"true"},{"readonly":"true"},{"editable":"true"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeAllOptions(this)"},{"getStringKey":"Gen_Remove_All"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeFromList(this)"},{"getStringKey":"Gen_Remove_Last"}],"transformers":[]}]}', '[]', 'General')
conf.GRAPHQL_PORT = ccd('GRAPHQL_PORT', 20212 , c_d, 'GraphQL port', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
conf.API_TOKEN = ccd('API_TOKEN', 't_' + generate_random_string(20) , c_d, 'API token', '{"dataType": "string","elements": [{"elementType": "input","elementHasInputValue": 1,"elementOptions": [{ "cssClasses": "col-xs-12" }],"transformers": []},{"elementType": "button","elementOptions": [{ "getStringKey": "Gen_Generate" },{ "customParams": "API_TOKEN" },{ "onClick": "generateApiToken(this, 20)" },{ "cssClasses": "col-xs-12" }],"transformers": []}]}', '[]', 'General')
# UI # UI
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'German', 'Spanish', 'French', 'Norwegian', 'Russian', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Chinese (zh_cn)', 'Turkish (tr_tr)', 'Czech (cs_cz)', 'Arabic (ar_ar)', 'Catalan (ca_ca)' ]", 'UI') conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'German', 'Spanish', 'French', 'Norwegian', 'Russian', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Chinese (zh_cn)', 'Turkish (tr_tr)', 'Czech (cs_cz)', 'Arabic (ar_ar)', 'Catalan (ca_ca)' ]", 'UI')
@@ -399,21 +401,50 @@ def read_config_file(filename):
# 🤔Idea/TODO: Check and compare versions/timestamps amd only perform a replacement if config/version older than... # 🤔Idea/TODO: Check and compare versions/timestamps amd only perform a replacement if config/version older than...
replacements = { replacements = {
r'\bREPORT_TO\b': 'SMTP_REPORT_TO', r'\bREPORT_TO\b': 'SMTP_REPORT_TO',
r'\bSYNC_api_token\b': 'API_TOKEN',
r'\bREPORT_FROM\b': 'SMTP_REPORT_FROM', r'\bREPORT_FROM\b': 'SMTP_REPORT_FROM',
r'\bPIALERT_WEB_PROTECTION\b': 'SETPWD_enable_password', r'\bPIALERT_WEB_PROTECTION\b': 'SETPWD_enable_password',
r'\bPIALERT_WEB_PASSWORD\b': 'SETPWD_password', r'\bPIALERT_WEB_PASSWORD\b': 'SETPWD_password',
r'REPORT_MAIL=True': 'SMTP_RUN=\'on_notification\'', r'REPORT_MAIL=True': "SMTP_RUN='on_notification'",
r'REPORT_APPRISE=True': 'APPRISE_RUN=\'on_notification\'', r'REPORT_APPRISE=True': "APPRISE_RUN='on_notification'",
r'REPORT_NTFY=True': 'NTFY_RUN=\'on_notification\'', r'REPORT_NTFY=True': "NTFY_RUN='on_notification'",
r'REPORT_WEBHOOK=True': 'WEBHOOK_RUN=\'on_notification\'', r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
r'REPORT_PUSHSAFER=True': 'PUSHSAFER_RUN=\'on_notification\'', r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
r'REPORT_MQTT=True': 'MQTT_RUN=\'on_notification\'', r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=', r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS', r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG', r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
r'\/home/pi/pialert\b': '/app' r'dev_MAC': 'devMac',
r'dev_Name': 'devName',
r'dev_Favorite': 'devFavorite',
r'dev_Group': 'devGroup',
r'dev_Comments': 'devComments',
r'dev_FirstConnection': 'devFirstConnection',
r'dev_LastConnection': 'devLastConnection',
r'dev_LastIP': 'devLastIP',
r'dev_StaticIP': 'devStaticIP',
r'dev_ScanCycle': 'devScan',
r'dev_LogEvents': 'devLogEvents',
r'dev_AlertEvents': 'devAlertEvents',
r'dev_AlertDeviceDown': 'devAlertDown',
r'dev_SkipRepeated': 'devSkipRepeated',
r'dev_LastNotification': 'devLastNotification',
r'dev_PresentLastScan': 'devPresentLastScan',
r'dev_NewDevice': 'devIsNew',
r'dev_Location': 'devLocation',
r'dev_Archived': 'devIsArchived',
r'dev_Network_Node_MAC_ADDR': 'devParentMAC',
r'dev_Network_Node_port': 'devParentPort',
r'dev_Icon': 'devIcon',
r'dev_GUID': 'devGUID',
r'dev_NetworkSite': 'devSite',
r'dev_SSID': 'devSSID',
r'dev_SyncHubNodeName': 'devSyncHubNode',
r'dev_SourcePlugin': 'devSourcePlugin',
r'/home/pi/pialert\b': '/app'
} }
def renameSettings(config_file): def renameSettings(config_file):
# Check if the file contains any of the old setting code names # Check if the file contains any of the old setting code names
contains_old_settings = False contains_old_settings = False

View File

@@ -85,7 +85,7 @@ def void_ghost_disconnections (db):
AND eve_MAC IN ( AND eve_MAC IN (
SELECT Events.eve_MAC SELECT Events.eve_MAC
FROM CurrentScan, Devices, Events FROM CurrentScan, Devices, Events
WHERE dev_MAC = cur_MAC WHERE devMac = cur_MAC
AND eve_MAC = cur_MAC AND eve_MAC = cur_MAC
AND eve_EventType = 'Disconnected' AND eve_EventType = 'Disconnected'
AND eve_DateTime >= DATETIME(?, '-3 minutes') AND eve_DateTime >= DATETIME(?, '-3 minutes')
@@ -99,7 +99,7 @@ def void_ghost_disconnections (db):
AND eve_PairEventRowid IN ( AND eve_PairEventRowid IN (
SELECT Events.RowID SELECT Events.RowID
FROM CurrentScan, Devices, Events FROM CurrentScan, Devices, Events
WHERE dev_MAC = cur_MAC WHERE devMac = cur_MAC
AND eve_MAC = cur_MAC AND eve_MAC = cur_MAC
AND eve_EventType = 'Disconnected' AND eve_EventType = 'Disconnected'
AND eve_DateTime >= DATETIME(?, '-3 minutes') AND eve_DateTime >= DATETIME(?, '-3 minutes')
@@ -114,7 +114,7 @@ def void_ghost_disconnections (db):
AND ROWID IN ( AND ROWID IN (
SELECT Events.RowID SELECT Events.RowID
FROM CurrentScan, Devices, Events FROM CurrentScan, Devices, Events
WHERE dev_MAC = cur_MAC WHERE devMac = cur_MAC
AND eve_MAC = cur_MAC AND eve_MAC = cur_MAC
AND eve_EventType = 'Disconnected' AND eve_EventType = 'Disconnected'
AND eve_DateTime >= DATETIME(?, '-3 minutes') AND eve_DateTime >= DATETIME(?, '-3 minutes')
@@ -186,12 +186,12 @@ def insert_events (db):
sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime, sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime,
eve_EventType, eve_AdditionalInfo, eve_EventType, eve_AdditionalInfo,
eve_PendingAlertEmail) eve_PendingAlertEmail)
SELECT dev_MAC, dev_LastIP, '{startTime}', 'Device Down', '', 1 SELECT devMac, devLastIP, '{startTime}', 'Device Down', '', 1
FROM Devices FROM Devices
WHERE dev_AlertDeviceDown != 0 WHERE devAlertDown != 0
AND dev_PresentLastScan = 1 AND devPresentLastScan = 1
AND NOT EXISTS (SELECT 1 FROM CurrentScan AND NOT EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC WHERE devMac = cur_MAC
) """) ) """)
# Check new Connections or Down Reconnections # Check new Connections or Down Reconnections
@@ -208,7 +208,7 @@ def insert_events (db):
1 1
FROM CurrentScan AS c FROM CurrentScan AS c
LEFT JOIN LatestEventsPerMAC AS last_event ON c.cur_MAC = last_event.eve_MAC LEFT JOIN LatestEventsPerMAC AS last_event ON c.cur_MAC = last_event.eve_MAC
WHERE last_event.dev_PresentLastScan = 0 OR last_event.eve_MAC IS NULL WHERE last_event.devPresentLastScan = 0 OR last_event.eve_MAC IS NULL
""") """)
# Check disconnections # Check disconnections
@@ -216,13 +216,13 @@ def insert_events (db):
sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime, sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime,
eve_EventType, eve_AdditionalInfo, eve_EventType, eve_AdditionalInfo,
eve_PendingAlertEmail) eve_PendingAlertEmail)
SELECT dev_MAC, dev_LastIP, '{startTime}', 'Disconnected', '', SELECT devMac, devLastIP, '{startTime}', 'Disconnected', '',
dev_AlertEvents devAlertEvents
FROM Devices FROM Devices
WHERE dev_AlertDeviceDown = 0 WHERE devAlertDown = 0
AND dev_PresentLastScan = 1 AND devPresentLastScan = 1
AND NOT EXISTS (SELECT 1 FROM CurrentScan AND NOT EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC WHERE devMac = cur_MAC
) """) ) """)
# Check IP Changed # Check IP Changed
@@ -231,10 +231,10 @@ def insert_events (db):
eve_EventType, eve_AdditionalInfo, eve_EventType, eve_AdditionalInfo,
eve_PendingAlertEmail) eve_PendingAlertEmail)
SELECT cur_MAC, cur_IP, '{startTime}', 'IP Changed', SELECT cur_MAC, cur_IP, '{startTime}', 'IP Changed',
'Previous IP: '|| dev_LastIP, dev_AlertEvents 'Previous IP: '|| devLastIP, devAlertEvents
FROM Devices, CurrentScan FROM Devices, CurrentScan
WHERE dev_MAC = cur_MAC WHERE devMac = cur_MAC
AND dev_LastIP <> cur_IP """ ) AND devLastIP <> cur_IP """ )
mylog('debug','[Events] - Events end') mylog('debug','[Events] - Events end')
@@ -248,9 +248,9 @@ def insertOnlineHistory(db):
query = """ query = """
SELECT SELECT
COUNT(*) AS allDevics, COUNT(*) AS allDevics,
SUM(CASE WHEN dev_Archived = 1 THEN 1 ELSE 0 END) AS archivedDevices, SUM(CASE WHEN devIsArchived = 1 THEN 1 ELSE 0 END) AS archivedDevices,
SUM(CASE WHEN dev_PresentLastScan = 1 THEN 1 ELSE 0 END) AS onlineDevices, SUM(CASE WHEN devPresentLastScan = 1 THEN 1 ELSE 0 END) AS onlineDevices,
SUM(CASE WHEN dev_PresentLastScan = 0 AND dev_AlertDeviceDown = 1 THEN 1 ELSE 0 END) AS downDevices SUM(CASE WHEN devPresentLastScan = 0 AND devAlertDown = 1 THEN 1 ELSE 0 END) AS downDevices
FROM Devices FROM Devices
""" """

View File

@@ -246,8 +246,8 @@ class Notification_obj:
def clearPendingEmailFlag(self): def clearPendingEmailFlag(self):
# Clean Pending Alert Events # Clean Pending Alert Events
self.db.sql.execute ("""UPDATE Devices SET dev_LastNotification = ? self.db.sql.execute ("""UPDATE Devices SET devLastNotification = ?
WHERE dev_MAC IN ( WHERE devMac IN (
SELECT eve_MAC FROM Events SELECT eve_MAC FROM Events
WHERE eve_PendingAlertEmail = 1 WHERE eve_PendingAlertEmail = 1
) )

View File

@@ -48,12 +48,12 @@ def get_notifications (db):
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0 sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected', 'New Device' ) AND eve_MAC IN WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected', 'New Device' ) AND eve_MAC IN
( (
SELECT dev_MAC FROM Devices WHERE dev_AlertEvents = 0 SELECT devMac FROM Devices WHERE devAlertEvents = 0
)""") )""")
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0 sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType in ('Device Down', 'Down Reconnected') AND eve_MAC IN WHERE eve_PendingAlertEmail = 1 AND eve_EventType in ('Device Down', 'Down Reconnected') AND eve_MAC IN
( (
SELECT dev_MAC FROM Devices WHERE dev_AlertDeviceDown = 0 SELECT devMac FROM Devices WHERE devAlertDown = 0
)""") )""")
sections = get_setting_value('NTFPRCS_INCLUDED_SECTIONS') sections = get_setting_value('NTFPRCS_INCLUDED_SECTIONS')
@@ -62,7 +62,7 @@ def get_notifications (db):
if 'new_devices' in sections: if 'new_devices' in sections:
# Compose New Devices Section (no empty lines in SQL queries!) # Compose New Devices Section (no empty lines in SQL queries!)
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1 WHERE eve_PendingAlertEmail = 1
AND eve_EventType = 'New Device' {get_setting_value('NTFPRCS_new_dev_condition').replace('{s-quote}',"'")} AND eve_EventType = 'New Device' {get_setting_value('NTFPRCS_new_dev_condition').replace('{s-quote}',"'")}
ORDER BY eve_DateTime""" ORDER BY eve_DateTime"""
@@ -83,7 +83,7 @@ def get_notifications (db):
# Compose Devices Down Section # Compose Devices Down Section
# - select only Down Alerts with pending email of devices that didn't reconnect within the specified time window # - select only Down Alerts with pending email of devices that didn't reconnect within the specified time window
sqlQuery = f""" sqlQuery = f"""
SELECT dev_Name, eve_MAC, dev_Vendor, eve_IP, eve_DateTime, eve_EventType SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
FROM Events_Devices AS down_events FROM Events_Devices AS down_events
WHERE eve_PendingAlertEmail = 1 WHERE eve_PendingAlertEmail = 1
AND down_events.eve_EventType = 'Device Down' AND down_events.eve_EventType = 'Device Down'
@@ -113,7 +113,7 @@ def get_notifications (db):
# Compose Reconnected Down Section # Compose Reconnected Down Section
# - select only Devices, that were previously down and now are Connected # - select only Devices, that were previously down and now are Connected
sqlQuery = f""" sqlQuery = f"""
SELECT dev_Name, eve_MAC, dev_Vendor, eve_IP, eve_DateTime, eve_EventType SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
FROM Events_Devices AS reconnected_devices FROM Events_Devices AS reconnected_devices
WHERE reconnected_devices.eve_EventType = 'Down Reconnected' WHERE reconnected_devices.eve_EventType = 'Down Reconnected'
AND reconnected_devices.eve_PendingAlertEmail = 1 AND reconnected_devices.eve_PendingAlertEmail = 1
@@ -133,7 +133,7 @@ def get_notifications (db):
if 'events' in sections: if 'events' in sections:
# Compose Events Section (no empty lines in SQL queries!) # Compose Events Section (no empty lines in SQL queries!)
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1 WHERE eve_PendingAlertEmail = 1
AND eve_EventType IN ('Connected', 'Down Reconnected', 'Disconnected','IP Changed') {get_setting_value('NTFPRCS_event_condition').replace('{s-quote}',"'")} AND eve_EventType IN ('Connected', 'Down Reconnected', 'Disconnected','IP Changed') {get_setting_value('NTFPRCS_event_condition').replace('{s-quote}',"'")}
ORDER BY eve_DateTime""" ORDER BY eve_DateTime"""
@@ -190,11 +190,11 @@ def skip_repeated_notifications (db):
db.sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0 db.sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_MAC IN WHERE eve_PendingAlertEmail = 1 AND eve_MAC IN
( (
SELECT dev_MAC FROM Devices SELECT devMac FROM Devices
WHERE dev_LastNotification IS NOT NULL WHERE devLastNotification IS NOT NULL
AND dev_LastNotification <>"" AND devLastNotification <>""
AND (strftime("%s", dev_LastNotification)/60 + AND (strftime("%s", devLastNotification)/60 +
dev_SkipRepeated * 60) > devSkipRepeated * 60) >
(strftime('%s','now','localtime')/60 ) (strftime('%s','now','localtime')/60 )
) )
""" ) """ )