Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User alerts; level/color start/stop events; set_log_file_path() #207

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion src-api/openzwave/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions src-api/openzwave/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
53 changes: 51 additions & 2 deletions src-lib/libopenzwave/libopenzwave.pyx
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = [
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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")
(<object>_context)(n)
if notification.GetType() == Type_ValueRemoved:
Expand Down
51 changes: 49 additions & 2 deletions src-lib/libopenzwave/notification.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -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 *:
Expand Down Expand Up @@ -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":

Expand All @@ -73,16 +78,58 @@ 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()
uint8_t GetButtonId()
uint8_t GetSceneId()
uint8_t GetNotification()
uint8_t GetByte()
UserAlertNotification GetUserAlertType()
LevelChangeParameters GetLevelChangeParameters()