diff --git a/front/plugins/unifi_import/config.json b/front/plugins/unifi_import/config.json old mode 100755 new mode 100644 index d9cd84c5..f4964a56 --- a/front/plugins/unifi_import/config.json +++ b/front/plugins/unifi_import/config.json @@ -435,7 +435,7 @@ { "function": "CMD", "type": "text", - "default_value":"python3 /home/pi/pialert/front/plugins/unifi_import/script.py username={username} password={password} host={host} sites={sites} port={port} verifyssl={verifyssl} version={version}", + "default_value":"python3 /home/pi/pialert/front/plugins/unifi_import/script.py username={username} password={password} host={host} sites={sites} port={port} verifyssl={verifyssl} version={version} fullimport={fullimport}", "options": [], "localized": ["name", "description"], "name" : [{ @@ -548,7 +548,7 @@ }], "description": [{ "language_code":"en_us", - "string" : "The port number where the UNIFI controller is runnig. Usually it is 8443." + "string" : "The port number where the UNIFI controller is runnig. Usually it is 8443, for UDM(P) devices its 443." }, { "language_code":"es_es", @@ -722,7 +722,38 @@ { "language_code":"es_es", "string" : "Envíe una notificación solo en estos estados. new significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). watched-changed significa que las columnas Watched_ValueN seleccionadas cambiaron." - }] + }, + { + "function": "fullimport", + "type": "text.select", + "default_value":"disabled", + "options": ["disabled", "once", "always"], + "localized": ["name", "description"], + "name" :[{ + "language_code":"en_us", + "string" : "Perform full import" + }, + { + "language_code":"es_es", + "string" : "[ES] Perform full import" + }, + { + "language_code":"de_de", + "string" : "Vollständigen Import durchführen" + }], + "description": [{ + "language_code":"en_us", + "string" : "Enable a full import of all known devices by the controller instead of only the online ones. During the scan, all found devices appear online. If you select once the full import is only performed once and the status is set to done afterwards." + }, + { + "language_code":"es_es", + "string" : "Translation Needed - Enable a full import of all known devices by the controller instead of only the online ones. During the scan, all found devices appear online. If you select once the full import is only performed once and the status is set to done afterwards." + }, + { + "language_code":"de_de", + "string" : "Führe einen kompletten Import aller dem Controller bekannten Geräten durch. Während des Scans werden alle gefundenen Geräte einmalig als Online angezeigt. Bei der Auswahl von once wird der Scan einmalig durchgeführt und der Status anschliessend auf done gesetzt" + }] + }] } ] } diff --git a/front/plugins/unifi_import/script.py b/front/plugins/unifi_import/script.py old mode 100755 new mode 100644 index ccadeeb4..f8f195df --- a/front/plugins/unifi_import/script.py +++ b/front/plugins/unifi_import/script.py @@ -2,7 +2,7 @@ # Inspired by https://github.com/stevehoek/Pi.Alert # Example call -# python3 /home/pi/pialert/front/plugins/unifi_import/script.py username=pialert password=passw0rd host=192.168.1.1 site=default protocol=https port=8443 version='UDMP-unifiOS' +# python3 /home/pi/pialert/front/plugins/unifi_import/script.py username=pialert password=passw0rd host=192.168.1.1 site=default protocol=https port=443 verifyssl=false version='UDMP-unifiOS' # python3 /home/pi/pialert/front/plugins/unifi_import/script.py username=pialert password=passw0rd host=192.168.1.1 sites=sdefault port=8443 verifyssl=false version=v5 from __future__ import unicode_literals @@ -28,6 +28,7 @@ from logger import mylog 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') +LOCK_FILE = os.path.join(CUR_PATH, 'full_run.lock') requests.packages.urllib3.disable_warnings(InsecureRequestWarning) @@ -39,7 +40,7 @@ def main(): # init global variables - global UNIFI_USERNAME, UNIFI_PASSWORD, UNIFI_HOST, UNIFI_SITES, PORT, VERIFYSSL, VERSION + global UNIFI_USERNAME, UNIFI_PASSWORD, UNIFI_HOST, UNIFI_SITES, PORT, VERIFYSSL, VERSION, FULL_IMPORT parser = argparse.ArgumentParser(description='Import devices from a UNIFI controller') @@ -51,9 +52,13 @@ def main(): parser.add_argument('port', action="store", help="Usually 8443") parser.add_argument('verifyssl', action="store", help="verify SSL certificate [true|false]") parser.add_argument('version', action="store", help="The base version of the controller API [v4|v5|unifiOS|UDMP-unifiOS]") + parser.add_argument('fullimport', action="store", help="Defines if a full import or only online devices hould be imported [disabled|once|always]" values = parser.parse_args() + + + # parse output plugin_objects = Plugin_Objects(RESULT_FILE) @@ -69,6 +74,7 @@ def main(): PORT = values.port.split('=')[1] VERIFYSSL = values.verifyssl.split('=')[1] VERSION = values.version.split('=')[1] + FULL_IMPORT = values.fullimport.split('=')[1] plugin_objects = get_entries(plugin_objects) @@ -79,9 +85,14 @@ def main(): # ............................................. -def get_entries(plugin_objects): +def get_entries(plugin_objects: plugin_helper.Plugin_Objects) -> plugin_helper.Plugin_Objects: global VERIFYSSL + # check if the full run must be run: + lock_file_value = read_lock_file() + perform_full_run = check_full_run_state(FULL_IMPORT, lock_file_value) + + sites = [] if ',' in UNIFI_SITES: @@ -157,7 +168,7 @@ def get_entries(plugin_objects): status = 1 if user['mac'] in online_macs else 0 - if status == 1: + if status == 1 or perform_full_run is True: ipTmp = get_unifi_val(user, 'last_ip') @@ -174,11 +185,15 @@ def get_entries(plugin_objects): extra=get_unifi_val(user, 'last_connection_network_name') ) - + # check if the lockfile needs to be adapted + set_lock_file_value(FULL_IMPORT, lock_file_value) + + mylog('verbose', [f'[UNFIMP] Found {len(plugin_objects)} Clients overall']) return plugin_objects + # ----------------------------------------------------------------------------- def get_unifi_val(obj, key): @@ -192,8 +207,8 @@ def get_unifi_val(obj, key): return 'null' -# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def set_name(name: str, hostName: str) -> str: if name != 'null': @@ -205,8 +220,42 @@ def set_name(name: str, hostName: str) -> str: else: return 'null' + +# ----------------------------------------------------------------------------- +def set_lock_file_value(config_value: str, lock_file_value: bool) -> None: + + # set lock if 'once' is set and the lock is not set + if config_value == 'once' and lock_file_value is False: + out = 1 + # reset lock if not 'once' is set and the lock is present + if config_value != 'once' and lock_file_value is True: + out = 0 + else: + mylog('debug', [f'[UNFIMP] No change on lock file needed'])) + return + + mylog('verbose', [f'[UNFIMP] Setting lock value for "full import" to {out}'])) + with open(LOCK_FILE 'w') as lock_file: + lock_file.write(str(value)) + + +# ----------------------------------------------------------------------------- +def read_lock_file() -> bool: + with open(LOCK_FILE, 'w') as lock_file: + return bool(int(lock_file.readline())) + + +# ----------------------------------------------------------------------------- +def check_full_run_state(config_value: str, lock_file_value: bool) -> bool: + if config_value == 'always' or (config_value == 'once' and lock_file_value == False): + mylog('debug', [f'[UNFIMP] Full import needs to be done: config_value: {config_value} and lock_file_value: {lock_file_value}'])) + return True + else: + mylog('debug', [f'[UNFIMP] Full import NOT needed: config_value: {config_value} and lock_file_value: {lock_file_value}'])) + return False + #=============================================================================== # BEGIN #=============================================================================== if __name__ == '__main__': - main() \ No newline at end of file + main()