From a6530503161a88518ab7a8ec7f5ec0f9899aa68c Mon Sep 17 00:00:00 2001 From: Nick Bogdanov Date: Fri, 9 Apr 2021 17:03:51 -0700 Subject: [PATCH] Handle UserAlerts and ManufacturerSpecificDBReady notifications On installations where the /etc/openzwave device configuration database is missing files, the Python wrapper can generate these unhelpful errors: 2021-04-09 09:01:26,267 notif_callback : new notification 2021-04-09 09:01:26,268 notif_callback : Notification type : 30, nodeId : 0 2021-04-09 09:01:26,268 notif_callback exception Traceback (most recent call last): File "src-lib/libopenzwave/libopenzwave.pyx", line 512, in libopenzwave.notif_callback IndexError: list index out of range UnboundLocalError: local variable 'n' referenced before assignment Exception ignored in: 'libopenzwave.notif_callback' UnboundLocalError: local variable 'n' referenced before assignment 2021-04-09 09:01:26,269 notif_callback : new notification 2021-04-09 09:01:26,269 notif_callback : Notification type : 30, nodeId : 0 2021-04-09 09:01:26,269 notif_callback exception Traceback (most recent call last): File "src-lib/libopenzwave/libopenzwave.pyx", line 512, in libopenzwave.notif_callback IndexError: list index out of range They correspond to these messages in the C++ library's log: 2021-04-09 09:10:23.476 Warning, Config Revision of ManufacturerSpecific Database is out of date 2021-04-09 09:10:23.476 Info, Queuing download for http://download.db.openzwave.com/mfs.xml 2021-04-09 09:10:23.477 Warning, File Removal failed: /etc/openzwave/manufacturer_specific.xml 2021-04-09 09:10:23.477 Warning, File Transfer Failed. Could not Rotate Existing File: /etc/openzwave/manufacturer_specific.xml 2021-04-09 09:10:23.477 Warning, Can't download ManufacturerSpecifix.xml Config file 2021-04-09 09:10:23.477 Info, ManufacturerSpecificDB Initialized 2021-04-09 09:10:23.477 Detail, Notification: User Alert - Manufacturer_specific.xml out of Date 2021-04-09 09:10:23.478 Detail, Notification: A Config File Failed to download 2021-04-09 09:10:23.478 Detail, Notification: ManufacturerSpecificDB Ready Update the Python wrapper to handle the notifications properly instead of generating IndexError exceptions. --- src-api/openzwave/network.py | 34 +++++++++++++++++++++++++++ src-lib/libopenzwave/libopenzwave.pyx | 2 ++ 2 files changed, 36 insertions(+) diff --git a/src-api/openzwave/network.py b/src-api/openzwave/network.py index 91fa48b9..32c21340 100755 --- a/src-api/openzwave/network.py +++ b/src-api/openzwave/network.py @@ -105,6 +105,8 @@ class ZWaveNetwork(ZWaveObject): * SIGNAL_NOTIFICATION = 'Notification' * SIGNAL_CONTROLLER_COMMAND = 'ControllerCommand' * SIGNAL_CONTROLLER_WAITING = 'ControllerWaiting' + * SIGNAL_USER_ALERTS = 'UserAlerts' + * SIGNAL_MANUFACTURER_SPECIFIC_DB_READY = 'ManufacturerSpecificDBReady' The table presented below sets notifications in the order they might typically be received, and grouped into a few logically related categories. Of course, given the variety @@ -282,6 +284,8 @@ class ZWaveNetwork(ZWaveObject): SIGNAL_NOTIFICATION = 'Notification' SIGNAL_CONTROLLER_COMMAND = 'ControllerCommand' SIGNAL_CONTROLLER_WAITING = 'ControllerWaiting' + SIGNAL_USER_ALERTS = 'UserAlerts' + SIGNAL_MANUFACTURER_SPECIFIC_DB_READY = 'ManufacturerSpecificDBReady' STATE_STOPPED = 0 STATE_FAILED = 1 @@ -984,6 +988,10 @@ def zwcallback(self, args): self._handle_driver_removed(args) elif notify_type == self.SIGNAL_CONTROLLER_COMMAND: self._handle_controller_command(args) + elif notify_type == self.SIGNAL_USER_ALERTS: + self._handle_user_alerts(args) + elif notify_type == self.SIGNAL_MANUFACTURER_SPECIFIC_DB_READY: + self._handle_manufacturer_specific_db_ready(args) else: logger.warning(u'Skipping unhandled notification [%s]', args) except: @@ -1600,6 +1608,32 @@ def _handle_controller_command(self, args): """ self._controller._handle_controller_command(args) + def _handle_user_alerts(self, args): + """ + Called when the library generates a warning or notification for the user + (e.g. out-of-date config files). The actual warning text is missing from the args dict, + but it shows up in the C++ logging output. + + :param args: data sent by the notification + :type args: dict() + + """ + logger.info(u'Z-Wave Notification UserAlert, see OZW_Log for details : %s', args) + dispatcher.send(self.SIGNAL_USER_ALERTS, \ + **{'network': self}) + + def _handle_manufacturer_specific_db_ready(self, args): + """ + Called when the ManufacturerSpecific database is ready. + + :param args: data sent by the notification + :type args: dict() + + """ + logger.debug(u'Z-Wave Notification ManufacturerSpecificDBReady : %s', args) + dispatcher.send(self.SIGNAL_MANUFACTURER_SPECIFIC_DB_READY, \ + **{'network': self}) + def _handle_msg_complete(self, args): """ The last message that was sent is now complete. diff --git a/src-lib/libopenzwave/libopenzwave.pyx b/src-lib/libopenzwave/libopenzwave.pyx index 2753a7d5..b5a87fe7 100644 --- a/src-lib/libopenzwave/libopenzwave.pyx +++ b/src-lib/libopenzwave/libopenzwave.pyx @@ -197,6 +197,8 @@ PyNotifications = [ EnumWithDoc('DriverRemoved').setDoc("The Driver is being removed."), EnumWithDoc('ControllerCommand').setDoc("When Controller Commands are executed, Notifications of Success/Failure etc are communicated via this Notification."), EnumWithDoc('NodeReset').setDoc("A node has been reset from OpenZWave's set. The Device has been reset and thus removed from the NodeList in OZW."), + EnumWithDoc('UserAlerts').setDoc("Warnings and Notifications Generated by the library that should be displayed to the user (eg, out of date config files)."), + EnumWithDoc('ManufacturerSpecificDBReady').setDoc("The ManufacturerSpecific Database Is Ready."), ] PyNotificationCodes = [