Zwave sensors
#1
Posted 08 January 2011 - 09:52 AM
I have three devices:
- HomeManageables HM-DW001 Door/Window Sensor (also known as Everspring SM103)
- ACT ZIR000 PIR motion Motion Sensor
- HomeManageables HM-FS001 Flood Sensor
First Question:
All three of these devices are classified as Binary Sensors, yet the device class in the "Leviton" Zwave module is called MotionDetector. I believe this class should be renamed BinarySensor. Is this agreeable? It seems logical to me, since the actual connection to a MotionDetector, WindowSensor, DoorSensor, WaterSensor, etc. happens when the Zwave device is bound to an object in the "Home".
Second Question:
The Leviton MotionDetector class (the one that I propose renaming to BinarySensor) inherits from a class called MotionDetector, but I can't seem to locate where that class is defined. Any guidance here?
I've already modified the following methods to support the discovery of the DW001 and ZIR000:
ViziaRF.OnChangeOnNewData
Devices.UpdateDevices
Devices.AddDevice
I've also added the following methods to process commands from the DW001 and ZIR000:
Devices.SetMotionDetected - detects state changes (motion on/off, contact open/closed, water detected, etc.) set from the device
Devices.SetLastNotificationTime - handles wakeup notifications sent from the device every 4 hours
Devices.SetTamperAlarm - handles tamper alarm sent from device
I've added the following properties to the MotionDetector class:
LastWakeupNotificationTime (DateTime: readonly / bindable) - gets set to the time when the wakeup notification is received
TamperAlarm (Boolean: readonly / bindable / momentary) - gets set to true when the tamper alarm is received
LastTamperAlarmTime (DateTime: readonly / bindable) - gets set to the time when the tamper alarm is received
Everything seems to be working fine. The devices are discovered correctly, and I can receive and process state changes, wakeup notifications, and tamper alarms. In a logic diagram, I wired the TamperAlarm to my email sender, and it worked great!
I haven't added support for low battery notifications yet, and I'm not sure how to test that without tracking down some old batteries and just waiting days, weeks, or months for something to happen. I've instrumented OnChangeOnNewData with debugout to log unknown events so I can see them in debugview, so I should be ok there.
Anyway, does all this make sense? I'm a Premise noob, so I need to know if I'm on the right track? If all this is agreeable, I'll add the final sensor, then post a work in progress so someone with more Premise knowledge can check my work...
Mark
#2
Posted 08 January 2011 - 09:05 PM
It appears we are both modifying the same file, doh
code added to "reset" the VRC0P
'tell the VRC0P to abort commands this.SendCommand ">AB", true 'reset the VRC0P in an attempt to fix the issue this.SendCommand ">DE", true
I plan to post my code in the next week (been busy installing an Elk M1G), and maybe then we can combine our work?
To answer your question, it depends on how the sensors are modeled in the VRC0P protocol and the Zensys protocol (I think there is an open zwave protocol wiki if you do a google search). I don't have any binary sensors to test, but from what you're saying, it appears that a door sensor looks the same as a motion sensor to the VRC0P (or any zwave controller) during discovery and polling; maybe we should use a generic class that inherits from the "DigitalInput" class (sys://Schema/Device/DigitalInput) which is what it sounds like you did... The DigitalInput class uses a boolean property called "State" that will automatically bind to the "DoorOpen" and "MotionDetected" properties found on door sensor and motion sensor objects.
Your findings sound similar to what I've found when using a vizia rf+ fan controller. The fan controller appears as a dimmer to the VRC0P, so I left it that way and just bound it to a fan speed controller under home. What ascii text are you sending to discover each type of device?
EDIT: Any chance you have figured out how to improve ImportDeviceName reliability? I have a 30+ node network, and I always receive some X002 errors if I let the script send the name requests and some names will fail to ever be received before reaching the 3 failed job limit. The only work around I could figure out is to have a 5 second buffer between device name requests which greatly improves reliability and always results in all names being imported...
Changes to ImportDeviceNames method:
' ' The SYS Device object name will inherit the physical Z-Wave Device name. ' SYS Device Name <--- Z-Wave Device name dim oDevice dim iInterval iInterval = 0 for each oDevice in this.GetObjectsByType(Schema.Modules.Leviton.Classes.Device.Path) 'the timer is necessary to improve name import reliability; without a time buffer, many X002 'transmission packets are received. system.addTimer iInterval, "on error resume next: this.Parent.SendCommand '>N' & " & oDevice.NodeID & " & '?NN', true, 995", 1, oDevice.NodeID & "_" & oDevice.ObjectID iInterval = iInterval + 5 next
Edited by etc6849, 09 January 2011 - 03:14 AM.
#3
Posted 09 January 2011 - 07:08 AM
Combining the code would be excellent!. Just let me know how you would like to do this. Most of my changes are well contained to a few areas, so I expect the merge will be straightforward.I plan to post my code in the next week (been busy installing an Elk M1G), and maybe then we can combine our work?
I referenced the open-zwave project on code.google.com -- just google for "zwave open source". It defines all the Zwave command types, which includes BinarySensor (DW001 Door/Window Sensor and ZIR000 Motion Sensor), AlarmSensor (FS001 Flood Sensor), MultilevelSensor, etc. What I would like to do is create a Sensor virtual base class, then have Binary Sensor and Alarm Sensor inherit from the base class. Does this make sense? The DigitalInput class is what I need Sensor to inherit from, but I cannot find it when I try to "right-click New->Relationship->InheritedClass" in expert mode. How do I make my Sensor class inherit from DigitalInput instead of MotionDetector?To answer your question, it depends on how the sensors are modeled in the VRC0P protocol and the Zensys protocol (I think there is an open zwave protocol wiki if you do a google search). I don't have any binary sensors to test, but from what you're saying, it appears that a door sensor looks the same as a motion sensor to the VRC0P (or any zwave controller) during discovery and polling; maybe we should use a generic class that inherits from the "DigitalInput" class (sys://Schema/Device/DigitalInput) which is what it sounds like you did... The DigitalInput class uses a boolean property called "State" that will automatically bind to the "DoorOpen" and "MotionDetected" properties found on door sensor and motion sensor objects.
This is how I modified the discovery section of OnChangeOnNewData. Does this make sense?Your findings sound similar to what I've found when using a vizia rf+ fan controller. The fan controller appears as a dimmer to the VRC0P, so I left it that way and just bound it to a fan speed controller under home. What ascii text are you sending to discover each type of device?
select case this.Devices.DiscoveryType case 16: ' Switches ' No more Switches. Move on to discovering Dimmers. this.Devices.DiscoveryType = 17 this.Devices.DiscoveryStatus = "Discovering Dimmers ..." debugout "Discovering Dimmers ..." this.SendCommand ">?FI0,17,0,1", false, 996 case 17: ' Dimmers ' No more Dimmers or Switches. Move on to discovering Thermostats. this.Devices.DiscoveryType = 8 this.Devices.DiscoveryStatus = "Discovering Thermostats ..." debugout "Discovering Thermostats ..." this.SendCommand ">?FI0,8,0,1", false, 996 case 8: ' Thermostats ' No more Thermostats. Move on to discovering Binary Sensors. this.Devices.DiscoveryType = 161 this.Devices.DiscoveryStatus = "Discovering Alarm Sensors ..." debugout "Discovering Alarm Sensors ..." this.SendCommand ">?FI0,161,0,1", false, 996 case 161: ' Alarm Sensors ' No more Alarm Sensors. Move on to discovering Binary Sensors. this.Devices.DiscoveryType = 32 this.Devices.DiscoveryStatus = "Discovering Binary Sensors ..." debugout "Discovering Binary Sensors ..." this.SendCommand ">?FI0,32,0,1", false, 996 case 32: ' Binary Sensors ' No more Binary Sensors. Quit and reset. this.Devices.DeleteOrphanDevices this.Devices.ImportDeviceNames this.Devices.ResetDiscovery ' Poll all Devices unless Polling is already enabled if this.Devices.PollingInterval = 0 then this.Devices.PollDevices end if end selectUpdateDevices just becomes:
if this.InDiscoveryMode = true then select case this.DiscoveryType case 16: ' Switch this.AddDevice "Switch", method.NodeID iNodeID = method.NodeID case 17: ' Dimmer this.AddDevice "Dimmer", method.NodeID iNodeID = method.NodeID case 8: ' Thermostat this.AddDevice "Thermostat", method.NodeID iNodeID = method.NodeID case 32: ' Binary Sensor this.AddDevice "BinarySensor", method.NodeID iNodeID = method.NodeID case 161: ' Alarm Sensor this.AddDevice "AlarmSensor", method.NodeID iNodeID = method.NodeID case else: ' Unknown debugout "UpdateDevices(): Unknown device type: " & this.DiscoveryType & ", Node: " & method.NodeID end select
I have not looked at this part of the code yet. From what I can see in my own installation, it doesn't appear that I'm receiving any of the device names during device discovery.EDIT: Any chance you have figured out how to improve ImportDeviceName reliability? I have a 30+ node network, and I always receive some X002 errors if I let the script send the name requests and some names will fail to ever be received before reaching the 3 failed job limit. The only work around I could figure out is to have a 5 second buffer between device name requests which greatly improves reliability and always results in all names being imported...
#4
Posted 09 January 2011 - 01:54 PM
The other secret is some items don't show up when you try to browse to them from the new -> relationship menu. The secret is that you have to manually browse to the object and enable the "virtual" property (see attached). Once virtual is enabled, you can access the object from the relationship menu. To manually browse, hold control and left click on the "type" icon found under a random object's "Properties" window. Next, use the tree to navigate to Digital Input. Remember to change the virtual property back when you are done, but I think it will automatically change back if you restart the SYS service.
EDIT: Side note on how to structure things...
The RZC0P programming guide states the following:
For the generic and specific classes refer to the Zensys device class specification. For example switch device will have ggg=16, dimmer ggg=17, thermostat ggg=8.
I think that things should follow the Zensys device class typology; i.e. one virtual class for each Zensys device type. If motion sensor has its own Zensys device class, it should be a separate device that inherits from the relevant SYS class (sys://Schema/Device/MotionDetector). If all alarm sensors use the same Zensys device class, then I would stick with the DigitInput idea to make more generic alarm device objects that will bind to specific home objects. There are many SYS device classes to think about (see attached)...
It sounds like it will take me some research on the open zwave site to determine the device classes... Unless you want to paste them here
Attached Files
Edited by etc6849, 09 January 2011 - 02:15 PM.
#5
Posted 09 January 2011 - 06:16 PM
Don't you just love the secret handshakes and trapdoors in this app....The other secret is some items don't show up when you try to browse to them from the new -> relationship menu. The secret is that you have to manually browse to the object and enable the "virtual" property (see attached). Once virtual is enabled, you can access the object from the relationship menu. To manually browse, hold control and left click on the "type" icon found under a random object's "Properties" window. Next, use the tree to navigate to Digital Input. Remember to change the virtual property back when you are done, but I think it will automatically change back if you restart the SYS service.
I understand your point about one virtual class for each device type. OTOH, the BinarySensor and AlarmSensor devices seem to share many of the same characteristics, such as State Change, Wakeup Notification, Battery Level Notification, Tamper Notification, etc. I'll defer to your judgement on whether there should be a BinarySensor virtual class and an AlarmSensor virtual class, or just a single Sensor virtual class. Right now, I have a Sensor virtual class, along with a BinarySensor class and an AlarmSensor class, both of which inherit from Sensor (see attached).EDIT: Side note on how to structure things...
The RZC0P programming guide states the following:
For the generic and specific classes refer to the Zensys device class specification. For example switch device will have ggg=16, dimmer ggg=17, thermostat ggg=8.
I think that things should follow the Zensys device class typology; i.e. one virtual class for each Zensys device type. If motion sensor has its own Zensys device class, it should be a separate device that inherits from the relevant SYS class (sys://Schema/Device/MotionDetector). If all alarm sensors use the same Zensys device class, then I would stick with the DigitInput idea to make more generic alarm device objects that will bind to specific home objects. There are many SYS device classes to think about (see attached)...
Here's a link to the zwave open source project document I referenced.It sounds like it will take me some research on the open zwave site to determine the device classes... Unless you want to paste them here
Open Zwave Device Classes
Attached Files
#6
Posted 09 January 2011 - 08:04 PM
I'm curious how the motion sensors work... Do they require polling or will they instantly send a state change to the VRC0P?
Edited by etc6849, 09 January 2011 - 08:06 PM.
#7
Posted 09 January 2011 - 09:36 PM
After inclusion in the network, the sensor must be associated with the VRCOP in order for the VRCOP to be able to receive commands from the device. All commands (including state changes) are sent asynchronously (i.e. at the time the event occurs). Polling is not required.What you have looks very logical if there are some properties that are different; however, if both BinarySensor and AlarmSensor have the same exact properties, I would make a single sensor class. The sensor class would inherit from the DigitalInput class and have a property called "State" for sensor states. I would leave the tamper boolean since you can bind it to a "RelayDevice" under "Home" in order to trigger an alert (email, voice notification etc...) through a scriptMacro. This works because you can bind multiple home objects to a single device object luckily...
I'm curious how the motion sensors work... Do they require polling or will they instantly send a state change to the VRC0P?
It appears that AlarmSensor properties are a superset of BinarySensor.
All sensors of type BinarySensor and AlarmSensor send these commands:
32 -- Basic Command to set and unset the state (i.e. motion detected, contact closure opened/closed, water detected, etc.). This command is sent asynchronously by the device when the event occurs (i.e. without being polled)
113 -- Tamper Alarm Command is sent asynchronously when the device is "disturbed" (e.g. in the case of the door/window sensor, the tamper alarm is sent when you lift the device in a way that triggers the spring loaded switch on the bottom of the device).
132 -- Wakeup Notification Command is sent asynchronously by the device typically every 4 hours (although the interval can be changed)
128 -- Battery Level/Alarm Command is sent asynchronously by some of the devices (interval is still unclear to me). A low battery alarm condition also appears to be sent when the battery level gets "low" (not sure how they define "low").
In addition to the above, the flood sensor (AlarmSensor) also sends:
156 -- Sensor Alarm Command is sent asynchronously when it detects the presence or absence of water
145 -- Manufacturer Proprietary Command is sent periodically (I haven't figured out why or what this does yet)
Based on the above, it feels like there should be a base Sensor class, from which BinarySensor and AlarmSensor both inherit. There also is a MultilevelSensor defined in the doc I included in my previous reply. That also might inherit from Sensor. Alternatively, AlarmSensor could just inherit from BinarySensor, but I think that might take away some flexibility. What do you think?
From what I've seen in just a couple days, I'm pretty impressed with how the devices work.
Would you like me to post the Leviton module with my changes/edits?
Edited by markh, 09 January 2011 - 09:37 PM.
#8
Posted 10 January 2011 - 11:43 PM
These numbers represent a 10+ fold failure decrease from the old vizia rf xdo, so I'd like to publish this version along with your work. If you could post a similar image of failed jobs and transmission failures you're encountering that'd be great
To get the transmission numbers low I had to sacrifice the ",UP" that would result in an update being sent back to the controller for single switch and dimmer operations. Groups and scenes still rely on an update to change the state of the switch/dimmer in Premise after a group or scene command is sent (i.e. ",UP" is still appended to scene or group commands). I thought about coding a state change to match what is being sent to the dimmer/switch (that way the controller doesn't rely on an update being received from each switch/dimmer), but wasn't sure if it was worth the effort as I don't use scene or group commands enough and any updates do eventually come in (but can take a few seconds). This may be worth doing before we release a final version under the downloads section, what do you think?
As far as fixing your naming issue, I can't think of an elegant way to handle names. >Nxxx" should be received when a name is request is initiated, but there is no guarantee >Nxxx" will be received; thus, I don't think it's a good idea to use a flag like InNamingRequestMode. This new version uses a simple 5 second timer instead, but works very well on my 39 node vizia rf+ network.
Attached Files
Edited by etc6849, 10 January 2011 - 11:44 PM.
#9
Posted 11 January 2011 - 09:59 PM
I made the following modifications. As I'm still a Premise noob, please review my changes carefully and provide any constructive feedback. <wink> Feel free to modify as necessary.
Classes Deleted
- MotionDetector class
Classes Added
- Sensor virtual class
- BinarySensor class
- AlarmSensor class
Added the following methods to the Devices class
- SetSensorState
- SetLastWakeupNotificationTime
- SetTamperAlarm
- SetSensorAlarm
- SetBatteryLevel
Modified the following methods
- Devices.UpdateDevices
- Devices.AddDevice
- ViziaRF.OnChangeOnNewData
I've not had a chance to look at the naming process, and I may not be able to get to that for about a week or so.
Best regards,
Mark
Attached Files
#10
Posted 12 January 2011 - 05:25 PM
#11
Posted 14 January 2011 - 05:17 PM
Here's three notes I have:
1. The SetTamperAlarm only has one parameter, nodeID, but you pass two parameters from OnChangeOnNewData.
2. The default value property defines the defualt value for a device when it's constructed. You don't need the class constructor methods for each device type...
3. For cleanliness, I should have put the boolean PowerStateChanging and BrightnessChanging under Switch and Dimmer respectively not under the Device class. Sorry about that. I promise to remember to move them once we are done.
Pretty nice editions to the driver. Thanks
Attached Files
Edited by etc6849, 14 January 2011 - 05:31 PM.
#12
Posted 15 January 2011 - 02:57 AM
I'll take another look at what the tamper alarm command includes, then decide what to do about this.1. The SetTamperAlarm only has one parameter, nodeID, but you pass two parameters from OnChangeOnNewData.
If that's the case, then the constructors can be deleted.2. The default value property defines the defualt value for a device when it's constructed. You don't need the class constructor methods for each device type...
Makes sense.3. For cleanliness, I should have put the boolean PowerStateChanging and BrightnessChanging under Switch and Dimmer respectively not under the Device class. Sorry about that. I promise to remember to move them once we are done.
Unfortunately, I won't be able to look #1 for about a week or so.
Going forward, how would like to handle the edits to the module in order to avoid complicated code merges?
#13
Posted 15 January 2011 - 08:17 PM
The Sensor class has a property for tracking the last Wakeup Notification time; however, it's not clear to me how I would detect the absence of a Wakeup Notification event. By any chance, does the module have the ability to periodically (every 30 or 60 minutes, for example) iterate through the list of sensor devices looking for Wakeup Notifications that have not occurred? If detected, it could set a property that could be used to alert the user. Normally, this would be done by a watchdog thread, but I don't know if Premise supports such a thing inside a module.
#14
Posted 15 January 2011 - 09:02 PM
Since all modules execute in the same thread, what you could do is have a timer that is added when the date changes (to be conservative maybe we should use an 9 hour timer?). Since the date will be set every four hours, the timer we add will never execute. If the timer does execute, it will execute code to set an "Event" to alert the user by calling a method called something like WakeUpNotificationNotReceived or ChangeBatteries. I think I did something similar in this module to monitor battery status of X10 motion and door sensors: http://www.cocoontec...ds&showfile=159
#15
Posted 19 January 2011 - 11:52 AM
It turns out if you change from the default fade rate of a dimmer (by holding the paddle down and the left button at the same time), the module will not honor the new fade rate, doh! FadeRate is a feature of Leviton Vizia RF and RF+ dimmers, not sure if it applies to your dimmers or not. FadeRate not only defines how long a light takes to turn off, but there is also a FadeRate for turning on a lamp. Fade rates are set locally at the dimmer, except for scenes which can use fade rates set by Premise.
I've found there's a small bug in Leviton's protocol or firmware. If you turn on a light by sending a level command, (i.e. N23L50), the node will always use the default factory fade rate!?! If you send a power on command, the light will come on with the correct fade rate. Not a big change, so I can make it once your done testing the sensor classes. I don't think there's a work around; if you initiate a brightness change to turn on a light that Premise thinks is Off, NxxxOn must be sent before NxxxLxx in order to honor the fade rate set by the user.
Edited by etc6849, 19 January 2011 - 12:04 PM.
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users















