Premise Z-Wave Status using RZCOP/VRCOP help

Motorola Premise
I just spotted the variables found under JobQueue. My math was off by a factor of 60 earlier... Doh!

The way I previously read the statement below is that the rs232 controller needs to see ",UP" to ask the lights to broadcast their updated state over the zwave network so that all controllers will update. I know if ",UP" is not present in an action command, I don't see a response from the device (ie no <N014S000,000,000). However, if it is the controller sending the updated status to all other controllers and not the device responding the update request, why does it look like data is received from the device when using ",UP" (ie <N014S000,000,000). You are right though, this seems to conflict with the description in the documentation so I might just be confused :(

I haven't seen anything that says non-vizia devices will not respond to the "UP" command. I'll run this test when I get back in a few weeks. All I've seen stated is that third party devices will not offer two way control (which is an entirely different issue).

...the driver assumes all group members will respond to the ",UP" portion of the command (ie is a vizia rf product) which may not always be true.
That is not my understanding of the "UP" command's purpose. The documentation indicates "UP" should be appended to all 'action' statements and its purpose is as follows:
After any command where changing the level or state of the load was sent, the sending node is
responsible for updating information for all other controllers controlling the same nodes.

My interpretation is that these 'other controllers' need not be from Leviton and must be informed of any state-changes to the nodes they control.
 
123, a quick question about some code from your driver... Should the lights really not actuate if srcProperty.Name is a trigger? I use the X10 palm pads almost exclusively to turn the zwave lights on/off. It appears you added this in case a future version of the driver were to include one of the 4 button zwave controllers?

Code:
dim sCmd

if this.ReceivingUpdate = false then
	' Ignore requests from Brightness changes because OnChangeBrightness will handle 
	' the task of turning a dimmer on or off.
	' Also ignore requests from objects with a Trigger property (used in SmartPalmPad)
	if sysevent.srcProperty.name <> "Brightness" and sysevent.srcProperty.name <> "Trigger" then
		sCmd = ">N" & this.NodeID
	
		if this.PowerState = true then
			sCmd = sCmd & "ON,UP"
		else
			sCmd = sCmd & "OF,UP"
		end if
	
		this.Parent.Parent.SendCommand sCmd
	end if
end if

If I replace the code above with this, my palm pad works again...

Code:
'
dim sCmd

if this.ReceivingUpdate = false then
	' Ignore requests from Brightness changes because OnChangeBrightness will handle 
	' the task of turning a dimmer on or off.
	' Also ignore requests from objects with a Trigger property (used in SmartPalmPad)
	if sysevent.srcProperty.name <> "Brightness" then

		sCmd = ">N" & this.NodeID
	
		if this.PowerState = true then
			sCmd = sCmd & "ON,UP"
		else
			sCmd = sCmd & "OF,UP"
		end if
	
		this.Parent.Parent.SendCommand sCmd
	end if
end if
 
Your explanation, and observation, of how "UP" operates makes a lot of sense. It'll be interesting to see if all Z-Wave devices respond with their status upon receipt of an "UP".

The need to exclude commands sourced by the "Trigger" property came from the ELK M1 driver's handling of lighting devices. It was needed there in order to prevent double-processing (i.e. similar to the "ReceivingUpdate" flag). Yet, you've experienced that it suppresses all Trigger-related requests! I'll remove that code but I plan to look into why it doesn't work correctly.
I just finished testing it, with the Trigger exclusion-code left intact, and the driver works correctly for me. Although I don't have an RZC0P interface, I can see, in DebugView, an ">N1ON,UP" command is transmitted.

Try this:
  1. Put the Trigger exclusion-code back into OnChangePowerstate.
  2. Add the following debugout line into OnChangePowerstate
Code:
if this.ReceivingUpdate = false then
	debugout "SourceElementName: " & sysevent.srcElement.Name & ", SourcePropertyName: " & sysevent.srcProperty.name
Now operate a bound light from the Home level, the SmartPalmPad, and Premise Browser. Observe the results in DebugView. Here's what I get for a light called "MyLight" at the Home-level and bound to a light called "Spotlights" in the ViziaRF driver:

Code:
Result of turning MyLight on via Builder:
SourceElementName: Spotlights, SourcePropertyName: PowerState

Result of turning MyLight on via the SmartPalmPad:
SourceElementName: Button1ON, SourcePropertyName: ButtonState

