diff --git a/.gitignore b/.gitignore index ea9c9e15..f908738e 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ front/log/* front/plugins/**/*.log **/%40eaDir/ **/@eaDir/ + +__pycache__/ +*.py[cod] +*$py.class \ No newline at end of file diff --git a/db/pialert.db b/db/pialert.db deleted file mode 100755 index ff4e2731..00000000 Binary files a/db/pialert.db and /dev/null differ diff --git a/front/plugins/undiscoverables/README.md b/front/plugins/undiscoverables/README.md new file mode 100644 index 00000000..622c5306 --- /dev/null +++ b/front/plugins/undiscoverables/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: +![settings](https://github.com/Data-Monkey/Pi.Alert/assets/7224371/52883307-19a5-4602-b13a-9825461f6cc4) + +resulting in these devices: +![devices](https://github.com/Data-Monkey/Pi.Alert/assets/7224371/9f7659e7-75a8-4ae9-9f5f-781bdbcbc949) + +Allowing Un-Discoverable devices like hubs, switches or APs to be added to the network view. +![network](https://github.com/Data-Monkey/Pi.Alert/assets/7224371/b5ccc3b3-f5fd-4f5b-b0f0-e4e637c6da33) + +### 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/undiscoverables/config.json b/front/plugins/undiscoverables/config.json new file mode 100644 index 00000000..de03f76f --- /dev/null +++ b/front/plugins/undiscoverables/config.json @@ -0,0 +1,217 @@ +{ + "code_name": "undiscoverables", + "unique_prefix": "UNDIS", + "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": "selecttext", + "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": "readonly", + "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" + }] + } + ] +} diff --git a/front/plugins/undiscoverables/plugin_helper.py b/front/plugins/undiscoverables/plugin_helper.py new file mode 100644 index 00000000..e198f30a --- /dev/null +++ b/front/plugins/undiscoverables/plugin_helper.py @@ -0,0 +1,96 @@ +from time import strftime + + +# ------------------------------------------------------------------- +class Plugin_Object: + """ + Plugin_Object class to manage one object introduced by the plugin + An object typically is a device but could also be a website or something + else that is monitored by the plugin. + """ + + def __init__( + self, + primaryId="", + secondaryId="", + watched1="", + watched2="", + watched3="", + watched4="", + extra="", + foreignKey="", + ): + self.pluginPref = "" + self.primaryId = primaryId + self.secondaryId = secondaryId + self.created = strftime("%Y-%m-%d %H:%M:%S") + self.changed = "" + self.watched1 = watched1 + self.watched2 = watched2 + self.watched3 = watched3 + self.watched4 = watched4 + self.status = "" + self.extra = extra + self.userData = "" + self.foreignKey = foreignKey + + def write(self): + """ + write the object details as a string in the + format required to write the result file + """ + line = "{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format( + self.primaryId, + self.secondaryId, + self.created, + self.watched1, + self.watched2, + self.watched3, + self.watched4, + self.extra, + self.foreignKey, + ) + return line + + +class Plugin_Objects: + """ + Plugin_Objects is the class that manages and holds all the objects created by the plugin. + It contains a list of Plugin_Object instances. + And can write the required result file. + """ + + def __init__(self, result_file): + self.result_file = result_file + self.objects = [] + + def add_object( + self, + primaryId="", + secondaryId="", + watched1="", + watched2="", + watched3="", + watched4="", + extra="", + foreignKey="", + ): + self.objects.append( + Plugin_Object( + primaryId, + secondaryId, + watched1, + watched2, + watched3, + watched4, + extra, + foreignKey, + ) + ) + + def write_result_file(self): + # print ("writing file: "+self.result_file) + with open(self.result_file, mode="w") as fp: + for obj in self.objects: + fp.write(obj.write()) + fp.close() diff --git a/front/plugins/undiscoverables/script.py b/front/plugins/undiscoverables/script.py new file mode 100644 index 00000000..7f17554d --- /dev/null +++ b/front/plugins/undiscoverables/script.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# test script by running python script.py devices=test,dummy + +import os +import pathlib +import argparse + +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