diff --git a/src-api/openzwave/network.py b/src-api/openzwave/network.py index 91fa48b9..9c35d074 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_LEVEL_CHANGE_START = 'LevelChangeStart' + * SIGNAL_LEVEL_CHANGE_STOP = 'LevelChangeStop' 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_LEVEL_CHANGE_START = 'LevelChangeStart' + SIGNAL_LEVEL_CHANGE_STOP = 'LevelChangeStop' 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_LEVEL_CHANGE_START: + self._handle_level_change_start(args) + elif notify_type == self.SIGNAL_LEVEL_CHANGE_STOP: + self._handle_level_change_stop(args) else: logger.warning(u'Skipping unhandled notification [%s]', args) except: @@ -1180,7 +1188,7 @@ def _handle_node_event(self, args): """ logger.debug(u'Z-Wave Notification NodeEvent : %s', args) dispatcher.send(self.SIGNAL_NODE_EVENT, - **{'network': self, 'node': self.nodes[args['nodeId']], 'value': args['event']}) + **{'network': self, 'node': self.nodes[args['nodeId']], 'value': args['event'], 'instance': args['instance']}) def _handle_node_naming(self, args): """ @@ -1614,6 +1622,55 @@ def _handle_msg_complete(self, args): dispatcher.send(self.SIGNAL_MSG_COMPLETE, \ **{'network': self}) + def _handle_level_change_start(self, args): + """ + A command-class event of multilevel switch start or color change start was received. You get this FROM a switch, when it starts + the switching state (e.g., holding a button that starts a dimmer action). It'll be terminated by an end event. + + dispatcher.send(self.SIGNAL_LEVEL_CHANGE_START, **{'network': self, 'node': self.nodes[args['nodeId']], 'instance': args['instance']}) + ... plus all the start parameters: primaryDirection, secondaryDirection, ignoreStartLevel, primarySwitchStartLevel, + durationSeconds, secondaryStepSize -- see the ZWave doc for these. + + :param args: data sent by the notification + :type args: dict() + + """ + logger.debug(u'Z-Wave Notification Level Change start : %s', args) + parameters = { + 'network' : self, + 'node' : self.nodes[args['nodeId']], + 'instance' : args['instance'], + 'type' : args['type'], + 'primaryDirection' : args['primaryDirection'], + 'secondaryDirection' : args['secondaryDirection'], + 'ignoreStartLevel' : args['ignoreStartLevel'], + 'primaryStartLevel' : args['primaryStartLevel'], + 'durationSeconds' : args['durationSeconds'], + 'secondaryStepSize' : args['secondaryStepSize'], + 'colorTarget' : args['colorTarget'] + } + dispatcher.send(self.SIGNAL_LEVEL_CHANGE_START, **parameters ) + + def _handle_level_change_stop ( self, args ): + """ + A command-class event of multilevel switch or color change stop was received. You get this FROM a switch, when it ENDS + the switching state (e.g., holding a button that starts a dimmer action, this is the button release). + + dispatcher.send(self.SIGNAL_LEVEL_CHANGE_STOP, **{'network': self, 'node': self.nodes[args['nodeId']], 'instance': args['instance']}) + + :param args: data sent by the notification + :type args: dict() + + """ + logger.debug( u'Z-Wave Notification Level Change stop : %s', args ) + parameters = { + 'network': self, + 'node': self.nodes[ args[ 'nodeId' ] ], + 'instance': args[ 'instance' ], + 'type' : args[ 'type' ] + } + dispatcher.send( self.SIGNAL_LEVEL_CHANGE_STOP, **parameters ) + def write_config(self): """ The last message that was sent is now complete. diff --git a/src-api/openzwave/option.py b/src-api/openzwave/option.py index 7fc68990..48e4cb8e 100755 --- a/src-api/openzwave/option.py +++ b/src-api/openzwave/option.py @@ -123,6 +123,17 @@ def set_log_file(self, logfile): """ return self.addOptionString("LogFileName", logfile, False) + def set_log_file_path(self, logfilePath): + """ + Set the log file location (directory). The logfile parameter just sets + the name, and defaults to userpath. Uncool if you want logs in RAM, e.g. + + :param logfilePath: The location of the log file + :type logfilePath: str + + """ + return self.addOptionString("LogFilePath", logfilePath, False) + def set_logging(self, status): """ Set the status of logging. diff --git a/src-lib/libopenzwave/libopenzwave.pyx b/src-lib/libopenzwave/libopenzwave.pyx old mode 100644 new mode 100755 index 2753a7d5..c5ac95f6 --- a/src-lib/libopenzwave/libopenzwave.pyx +++ b/src-lib/libopenzwave/libopenzwave.pyx @@ -47,7 +47,7 @@ from notification cimport Notification, NotificationType, NotificationCode from notification cimport Type_Notification, Type_Group, Type_NodeEvent, Type_SceneEvent, Type_DriverReset, Type_DriverRemoved from notification cimport Type_CreateButton, Type_DeleteButton, Type_ButtonOn, Type_ButtonOff from notification cimport Type_ValueAdded, Type_ValueRemoved, Type_ValueChanged, Type_ValueRefreshed -from notification cimport Type_ControllerCommand +from notification cimport Type_ControllerCommand, Type_LevelChangeStart, Type_LevelChangeStop from notification cimport const_notification, pfnOnNotification_t from values cimport ValueGenre, ValueType, ValueID from options cimport Options, Create as CreateOptions, OptionType, OptionType_Invalid, OptionType_Bool, OptionType_Int, OptionType_String @@ -197,6 +197,10 @@ 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"), + EnumWithDoc('LevelChangeStart').setDoc("Start for a multilevel switch or color change transition"), + EnumWithDoc('LevelChangeStop').setDoc("End of a multilevel switch or color change transition") ] PyNotificationCodes = [ @@ -292,6 +296,30 @@ PyOptionType = [ EnumWithDoc('String').setDoc("String."), ] +PyUserAlerts = [ + EnumWithDoc('Alert_None').setDoc("No Alert Currently Present"), + EnumWithDoc('Alert_ConfigOutOfDate').setDoc("One of the Config Files is out of date. Use GetNodeId to determine which node is effected."), + EnumWithDoc('Alert_MFSOutOfDate').setDoc("the manufacturer_specific.xml file is out of date."), + EnumWithDoc('Alert_ConfigFileDownloadFailed').setDoc("A Config File failed to download "), + EnumWithDoc('Alert_DNSError').setDoc("A error occurred performing a DNS Lookup"), + EnumWithDoc('Alert_NodeReloadRequired').setDoc("A new Config file has been discovered for this node, and its pending a Reload to Take affect"), + EnumWithDoc('Alert_UnsupportedController').setDoc("The Controller is not running a Firmware Library we support"), + EnumWithDoc('Alert_ApplicationStatus_Retry').setDoc("Application Status CC returned a Retry Later Message"), + EnumWithDoc('Alert_ApplicationStatus_Queued').setDoc("Command Has been Queued for later execution"), + EnumWithDoc('Alert_ApplicationStatus_Rejected').setDoc("Command has been rejected"), +] + +PyLevelChangeType = [ + EnumWithDoc('LevelChange_Switch').setDoc("Multilevel Switch"), + EnumWithDoc('LevelChange_Color').setDoc("Color Switch start/stop level change") +] + +PyLevelChangeDirection = [ + EnumWithDoc('LevelChangeDirection_Up').setDoc("When the change is started, increment."), + EnumWithDoc('LevelChangeDirection_Down').setDoc("When the change is started, decrement."), + EnumWithDoc('LevelChangeDirection_None').setDoc("Do not increment or decrement. Used for multilevel switch with 2 switches.") +] + class EnumWithDocType(str): """Enum helper""" def setDocType(self, doc, stype): @@ -512,9 +540,11 @@ cdef void notif_callback(const_notification _notification, void* _context) with n = {'notificationType' : PyNotifications[notification.GetType()], 'homeId' : notification.GetHomeId(), 'nodeId' : notification.GetNodeId(), + 'instance' : notification.GetInstance(), + 'userAlert' : PyUserAlerts[ notification.GetUserAlertType() ] } except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception - type %s", notification.GetType()) if notification.GetType() == Type_Group: try: n['groupIdx'] = notification.GetGroupIdx() @@ -587,6 +617,25 @@ cdef void notif_callback(const_notification _notification, void* _context) with #elif notification.GetType() in (Type_PollingEnabled, Type_PollingDisabled): # #Maybe we should enable/disable this # addValueId(notification.GetValueID(), n) + elif notification.GetType() == Type_LevelChangeStart: + try: + n['type'] = PyLevelChangeType[notification.GetLevelChangeParameters().m_type] + n['primaryDirection'] = PyLevelChangeDirection[notification.GetLevelChangeParameters().m_primaryDirection] + n['secondaryDirection'] = PyLevelChangeDirection[notification.GetLevelChangeParameters().m_secondaryDirection] + n['ignoreStartLevel'] = notification.GetLevelChangeParameters().m_ignoreStartLevel + n['primaryStartLevel'] = notification.GetLevelChangeParameters().m_primaryStartLevel + n['durationSeconds'] = notification.GetLevelChangeParameters().m_durationSeconds + n['secondaryStepSize'] = notification.GetLevelChangeParameters().m_secondaryStepSize + n['colorTarget'] = notification.GetLevelChangeParameters().m_colorTarget + except: + logger.exception("notif_callback exception Type_MultilevelSwitchStart") + raise + elif notification.GetType() == Type_LevelChangeStop: + try: + n['type'] = PyLevelChangeType[notification.GetLevelChangeParameters().m_type] + except: + logger.exception("notif_callback exception Type_LevelChangeStop") + raise logger.debug("notif_callback : call callback context") (_context)(n) if notification.GetType() == Type_ValueRemoved: diff --git a/src-lib/libopenzwave/notification.pxd b/src-lib/libopenzwave/notification.pxd index ab3f6a9e..181f3ae4 100755 --- a/src-lib/libopenzwave/notification.pxd +++ b/src-lib/libopenzwave/notification.pxd @@ -17,11 +17,11 @@ You should have received a copy of the GNU General Public License along with python-openzwave. If not, see http://www.gnu.org/licenses. """ -from libc.stdint cimport uint32_t, int32_t, int16_t, uint8_t, int8_t +from libc.stdint cimport uint32_t, int32_t, int16_t, uint8_t, int8_t, uint16_t from libcpp cimport bool #from libc.stdint cimport bint from values cimport ValueID -#from libcpp.string cimport string +from libcpp.string cimport string from mylibc cimport string cdef extern from *: @@ -61,6 +61,11 @@ cdef extern from "Notification.h" namespace "OpenZWave::Notification": Type_Notification = 26 # A manager notification report. Type_DriverRemoved = 27 # The Driver is being removed. (either due to Error or by request) Do Not Call Any Driver Related Methods after receiving this call. Type_ControllerCommand = 28 # When Controller Commands are executed, Notifications of Success/Failure etc are communicated via this Notification * Notification::GetEvent returns Driver::ControllerCommand and Notification::GetNotification returns Driver::ControllerState + Type_NodeReset = 29 # The Device has been reset and thus removed from the NodeList in OZW + Type_UserAlerts = 30 # Warnings and Notifications Generated by the library that should be displayed to the user (eg, out of date config files) + Type_ManufacturerSpecificDBReady = 31 # The ManufacturerSpecific Database Is Ready + Type_LevelChangeStart = 32 # Start for a multilevel switch or color change transition + Type_LevelChangeStop = 33 # End of a multilevel switch or color change transition cdef extern from "Notification.h" namespace "OpenZWave::Notification": @@ -73,12 +78,52 @@ cdef extern from "Notification.h" namespace "OpenZWave::Notification": Code_Dead = 5 # Report when a node is presumed dead. Code_Alive = 6 # Report when a node is revived. +cdef extern from "Notification.h" namespace "OpenZWave::Notification": + + cdef enum UserAlertNotification: + Alert_None = 0 # No Alert Currently Present + Alert_ConfigOutOfDate = 1 # One of the Config Files is out of date. Use GetNodeId to determine which node is effected. + Alert_MFSOutOfDate = 2 # the manufacturer_specific.xml file is out of date. + Alert_ConfigFileDownloadFailed = 3 # A Config File failed to download + Alert_DNSError = 4 # A error occurred performing a DNS Lookup + Alert_NodeReloadRequired = 5 # A new Config file has been discovered for this node, and its pending a Reload to Take affect + Alert_UnsupportedController = 6 # The Controller is not running a Firmware Library we support + Alert_ApplicationStatus_Retry = 7 # Application Status CC returned a Retry Later Message + Alert_ApplicationStatus_Queued = 8 # Command Has been Queued for later execution + Alert_ApplicationStatus_Rejected = 9 # Command has been rejected + +cdef extern from "Notification.h" namespace "OpenZWave::Notification": + + cdef enum LevelChangeType: + LevelChangeType_Switch = 0 # Multilevel switch + LevelChangeType_Color = 1 # Color change + +cdef extern from "Notification.h" namespace "OpenZWave::Notification": + + cdef enum LevelChangeDirection: + LevelChangeDirection_Up = 0 # Increment going up + LevelChangeDirection_Down = 1 # Decrement going down + LevelChangeDirection_None = 2 # Don't change in steps - used for multi-level switch for primary/secondary + +cdef extern from "Notification.h" namespace "OpenZWave::Notification": + + cdef cppclass LevelChangeParameters: + LevelChangeType m_type + LevelChangeDirection m_primaryDirection + LevelChangeDirection m_secondaryDirection + uint8_t m_ignoreStartLevel + uint8_t m_primaryStartLevel + uint16_t m_durationSeconds + uint8_t m_secondaryStepSize + string m_colorTarget + cdef extern from "Notification.h" namespace "OpenZWave": cdef cppclass Notification: NotificationType GetType() uint32_t GetHomeId() uint8_t GetNodeId() + uint8_t GetInstance() ValueID& GetValueID() uint8_t GetGroupIdx() uint8_t GetEvent() @@ -86,3 +131,5 @@ cdef extern from "Notification.h" namespace "OpenZWave": uint8_t GetSceneId() uint8_t GetNotification() uint8_t GetByte() + UserAlertNotification GetUserAlertType() + LevelChangeParameters GetLevelChangeParameters()