Result of turning MyLight on via its Premise Browser user-interface:
SourceElementName: RoomLighting, SourcePropertyName: TogglePower

Notice that, in all cases, the SourcePropertyName is never "Trigger" and so the request is never ignored by the driver. Let me know the results of the same tests performed on your PC. I'd like to see what is the source of the "Trigger" property in your case.


I've added all the code needed to handle thermostats. The supported features include:
  • Heating/Cooling Setpoints
  • Current Setpoint
  • Fan Control and Status
  • Temperature Mode and Heating Status (a.k.a. HVAC Operating Mode and current HVAC State)
The only properties I have not implemented are "UserHold" and the setpoint "Mode". When you get a thermostat, we'll figure out the best way to handle them.

I'll try to add support for Motion Detectors before releasing the next version.
I take that back. I had a look at Karl Denninger's work and it's clear to me that, without a PIR in hand, my efforts would be a complete 'shot in the dark'. I'll leave this task for someone who owns a Z-Wave PIR.
 
Apparently I can't get debugview to work remotely (not using debugview on the machine running SYS). Attached is a jpeg of what the interpreter shows after reaching a stop point.

My code for one of the buttons looks like this:
Button4On.ScriptMacro:
Code:
home.Master.TableLamp1.PowerState = false

EDIT: Additional Information that may help: I have the MR26a hooked up to a GC100-12. This is the only odd configuration I think I have... I'm also running SYS on windows 7.
 

Attachments

  • sourceName.JPG
    sourceName.JPG
    44.5 KB · Views: 20
Tell me about the bindings. What is the TableLamp1 bound to? Is Button4ON bound to the HR12A or to something else?

OK, I see it now. Activating Button4On causes the execution of the ScriptMacro which turns off TableLamp1. TableLamp1 is bound to the driver. The driver sees Button4On as the source Element and Trigger as the source Property. As it stands, the driver will reject this request.

I can no longer recall why the ELK M1 needed to reject requests sourced by the Trigger property. However, it appears to be necessary to allow it in the Viziarf Driver. I'll remove the Trigger-rejection-code in the next release.


BTW
I've added Job Prioritization in the new version.
  • All user-requested commands are high-priority.
  • All polling requests are low-priority.
High-priority jobs are processed before low-priority jobs. So if the queue is filled with low-priority polling jobs and you turn on a light in Premise, your request is the last job in the queue. However, it will be executed first because it has a higher priority. This prevents having to wait for all the polling requests to finish before the desired light turns on.


Another benefit of adopting job prioritization, is how it helps to avoid "over-polling". Let's assume PollingInterval is set to 20 seconds. However, it actually takes longer than 20 seconds to poll the entire Z-Wave network. That means the next polling cycle will start before the first one is finished! The job queue will grow with each polling cycle and fail to ever clear out its backlog of jobs.

The solution to prevent over-polling is simple (now that we have job prioritization). At the beginning of each polling cycle, the driver checks if there are any low-priority jobs in the queue (all Polling-related jobs are tagged as low-priority). If there are, then it means that the previous polling cycle is still underway and needs more time to finish. So the driver simply skips a polling cycle.

Theoretically, the driver could automatically increase the PollingInterval if it finds itself skipping cycles far too often. How cool is that!

Last of all, I've added support for Scenes. However, I've discovered that Scenes are a unique feature of Leviton-brand dimmers so this feature is not as inclusive as Groups. The one thing I could not figure out is a Scene's Fade Rate. The documentation indicates 255 represents the default fade rate but it doesn't provide the range of valid values nor what a fade rate of "60" means (i.e. does it mean fading over a period of 60 seconds?).
 
Job priority is a great idea, and this idea about over polling is ingenious!

I was able to find this statement about vizia rf+:
Advanced Features
Energy save mode
Minimum brightness adjustment
Preset ON level
Preset OFF level (Vizia + only)
49 adjustable fade rates
Restore factory defaults

