diff --git a/front/plugins/arp_scan/README.md b/front/plugins/arp_scan/README.md
new file mode 100755
index 00000000..622c5306
--- /dev/null
+++ b/front/plugins/arp_scan/README.md
@@ -0,0 +1,27 @@
+## Overview
+
+A plugin allowing for importing Un-Discoverable devices from the settings page.
+The main usecase is to add dumb network gear like unmanaged hubs and switches to the network view.
+There might be other usecases, please let me know.
+
+### Usage
+
+- Go to settings and find Un-Discoverabe Devices in the list of plugins.
+- Enable the plugin by changing the RUN parameter from disabled to `once` or `always_after_scan`.
+- Add the name of your device to the list. (remove the sample entry first)
+- SAVE
+- wait for the next scan to finish
+
+#### Examples:
+Settings:
+
+
+resulting in these devices:
+
+
+Allowing Un-Discoverable devices like hubs, switches or APs to be added to the network view.
+
+
+### Known Limitations
+ - Un-Discoverable Devices always show as offline. That is expected as they can not be discovered by Pi.Alert.
+ - All IPs are set to 0.0.0.0 therefore the "Random MAC" icon might show up.
diff --git a/front/plugins/arp_scan/config.json b/front/plugins/arp_scan/config.json
new file mode 100755
index 00000000..4f84c868
--- /dev/null
+++ b/front/plugins/arp_scan/config.json
@@ -0,0 +1,217 @@
+{
+ "code_name": "undiscoverables",
+ "unique_prefix": "ARPSCAN",
+ "enabled": true,
+ "data_source": "python-script",
+ "mapped_to_table": "DHCP_Leases",
+
+ "localized": ["display_name", "description", "icon"],
+
+ "display_name": [
+ {
+ "language_code": "en_us",
+ "string": "Un-Discoverable Devices"
+ }
+ ],
+ "icon": [
+ {
+ "language_code": "en_us",
+ "string": ""
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "This plugin is to import undiscoverable devices from a file."
+ }
+ ],
+ "params" : [
+ {
+ "name" : "devices",
+ "type" : "setting",
+ "value" : "UNDIS_devices_to_import"
+ }],
+
+ "settings": [
+ {
+ "function": "RUN",
+ "type": "text.select",
+ "default_value":"disabled",
+ "options": ["disabled", "once", "always_after_scan"],
+ "localized": ["name", "description"],
+ "name" :[{
+ "language_code":"en_us",
+ "string" : "When to run"
+ }],
+ "description": [{
+ "language_code":"en_us",
+ "string" : "When enabled, ONCE is the preferred option. It runs at startup and after every save of the config here.
Changes will only show in the devices after the next scan!"
+ }]
+ },
+ {
+ "function": "CMD",
+ "type": "text",
+ "default_value": "python3 /home/pi/pialert/front/plugins/undiscoverables/script.py devices={devices}",
+ "options": [],
+ "localized": ["name", "description"],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Command"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Command to run. This can not be changed"
+ }
+ ]
+ },
+
+ {
+ "function": "RUN_TIMEOUT",
+ "type": "integer",
+ "default_value": 10,
+ "options": [],
+ "localized": ["name", "description"],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Run timeout"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
+ }
+ ]
+ },
+ {
+ "function": "WATCH",
+ "type": "lable",
+ "default_value": [],
+ "options": [],
+ "localized": ["name", "description"],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Watched"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Undiscoverable Devices can not change their status, no watch is enabled."
+ }
+ ]
+ },
+ {
+ "function": "REPORT_ON",
+ "type": "lable",
+ "default_value": [],
+ "options": ["new", "watched-changed", "watched-not-changed"],
+ "localized": ["name", "description"],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Report on"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "No notifications will be sent."
+ }
+ ]
+ },
+ {
+ "function": "devices_to_import",
+ "type": "list",
+ "default_value":["dummy_router"],
+ "options": [],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code":"en_us",
+ "string" : "UnDiscoverable Devices"
+ }],
+ "description": [{
+ "language_code":"en_us",
+ "string" : "Devices to be added to the devices list."
+ }]
+ }
+ ],
+
+ "database_column_definitions":
+ [
+ {
+ "column": "Watched_Value1",
+ "mapped_to_column": "DHCP_Name",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "label",
+ "default_value":"",
+ "options": [],
+ "localized": ["name"],
+ "name":[{
+ "language_code":"en_us",
+ "string" : "Device Name"
+ }]
+ },
+ {
+ "column": "Object_PrimaryID",
+ "mapped_to_column": "DHCP_MAC",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "devicemac",
+ "default_value":"",
+ "options": [],
+ "localized": ["name"],
+ "name":[{
+ "language_code":"en_us",
+ "string" : "MAC address"
+ }]
+ },
+ {
+ "column": "Object_SecondaryID",
+ "mapped_to_column": "DHCP_IP",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "deviceip",
+ "default_value":"",
+ "options": [],
+ "localized": ["name"],
+ "name":[{
+ "language_code":"en_us",
+ "string" : "IP"
+ }]
+ } ,
+ {
+ "column": "DateTimeCreated",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "label",
+ "default_value":"",
+ "options": [],
+ "localized": ["name"],
+ "name":[{
+ "language_code":"en_us",
+ "string" : "Created"
+ }]
+ },
+ {
+ "column": "DateTimeChanged",
+ "mapped_to_column": "DHCP_DateTime",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "label",
+ "default_value":"",
+ "options": [],
+ "localized": ["name"],
+ "name":[{
+ "language_code":"en_us",
+ "string" : "Changed"
+ }]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/front/plugins/arp_scan/script.py b/front/plugins/arp_scan/script.py
new file mode 100755
index 00000000..ecfece0c
--- /dev/null
+++ b/front/plugins/arp_scan/script.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# test script by running python script.py devices=test,dummy
+
+import os
+import pathlib
+import argparse
+import sys
+
+sys.path.append("/home/pi/pialert/front/plugins")
+
+from plugin_helper import Plugin_Objects
+
+CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
+LOG_FILE = os.path.join(CUR_PATH , 'script.log')
+RESULT_FILE = os.path.join(CUR_PATH , 'last_result.log')
+
+
+
+def main():
+
+ # the script expects a parameter in the format of devices=device1,device2,...
+ parser = argparse.ArgumentParser(description='Import devices from settings')
+ parser.add_argument('devices', action="store", help="list of device names separated by ','")
+ values = parser.parse_args()
+
+ UNDIS_devices = Plugin_Objects( RESULT_FILE )
+
+ if values.devices:
+ for fake_dev in values.devices.split('=')[1].split(','):
+ UNDIS_devices.add_object(
+ primaryId=fake_dev, # MAC (Device Name)
+ secondaryId="0.0.0.0", # IP Address (always 0.0.0.0)
+ watched1=fake_dev, # Device Name
+ watched2="",
+ watched3="",
+ watched4="",
+ extra="",
+ foreignKey="")
+
+ UNDIS_devices.write_result_file()
+
+ return 0
+
+#===============================================================================
+# BEGIN
+#===============================================================================
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/front/plugins/known_template/config.json b/front/plugins/known_template/config.json
index ce750874..c7e3b9ae 100755
--- a/front/plugins/known_template/config.json
+++ b/front/plugins/known_template/config.json
@@ -39,9 +39,9 @@
"settings":[
{
"function": "target_macs",
- "type": "readonly",
+ "type": "list.readonly",
"maxLength": 50,
- "default_value": "",
+ "default_value": [],
"options": [],
"localized": ["name", "description"],
"name": [
diff --git a/pialert/flows.py b/pialert/flows.py
new file mode 100644
index 00000000..87b59ba4
--- /dev/null
+++ b/pialert/flows.py
@@ -0,0 +1,31 @@
+import json
+
+def update_value(json_data, object_path, key, value, target_property, desired_value):
+ # Helper function to traverse the JSON structure and get the target object
+ def traverse(obj, path):
+ keys = path.split(".")
+ for key in keys:
+ if isinstance(obj, list):
+ key = int(key)
+ obj = obj[key]
+ return obj
+
+ # Helper function to update the target property with the desired value
+ def update(obj, path, key, value, target_property, desired_value):
+ keys = path.split(".")
+ for i, key in enumerate(keys):
+ if isinstance(obj, list):
+ key = int(key)
+ # Check if we have reached the desired object
+ if i == len(keys) - 1 and obj[key][key] == value:
+ # Update the target property with the desired value
+ obj[key][target_property] = desired_value
+ else:
+ obj = obj[key]
+ return obj
+
+ # Get the target object based on the object path
+ target_obj = traverse(json_data, object_path)
+ # Update the value in the target object
+ updated_obj = update(json_data, object_path, key, value, target_property, desired_value)
+ return updated_obj
\ No newline at end of file
diff --git a/pialert/flows/apply_template.json b/pialert/flows/apply_template.json
index 0df0952d..e6fd3f17 100755
--- a/pialert/flows/apply_template.json
+++ b/pialert/flows/apply_template.json
@@ -1,13 +1,54 @@
{
- "name":"apply_template",
- "triggers": [
+ "name":"apply_template",
+ "params" : [
{
- "type": "new",
- "object":
- {
- "type": "db.row",
- "target": "Devices"
- }
+ "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" : "",
+ "type":"array",
+ "value": "trigger.Object_PrimaryID"
+ },
+ {
+ "type":"array",
+ "value": "trigger"
+ }
+ ],
+ "trigger": [
+ {
+ "object_type": "dbtable",
+ "object_key": "Devices",
+ "object_event": "new",
+ "object_filter": "",
+ "object_mappings":
+ [
+ {
+ "column": "Object_PrimaryID",
+ "mapped_to_column": "Dev_MAC",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "devicemac",
+ "default_value":"",
+ "options": [],
+ "localized": ["name"],
+ "name":[{
+ "language_code":"en_us",
+ "string" : "MAC address"
+ }]
+ }
+ ]
}
],
"steps": [
@@ -51,9 +92,15 @@
"params":
{
"unique_prefix": "KNWN",
- "override":{
-
- }
+ "overrides":[
+ {
+ "object_path": "settings.0",
+ "key":"function",
+ "value":"target_macs",
+ "target_property":"default_value",
+ "desired_value": "triggers.keys"
+ }
+ ]
}
}
diff --git a/pialert/scanners/pholusscan.py b/pialert/scanners/pholusscan.py
index 8a31946d..9dce94aa 100755
--- a/pialert/scanners/pholusscan.py
+++ b/pialert/scanners/pholusscan.py
@@ -81,6 +81,7 @@ def cleanResult(str):
str = str.replace(".lan", "")
str = str.replace(".home", "")
str = re.sub(r'-[a-fA-F0-9]{32}', '', str) # removing last part of e.g. Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77
+ str = re.sub(r'#.*', '', str) # Remove everything after '#' including the '#'
# remove trailing dots
if str.endswith('.'):
str = str[:-1]