Premise Z-Wave Status using RZCOP/VRCOP help

Motorola Premise
Nice job!

I look forward to seeing the next release.

EDIT
I removed my questions from this post ... just had to read a little more of your code to to be able to answer my own questions!
 
Thanks 123. I decided to use builder and installed the module remotely, but discovered one small error; it is fixed now :) Seems like it works pretty good. I also tested sendpollrequest and it worked fine for the vizia rf+ lights I have.

Same comments as before:
Try this alpha version and please report any issues as I'm not home this week to actually test it...

You'll have to manually add the dimmers and switches and the respective node ID's (must be an integer greater than or equal to 1 and less than 255). To do this import the module, then create a new VIZIA device under CustomDevices. Right click on VIZIA and click dimmer or switch. Be sure to fill in the address (node id).

For now the "discoverZones" button does nothing. I'll eventually post a new version that will create the children automatically for the user, and a version that supports thermostats (this is my hidden motive ) and perhaps scenes and groups. Fade time is also not implemented yet.

"SendPollRequest" should work for what manxam needs; just add a timer to toggle it true at the desired time interval.
 

Attachments

  • LevitonViziaRF_Alpha_2.zip
    5.5 KB · Views: 24
123, is there an advantage to using ManualAck in conjunction with toggling setAck when <E000 is received? Z-Wave seems so reliable that I don't need to do this so just used a 10 ms delay for now.
 
I've improved polling to also include feedback of the form NxxxLxxx. I've finished the node discovery too. DiscoverNodes will add any newly discovered nodes, but also keep existing nodes that still exist (ie are still included in the mesh network).
 

Attachments

  • Leviton_Beta.zip
    6.5 KB · Views: 22
...is there an advantage to using ManualAck in conjunction with toggling setAck when <E000 is received? ... just used a 10 ms delay for now.
I'll be honest and admit that I've never had to use the ManualAck/SetAck flags in any of the drivers I've built .. so I can't comment on how their usage will impact this driver. What I do know is that a 10 ms delay seems awfully short. The Windows operating system time-slices at around that amount so I wouldn't count on getting such a low time delay.

I'm not going to put too fine a point on it but the code in OnChangeOnNewData is getting awfully difficult to follow. Plus, there are several more Vizia packet types that you'll need to support including the "Node General" type (<N00:000,000,000,...) used for thermostats ... and it can contain a variable number of parameters.