I have also read on the avs forum that vizia rf (not + ) only supported 7 fade rates (not sure this is true I think the user was confused about the limitations of programming a fade rate using the dimmer itself (after all there is only so much you can do with an up/down button and 7 led lights!). An rs232 controller obviously would not have the same limitations for setting the fade rate.

I then found in the attached dimmer instructions that the default fade rate is .5 seconds. This would mean to me that 0 is no fade rate, 255 is default, and in between is a variable fade rate that is linear from .5 seconds to 25 seconds (the table in the attached dimmer instructions may clear this up I think). I'm not sure about this and I'm not home to test this theory.

I can try to get Leviton tech support to email engineering this question though. They are not open until Monday :rockon: If you haven't looked there already, a great place to look would be in Damon's driver as I believe it had a fadeRate property on each dimmer.

Last of all, I've added support for Scenes. However, I've discovered that Scenes are a unique feature of Leviton-brand dimmers so this feature is not as inclusive as Groups. The one thing I could not figure out is a Scene's Fade Rate. The documentation indicates 255 represents the default fade rate but it doesn't provide the range of valid values nor what a fade rate of "60" means (i.e. does it mean fading over a period of 60 seconds?).

EDIT PDF is too large, try this link: http://www.leviton.com/OA_HTML/ibcGetAttac...amp;appName=IBE
 

Attachments

  • fade_rates.JPG
    fade_rates.JPG
    31.9 KB · Views: 13
..I was able to find this statement about vizia rf+:
...
Preset ON level
Preset OFF level (Vizia + only)
49 adjustable fade rates
....
... This would mean to me that 0 is no fade rate, 255 is default, and in between is a variable fade rate that is linear from .5 seconds to 25 seconds ... a great place to look would be in Damon's driver as I believe it had a fadeRate property on each dimmer.
I haven't seen anything in Leviton's RS232 protocol that supports Preset ON or OFF. Either they didn't bother to make that feature controllable via an RZC0P or they overlooked to document it.

I've seen the fade-rate table but it doesn't indicate what value should be used with the ">N S" command. Damon's code has a single comment indicating the fade rate can vary from 0-99 but what that means is unclear. Also, his code simply takes the received scene number and puts it in the Light's Description property ... I guess for informational purposes only. Beyond that, there's nothing else that supports Scenes.

Some experimentation will be needed to determine how the driver should handle the fade-rate property.

Let me know when you get back and I'll post the latest, greatest version. Until then, I'll tinker with it and try to add the "auto-adjusting PollingInterval" feature.
 
Attached is BETA 0.9.3 and it includes features that make Polling and Discovery more robust.

  • Job Priority
    Both Polling and Discovery generate Low-Priority Jobs. All other activities (initiated manually or programmatically) will generate High-Priority Jobs.
  • Auto-correcting Polling Interval
    Before a polling cycle begins, it confirms the previous polling cycle has completed. If it finds any Low-Priority Jobs in the queue, it concludes the last polling cycle is still underway, skips the current polling cycle, and automatically extends PollingInterval by 5 seconds.
  • Discovery and Polling cannot overlap.
    When Discovery begins, it purges all Low-Priority Jobs from the queue. In effect, it eliminates pending Polling jobs.
    When a new Polling cycle begins, it will skip its cycle if Discovery is underway.
  • Housekeeping for Discovery and Polling.
    If you disable Discovery or Polling while they are underway, they will purge their pending jobs from the queue.
This version also supports Scenes. Whereas a Group is a collection of Devices that is programmed into the RZC0P/VRC0P, a Scene is a lighting level programmed into a Device. If you request Group 10 to turn on, all members of the Group will turn on. If you play Scene 25, all members will change to whatever lighting level has been assigned to them. Scenes are a feature of Leviton ViziaRF+ devices so there's no value including a non-Leviton lighting device in a Scene.

To create a Scene:
  1. Right-click Scenes and select New > Scene.
  2. If you wish, rename "Scene" to something more meaningful ("WakeUp").
  3. Right-click "WakeUp" and select New > SceneMember
  4. Click the Device property and select a Device ("TableLamp").
  5. Set TableLamp's PowerState or Brightness.
  6. Create additional SceneMembers by repeating the last three steps.
  7. After you've defined all SceneMembers, click "WakeUp" and assign a SceneID (1-255).
  8. Click "SetSceneID" to program all Devices.
Here's how to activate a Scene in scripting:
Code:
Devices.CustomDevices.ViziaRF.Scenes.WakeUp.Play = true
 

Attachments

  • Leviton_BETA_9_3.zip
    37.1 KB · Views: 14
  • SceneMember.png
    SceneMember.png
    17.5 KB · Views: 17
Wow, 4 downloads already? It looks like you've attracted an audience by including scenes ;) I have attached your test results from the last version. I dd have polling enabled for a few days with 20 second intervals, but I didn't leave it on the entire time like I should have...
 

Attachments

  • test_results.JPG
    test_results.JPG
    22 KB · Views: 12
I don't know why, but sending >N2,17,26PS001 instead of >N2PS001, >N17PS001 and >N26PS001 seems to have fixed a non responsive problem I was having. Your code was correct given the documentation, but ???

Requesting a scene like this seems to get rid of the other issue shown in the jpeg. Using the command below, only lights actually found under the scene container will actuate: >N1,2,3S1,255. Note that even if node 4 had scene 1 stored, it would not actuate.

To date, I have only modified the following:

1. Added a text property to Scene call Members.
2. Modified OnChangePlay:

Code:
'
if sysevent.newVal and this.SceneID > 0 then ' Play scene with default FadeRate
	this.Parent.Parent.SendCommand ">N" & this.Members & "S" & this.SceneID & ",255" & ",UP", true
end if

3. OnChangeSetID:

Code:
'
dim oMember, oDevice
dim sCmd: sCmd = "ON,UP"
dim bFirst: bFirst = true
dim sDelimiter: sDelimiter = ""
this.Members = ""

' Get all group members
for each oMember in this.GetObjectsByType(Schema.Modules.Leviton.Classes.SceneMember.Path, false)
	set oDevice = oMember.Device
	if oDevice.IsOfExplicitType(Schema.Modules.Leviton.Classes.Dimmer.Path) then ' Dimmer
		this.Parent.Parent.SendCommand ">N" & oDevice.NodeID & "L" & this.ConvertBrightness(oMember.Brightness) & ",UP", true
	else ' Switch
		if oMember.PowerState = false then sCmd = "OF,UP"
		this.Parent.Parent.SendCommand ">N" & oDevice.NodeID & sCmd, true
	end if
	if not bFirst then sDelimiter = ","
	this.Members = this.Members & sDelimiter & oDevice.NodeID
	bFirst = false
	this.Programmed = now
next
this.Parent.Parent.SendCommand ">N" & this.Members & "PS" & this.SceneID & ",255", true  ' TODO --> Replace 255 with oMember.FadeRate
 

Attachments

  • node_17_is_not_in_the_scenes_folder_but_is_responding.JPG
    node_17_is_not_in_the_scenes_folder_but_is_responding.JPG
    25.7 KB · Views: 13
  • Leviton_Beta9_6_SUN_EVE.zip
    37.2 KB · Views: 9
Ok, so I meant to hit reply ealier instead of editing the post above. As an FYI, I have uploaded a newer version to the post above.

EDIT: I forgot to mention that I called Leviton about the fade rate question. The engineer who worked on the RS232 controller is out and there is a fill in this week, but the tech support person promised to get in touch with engineering and will email me the answer (may take a week though).
 
DOH!

When I saw the driver's name "Leviton SUN EVE" I realized I either posted the wrong version or, less likely, you use the exact same file-naming scheme as I do! I posted the version I created Sunday Evening and that is not the latest one. The attached file contains the latest version (BETA 9-5).
The results of the Scene tests you've performed are both enlightening and disappointing.

If this works (one command containing a list of all scene members):
>N2,17,26PS1

... and this does not work (one command per scene member):
>N2PS1
>N17PS1
>N26PS1


... it implies that one cannot append a device to an existing scene! To add one device, you have to reprogram all members of the scene. From a technical perspective, it is not an elegant technique.


Once the scene is programmed using something like ">N2,17,26PS1", one should be able to play the scene using ">S1,255". This was explained to me by a zwaveworld member. In other words, it shouldn't be necessary to list all of the scene members using ">N2,17,26S1,255" unless one wants to activate a subset of the scene's members (i.e. activate scene 1 for devices 2 and 26 but not 17: ">N2,26S1,255").

If you can confirm that ">S1,255" does work, then the driver will not need a "Members" property.
 

Attachments

  • Leviton_BETA_9_5.zip
    37.4 KB · Views: 11
Ok, I have some more testing to do tonight. I can confirm that one of these issues does not work as the documentation says. It sounds like I need to isolate the two code changes and see what code change is actually needed. I know one of them will be needed because only one device was responding to >S1,255 last night. If I had to guess >S1,255 is the problem...

>S1,255
I don't know if it was clear in the jpeg I posted, but >S1,255 has a hiddne issue: there maybe other scene members not shown under the scene container that actuate and this could be very confusing. For example say I program node 5 to be off for scene one using a handheld controller or perhaps I've deleted it from the scenes container in Premise, then reprogrammed the scene. I then create a new scene (or reprogram the existing with node 5 deleted) using Builder and only include 1,2,3 in the scene. Sending >S1,255 will cause node 5 to actuate in addition to nodes 1,2,3. This problem would go away if I knew how to delete a scene from node 5, but there is not a command for that from what I've read? Sending N1,2,3S1,255 would get rid of this altogether, but clearly it is not good to leave node 5 with a programmed scene you nolonger want. I think >S1,255 is fine as long as there is a way to delete the scene upon an objects removal from the scene container and the user never uses the handheld controller to program a scene.

>N1PS1,255
You are right, sending code to append the scene one at a time should work 100% and it wouldn't make sense if this didn't work. I'm going to try keeping the change for >N1,2,3S1,255 and putting your code back for PS. Honestly, I think I was trying to change too many parts at once to get all the lights to respond to a scene last night :( It's also hard to debug the lights without actually being in the home too ;), but I can use a linksys wireless camera to see what the lights were doing in one room atleast. I'm not sure if the newer version does this, but any time a scene is programmed, an ",UP" should be put in to update the other controllers on the network too.
 
...>S1,255 has a hiddne issue: there maybe other scene members not shown under the scene container that actuate
That's very true. If a scene is programmed using a handheld controller, the driver has no knowledge of this action.

>S1,255 tells all scene 1 devices to play their programming, even if some of them were programmed with the controller and not the driver. I suspect the controller must have a way of removing a device from a scene ... however, the ViziaRF protocol doesn't document the command.

The safest technique would be to avoid using >S1,255 and use the >N2,17,26S1,255 format where all scene members are identified in an association list. It seems silly to have to do it this way but it would avoid the situation described above. I don't care for it because (without any real evidence) I think S1,255 must be a more efficient transmission than >N2,17,25S1,255.


Your comment about deleting scene members made me discover a problem with the "Members" property ... it gets built each time SetSceneID is triggered but it never gets modified when a scene member is removed! I've changed the code (posted as BETA 9-5 above) so that Members is no longer required and I've added a GetAllSceneMembers method. This method is called wherever there's a need for an association list of all scene members.
 
I think I have answer the >S1,255,UP question. Please view the attached text file. I have sent several manual commands using OutCmd until I could figure out how the hardware is processing >S1,255,UP.

>S1,255,UP will only trigger Scene 1 for the very last node that was previously sent a full command in the format NxxxSxxx or NxxxLxxx. I have validated this several times as the pattern in the text file will show. This is the full cut/paste from port spy. I did not spice it at all.