I've written a parsing function that identifies received Vizia commands, validates their format, and extracts all parameters. It supports the following Vizia commands:
Code:
Error Status (<E)
Transmission Status (<X)
Found Node (<F)
Node Scene (<N S)
Node Light Level (<N L)
Node General (<N :)
Node Name (<N ")
Node Location Name (<N ')
gPacketParser returns an integer representing the packet type and a variable-length array containing all of the command's parameters. For example, for the Node Scene command the array would have four integer elements containing the following information:
(0) Node ID
(1) Scene Number
(2) Light Level
(3) Fade Rate

For the Node Light Level command, the array would have two integer elements:
(0) Node ID
(1) Light Level

For the Node Name command, the array would have two elements, one of type integer and the other string:
(0) Node ID
(1) Node Name

The attached zip archive contains a VBS file that allows you to test the function without using Premise. It doesn't read the serial-port but simply contains a few sample Vizia packets that you can test.

The zip archive also contains a bare-bones "zWave" driver that incorporates the new parser. It spits out whatever it receives to the Windows Debug Console.
 

Attachments

  • ViziaTester.zip
    5.1 KB · Views: 22
Thanks 123. RegEx looks really useful for something like this, too bad I've never heard of it!

Your code looks really nice. I think it's a good way to handle ascii feedback from any device, not just zwave... I'm going to have to study it a lot for learning purposes.

Just a few questions:
1. What's a good way to handle something like finding a node? Would you keep the FindDevice method that uses several object level hidden variables to store the node type asked about, instance, etc... or is there a better way?

If I make FindDevice a function instead of a method and place all of these variables (node type and instance) under it (where they probably belong), could I then access (from onchangenewdata) the last state of the variables after FindDevice has been called and completely executed using something like this: sysevent.method.FindDevice.DiscoveringInstance?
 
Regular Expressions are a very powerful means of handling strings. The syntax is difficult to master but it allows you to do some amazing things with very little code.

I reposted ViziaTester.zip (above) with a corrected version of the zWave class. The XDO should import cleanly.

1. I'll have a look at FindDevice and let you know.

2. The sysEvent object will definitely not support this: "sysevent.method.FindDevice.DiscoveringInstance" . If you need the last state of something, you have to save it somewhere.

ADDENDUM
I had a look at FindDevice and I recognize that you're emulating the Discovery process Damon created in his native driver. If you check his code you'll see that he is storing values in global properties of the ViziaRf class like "m_bInDiscoveryMode", "m_iCurrentAddress", "m_iDiscoveryType", etc. In a Module a class property is effectively a global variable. By making it hidden, as you've done, you avoid exposing it in the ViziaRf object's user-interface. It's all good.

I looked at AddDevice and, I may be wrong, but it doesn't look like the best way to handle additions. Correct me if I'm wrong but if a discovered object (Switch or Dimmer) does not already exist (i.e. as a child) then it will be created. However, if it does exist, it will be deleted and re-created. Won't deleting the existing object destroy any existing bindings? Imagine you have 25 Dimmer and Switch objects, all are bound to Home-level objects, and then you click "DiscoverNodes" . Poof! All of the objects and their bindings are deleted and you'll have to re-bind everything after Discovery is completed. Ouch! Perhaps if a discovered object has a matching child object then the child should be left alone?
 
AddDevice shouldn't do that. The only time I thought it deletes children is if the new node type doesn't match the old. In other words, if I replace a dimmer with a switch, but kept the same node ID I need to make the dimmer a switch in premise. This is necessary since the vizia rf+ handheld controller can let you switch out devices, keeping the node id the same.

RemExcludedNodes removes nodes that are no longer included and does delete the associated objects.

I'm 99% sure I have this right, but please let me know if i don't :huh:
 
And right you are! I stand corrected. It'll delete the child object only if it isn't the right class. Of course, the binding will still be lost. Here's another way to handle the situation: instead of deleting the child object, change its class.

If you've used X10 devices in Premise you will have encountered X10 objects whose underlying class can be changed from Dimmer, to Switch, to MotionSensor, to whatever. Have a look at this post regarding the Transformable flag.

Basically, all child objects would be based on a "zWaveDevice" class whose inheritance can be altered from Dimmer to Switch (the child would have to be deleted if it had to transform to a Thermostat!). It's a litle tricky to set up but the benefit is that AddDevice wouldn't delete a mis-matched child object but simply alter its class.

Food for thought.
 
I'll have to study the transformable flag as this sounds neat. I've incorporated your version 1 code. I haven't looked at version 2, but I guess it just deleted the dimmer and switch containers?

Your code works great and is very clean, thanks! I have one question, what does the "d" mean below in the vizia rf 232 documentation?

2.1.7. Send Command (“SEndâ€)
To provide control to the nodes which function a bit different than lighting control nodes the send
command can be used. This command sends over RF, all Z-wave command, the node will send the
message as before defined by any of the association commands:
N, AP, GR.
Example:
N5SE69,2 - Will request thermostat fan state from thermostat node 5.
2.1.8. NN and NL - Node name and location commands.
NN (NL) provides access to programming/recalling node name (node location name).
>NxxxNNdyyy…yyy
>NxxxNLdyyy… yyy

where xxx- node ID
yyy..yyy ASCII string up to 16 characters
To request previously programmed name use >?NN or >?NL
The name returns in format: <Nxxxâ€yyyyyyy
 

Attachments

  • leviton_beta_v4.zip
    7.7 KB · Views: 15
I found the answer in this PDF at the bottom of the third page. The "d" represents "Character Set" and the document recommends using "1" (Extended ASCII).

I recommend you have a look at the following post in zWaveWorld. It contains invaluable information about how things really work as opposed to what the documentation says. Apparently there is an undocumented response (<M000) after issuing a Group Set command (>GS). The gViziaParser function will simply return a zero ("Unknown Packet") if it encounters the "<M" command.

BTW, here's a source of information about the Z-Wave API.
 
I was able to add naming and a built in timer for polling. I'm hoping someone with non vizia rf lights will try the polling feature and report back on the polling function.

However, if I use the automation browser to change a lights brightness property, the light doesn't update until I let go of the up or down button. Is there a way to fix this so that as you hold down the up/down buttons the light continually dims? It appears it is due to the way the onChange property works for brightness, but I thought I'd ask anyway.
 

Attachments

  • leviton_beta_v5.zip
    8.8 KB · Views: 19
...if I use the automation browser to change a lights brightness property, the light doesn't update until I let go of the up or down button. ..
That's by design. After you release the button, Premise transmits the desired brightness level to the lighting device. To have the brightness change while you are pressing the button, Premise would have to transmit a continuous stream of commands to the lighting device. This is not a practical proposition when it comes to PLC lighting technologies.

I've been working on the transformable classes (i.e. convert an existing Switch object into a Dimmer and vice-versa) and on Groups.

The inheritance hierarchy for lights looks like this:
Device (Base Class for all zWave devices)
Lighting (Base class for all zWave lights)
Switch (Inherits from Device, Lighting, and Premise's Power class)
Dimmer (Inherits from Switch and Premise's Dimmer class)

I've defined Device to be Transformable so it can be changed to whatever is needed ... from Switch to Dimmer and back to Switch (or even a Thermostat!). The transformation can be performed by the end-user, using Builder, or it can be done programmatically. The attached zWave2.xdo contains an example of transformation. Import it and it will also create a zWave object in Devices > CustomDevices and in its Devices container you'll find two properties:
  1. SwitchesToDimmers
  2. DimmersToSwitches
If you click the first one, it will convert all Switches in the Devices container into Dimmers. Now that's a completely useless feature that should never make into the final release but it demonstrates how easily transformation can be accomplished. Here's how it's done:
Code:
	for each oDevice in this.GetObjectsByType(Schema.Modules.zWave.Classes.Switch.Path, false)
		set oDevice.Class = Schema.Modules.zWave.Classes.Dimmer ' <-- This is the line that does the magic.
	next

Add a few Dimmers, Switches and Thermostats into the Devices container. You'll notice that the driver creates an "AllLights" group and automatically populates it with all of the Lighting Devices you created in the Devices container. The AllLights group cannot be deleted and its members cannot be renamed nor deleted.

If you right-click the Groups container, you can create a new Group. Name it what you wish then right-click it and add new GroupMembers. Within the GroupMember, click Device and select an existing Device. That's how you build your own groups of devices.

If you change the name of a Device (in the Devices container), its name in AllLights will update automatically. If you delete the Device, it will be automatically removed from AllLights. The auto-renaming and deletion also applies to any Groups you created manually.

Now here's the fun part, if you inspect a Group you'll find it contains PowerState and Brightness properties. If you enable PowerState, it will compose a command to turn on all lights in that Group. OK, that's not fully functional yet, but it does build a list of Device addresses (and prints them to the Debug Console).

A script can turn on all the lights using the following command:
Code:
Devices.CustomDevices.zWave.Groups.AllLights.Powerstate = true

I have a few more ideas about Groups (that may involve the ViziaRF's group commands) but its almost 2:00 AM and its time to call it a day! I think I can incorporate Groups into your driver after you've finished testing all of the core functionality (I don't have any Z-Wave equipment).

BTW, I reviewed CQC's Z-Wave driver and learned there's another possible response command: "<!000". That makes two more commands to add to gViziaParser (the other is "<M000"). I'll take care of that next week.
 

Attachments

  • zwave.png
    zwave.png
    13.3 KB · Views: 16
  • zwave2.zip
    9.8 KB · Views: 23
Everything in Beta 5 works very well except polling. I finally made it home last night and tested everything and posted beta 5.

Some thoughts: Polling works better if you poll one device at a time. I would get X002 a lot if I polled everything at once. I ended up setting the timing at 100ms and this helped some. This seemed to get rid of the X002 error most of the time, but ~1/7 polls still receive an X002 from one random device. This really only happens on polling.

However, the thread link to suggests a very good idea: use command acknowledgement and send the next command only after receiving X000. This would entail breaking all commands down to handle each device one at a time and would use a global variable (or equivalent) called
nextNode. There would also need to be a way to track what the last method called was and recall it if necessary (I'm not sure how to do this). If X002 is received the method would be recalled and after 10 failed attempts in a role a comunications error set. Obviously, this would also require the use of manualAck that I couldn't figure out how to use manual ack.
 
Back
Top