Now I will independently test sending NxxxPSxxx one node at a time and post this in a separate post. I believe this must work and that my confusion before was in that I didn't catch the S1,255,UP pattern that is attached.

Reading this version of the Vizia RF documentation points to how not listing a node will behave as described above. This short-hand method is perfectly acceptable as long as the node from the last command was sent to is known somehow.

D. Dimmer control
Assume dimmer node is node 8.
>?N8 <- Request dimmer level
<E000 <- Request processed
<X000 <- Request has been sent
<N008L100 <- Received dimmer’s response, current level 100%
>L50UP <- Set light level at 50% and request update
<E000 <- Request processed
<X000 <- Request has been sent
<N008L050 <- Node 8 sends back it current level as result of update. Nothing will be
sent back if update wasn’t requested.

I don't know if this confuses things more, but there are a few examples from the vizia rf+ documentation and one of them does not work!?!:
"After programming a scene using the Program Scene command use the scene command to call a scene. (Example >S2ON)"
">N1,10,23S2,255 Call scene 2 with default fade rate for nodes above"

Now, the format >S2ON, doesn't seem to work for me??? See below.
>S1ON
>S1ON
<E004
<X000
>S1ON,UP
>S1ON,UP
<E004
<X000
>S1ON,255,UP
>S1ON,255,UP
<E004
<X000

Note: I'm not using the RF+ controller and this maybe why....?

PS: I'm still looking over your driver. I like how you have eliminated the Members text property, that was a very good catch 123! I didn't even think of how the deletion case would impact the Members property ;)
 

Attachments

  • test_results_for_S1_255.txt
    1.4 KB · Views: 12
Back
Top