Premise Z-Wave Status using RZCOP/VRCOP help

Motorola Premise
Resetting the port after a failed command is overkill. I wrote the code before reading your earlier response on what the proper way to implement a port reset is... For the timer I would delete the code I've added, but append any timers with this.ObjectID incase a user potentially has two RZC0P's.

The code looks good, I'm just getting one error: a missing dim for bIsDimmer: bIsDimmer = false under setLightLevel

EDIT: I just read what a colon operator can do. I had no idea you could have two lines of code on the same line. That's the only error and you didn't even run the code?!? I wish I could do that!

PS: Is there an advantage to using dim? I thought it wasn't required for vbscript. Also you seemed to have solved the mystery on why transmitted commands show up twice in portspy! Many thanks.
 
... I just read what a colon operator can do. I had no idea you could have two lines of code on the same line. ...
I've found it useful when defining a Timer's payload (i.e its "ScriptToRun" parameter). In this example, the colon allows me to define two statements in the Timer's payload, there's an "on error resume next" followed by a "this.OnWatchDogTimer".
system.addTimer this.WatchdogInterval, "on error resume next: this.OnWatchdogTimer", 1, this.GetWatchdogTimerName

BTW, this example resolves the following issue:
  • You create some sort of custom Home object that has an associated timer that runs "this.DoSomething".
  • Then you delete the Home object.
  • The timer expires and attempts to execute "this.DoSomething".
  • Unfortunately "this" was the Home object and no longer exists!
  • The Timer fails to execute "this.DoSomething" and the VBScript interpreter halts at the offending code.
  • By adding "On Error Resume Next" as the first line, the VBScript interpreter skips over "this.DoSomething" (i.e. ignores the error) and continues without interruption.
------------------------------------------------------------------------

I've revised the JobQueue class and now it can retry a failed Job. Basically each Job has a "Reps" property indicating how many times it ran (i.e. Repetitions). The JobQueue class has a "MaxReps" property which indicates the maximum number of times a Job can be repeated. MaxReps's default value is 3 so each Job can be run three times before it is discarded and the next Job in the queue is executed.

I believe if the driver fails to successfully transmit 2 consecutive Jobs (that's 2 Jobs x 3 repetitions per Job = 6 consecutive failed commands) that it'd be safe to conclude there's a communications problem and the driver should set the CommunicationFailure flag. If the next Job completes successfully, it will clear the CommunicationFailure flag. Does that sound reasonable?

If you've modified version 8-1, please post the revised version so I can proceed to add the improved JobQueue class.
 
123, the only thing I've added is the missing "dim" and I removed the reset port code from the job timeout. Other than that I have not changed anything and have no new version to offer. Your code works good.

Using the ":" operator to resume if a timer errors is clever. I've had timers give me an error in the past and halt execution. This is a great idea!

I double checked all possible cases through port spy I could think of: manual dimming/switching, automation browser dimming/switching etc... Naming, discovery etc also all work perfectly and I set the device for 1 minute polls to see what the error count would be after a day or two. The previous test with 2 minute polling showed ~1/6000 errors!

This driver is turning out to be a very useful framework for anyone wanting to make their own rs232 lighting driver ;)
 
I've been thinking about a way to optimize polling.

ViziaRF devices do not need to be polled because, when operated manually, they can broadcast their new state. The Polling function can safely skip them. All that's needed is a way of knowing which Devices don't need polling.

If the Device class had a property called "RequiresPolling", the end-user can set this property for each non-ViziaRF Device. When the Polling function builds its list of Devices to poll, it would filter it using 'RequiresPolling = true'. The Polling function wouldn't waste its time querying a Device that can automatically report its state.

---------------------------------------------------------------------------------

I think there's a line of code in OnChangeOnNewState that should be removed. It's the first call to GetNextJob.

Code:
			case 1:	' Error Status (<E)
				sMsg = "Error Status: " &  aParms(0)
				this.Jobs.GetNextJob
				if aParms(0) = 10 then
					this.Jobs.GetNextJob
					if this.DiscoveringType = 16 then
						this.DiscoveringType = 17
						this.DiscoveringInstance = 1
						this.FindDevice
						...
When OnChangeOnNewState receives an Error State "<E" response, the first thing it does is GetNextJob. Then it checks if the Error State = 10. Then it does a GetNextJob again. That doesn't sound right ... two GetNextJobs are being called one after the other.

I'm going to add code that looks like this:
Code:
			case 1:	' Error Status (<E)
				sMsg = "Error Status: " &  aParms(0)

				select case aParms(0)
					case 0: ' Good response
						this.Jobs.GetNextJob

					case 1,2,3,4,5,6,7,8,9: ' Bad response
						this.Jobs.RetryJob

					case 10: ' Discovery
						this.Jobs.GetNextJob
						if this.DiscoveringType = 16 then
							this.DiscoveringType = 17
							this.DiscoveringInstance = 1
							this.FindDevice
							...
				end select

What do you think?
 
These sound like great ideas to me!

So, when I came home today after running the polls for one minute for ~24 hours, my serial port does not seem to work unless I click reset or do a manually delete/re-add. Port spy also shows no data being rx or tx. Your new driver did make it to 1 errors/5954 commands!

This is exactly the same issue I had sending the betabright updates every minute if you remember; after 5-6 hours the betabrite would stop receiving data. For the betabrite I ended up making a reset timer that triggers every 2 hours (pretty basic).

Is there some new security feature to vista and windows 7 that could be causing this? This issue makes me want to add the reset port timer back ;) Personally, I think after x number of job retry's the driver should try to reset the serial port at least once, then retry the job again. Periodically polling for a predefined resonse would also work too.

Having three devices now that have this issue, I'm really curious if anyone running vista uses a custom serial driver that polls every minute and doesn't stop working (obviously the driver must not do the automatic port reset for the test)?
 
...after running the polls for one minute for ~24 hours, my serial port does not seem to work unless I click reset ...the same issue I had sending the betabright updates every minute ...Having three devices now that have this issue...
I've never experienced that problem. However, my (serial) drivers are native as opposed to Module-based and my server runs Win XP.

Premise has a long history of Module-based drivers that communicate via a serial-port. You're the first to report this problem so it may be due to, as you've pointed out, the operating system.

What would be interesting is to determine if all three drivers fail at approximately the same time or after the same polling count. Try modifying your drivers so that they record the Date, Time, and a running count each time they communicate via the serial-port. Start them at the same time and then see if they all fail at the same time (or after the same count). Failing at the same time implies some sort of external event that affects all ports. Failing after the same count might indicate a buffering issue (maybe). This isn't a solution but it might shed light on the cause.

------------------------------------------------

I've completely overhauled the ViziaRF driver. I'll list the new features when I release it to you for testing. I'll also add the ability to reset the serial-port after two consecutive Job failures.
 
What would be interesting is to determine if all three drivers fail at approximately the same time or after the same polling count. Try modifying your drivers so that they record the Date, Time, and a running count each time they communicate via the serial-port.

This is a heck of an idea! I'll have to try recorded date and time :) It could also be a hardware issue for all I know too... I use a complicated setup involving several networked digi serial controllers distributed throughout the house.

Failing at the same time implies some sort of external event that affects all ports.

Failing after the same count might indicate a buffering issue (maybe).

From the tests I ran last night with 5 seond intervales, the serial port stop rx/tx stops after 12000+ sends. This is very different from the numbers I got using 1 minute intervals which were ~5954.

I've completely overhauled the ViziaRF driver. I'll list the new features when I release it to you for testing. I'll also add the ability to reset the serial-port after two consecutive Job failures.

Many thanks for help on this 123! Your willingness to help teach me and contribute was very kind, especially since you don't use the RZC0P! An open driver like this that's easy to modify will be a great tutorial for future newbie's too. Who know's, maybe someone will create a W800RF32 driver based on your work.
 
I've gone over the driver's code with a fine-tooth comb and found the following error in OnChangeOnNewData:
Code:
			case 2: ' Transmission Status (<X)
				sMsg = "Transmission Status: " & aParms(0)
				if aParms(0) = 2 then
					this.errorCount = errorCount + 1
				end if
this.errorCount = errorCount +1 is a mistake. The righthand side of the statement should be this.errorCount +1. As it stands, the VBScript interpreter treats "errorCount" as a new, undefined variable. Because it is being added to an integer, "errorCount" is also treated as an integer. Because it is undefined, its value is 0. All of this results in "this.errorCount" having a permanent value of 0 + 1 = 1. Sadly, this coding glitch may be responsible for the ultra-low error rates you reported.

The next version will have counters for all Jobs, repeated Jobs, failed Jobs, Transmission errors, etc.
 
Sorry, I can't believe I did that :) Error count or not, the two way communication works darn good. I turned one switch on/off manually about 50 times and the automation browser updated with in two seconds for each manual action.

The bad thing about vbscript is you don't have to define variables properly so a typo can be hard to spot... Is there a way to force the interpreter into requiring variables be defined?
 
... Is there a way to force the interpreter into requiring variables be defined?
Not that I know of.
I define all the variables I need up front and initialize them if needed:
  • dim iIndex: iIndex = 1
  • dim bState: bState = true
  • dim bIsWidget
  • dim oWidget
...use them in the code and then purge all objects at the very end:
  • set oWidget = nothing
This practice doesn't eliminate problems but it helps to reduce them. I also prepend a single character to the variable's name to remind me its intended type (i=integer, b=boolean, a=array, o=object, s=string, etc).

This practice is unnecessary with VBScript because all variables are of type Variant (Variant can hold integers, strings, booleans, etc) and can be defined at the moment of usage. The VBScript interpreter determines (a.k.a "casts") the appropriate variable type (integer, string, object, boolean, etc) at the moment of usage. It's all very casual and user-friendly ("loosely typed as opposed to a strongly typed language) so that's why you don't have to define variables and can combine string and integer variables (i.e. "The count is: " & iIndex) without having to explicitly convert the integer to a string. But this can also get you into trouble such as with "this.errorCount = errorCount + 1".
 
etc6849,

Well, I'm passing the baton back to you. There's a lot of testing to do ...

Attached is Beta 0.9.1 and it is substantially different from the previous version. Without access to an RZC0P interface, there's only so much testing I can perform so this version will probably have several bugs.

Installation
Backup the current Leviton driver, delete it, and import the new Leviton driver (Beta 0.9.1). Do not import the new one over the old one!

Here's a summary of Beta 0.9.1:

Job Processing
  • If a transmitted command (i.e. a "job") is not acknowledged (i.e. receives a "<E000" within 5 seconds) the driver will transmit it again.
  • If no acknowledgement is received after three attempts, the job is purged. The failure is logged by incrementing "ConsecutiveJobFailures".
  • If two consecutive Jobs fail (defined by "MaxConsecutiveJobs"), the "InterfaceFailure" flag is enabled. The event will be logged and the serial-port reset.
  • After an "InterfaceFailure" event, job processing continues. The next successful job clears the "InterfaceFailure" flag.
  • "TotalJobs" is a running count of all jobs processed (successful and failed).
  • "TotalFailedJobs" is a running count of all failed jobs.
Received Commands
  • gViziaPacketParser now handles responses to Group commands ("<M000") and Network Reconfiguration ("<!000").
  • Upon receiving a Network Reconfiguration message, the driver will initiate a Discovery operation.
Discovery
  • Discovery creates an inventory of supported Z-Wave devices.
  • It looks for three types of Z-Wave devices: Switches, Dimmers, and Thermostats.
  • "DiscoveryStatus" reports what kind of device type is currently being discovered (i.e. 'Discovering Thermostats ...').
  • After it has found all available devices, it requests their names, removes 'orphan devices', and finally requests their state (unless Polling is already enabled).
  • 'Orphan devices' are devices that were discovered in the past, and recorded by the driver, but are no longer present.
  • The Discovery process can be aborted. If aborted, the Discovery process will not request device names, remove orphan devices, nor request status.
  • If a device exists but Discovery indicates its type has changed (i.e. Node 4 was a Switch but is now a Dimmer), the device's type will be converted appropriately.
Polling
  • Polling periodically requests the status of all devices whose "OneWay" property is enabled.
  • "PollingInterval" can be set to 0 (disable polling) or any value greater than 20 seconds.
Naming
  • "SetDeviceNames" will export the names of all Premise Z-Wave devices. In other words, physical devices will acquire the names of their Premise counterparts.
  • "GetDeviceNames" will import the names of all physical Z-Wave devices. Im other words, Premise devices will acquire the names of their physical counterparts.
Raw Command
  • "ViziaRFCommand" lets you enter and submit a raw command (i.e. send commands like ">N4L50,UP").
Groups
  • Driver automatically builds an "AllLights" group and populates it with discovered lighting devices.
  • User can define other groups of lighting devices.
  • Each group can be programmed into the RZC0P by assigning a value to "GroupID" and then clicking "SetGroupID".
  • Each group has its own "PowerState" and "Brightness" properties. Enabling a group's PowerState will cause the driver to turn on all lights in the group.
  • If "GroupID" is zero, the driver sends one command per device within the group.
  • If "GroupID" is non-zero, the driver sends one command for the entire group.
  • If you change the Powerstate of a group containing dimmers and switches, both device-types will be handled.
  • If you change the Brightness of a group containing dimmers and switches, only the dimmers will be handled.
Thermostats
  • The driver can discover a thermostat.
  • It can acquire the thermostat's ambient temperature.

Future Release
  • Add the concept of "Job Priority". All polling requests are considered low priority jobs. All end-user requests are high-priority jobs. When processing the queued jobs, high priority jobs are processed before low priority jobs (see this post for more information).
  • Better support for thermostats.
  • Support Z-Wave motion detectors.
 

Attachments

  • ViziaRF.png
    ViziaRF.png
    11.1 KB · Views: 9
  • Leviton_Beta_9_1.zip
    25.4 KB · Views: 12
123, your driver is world class. The structure is very nice and so is the code!

Just one small item: two lines were missing the ",UP" on the end when >GRxON, GRxOFF or GRxLxx was sent...

>GR5ON
>GR5ON
<E000
<X000

Compared to:
>N2,14OF,UP
>N2,14OF,UP
<E000
<X000
<N002S000,000,000
<N014S000,000,000

I fixed this and have attached a new version. I only modified code for OnChangePowerState and OnChangeBrightness under Group by appending ",UP" in two places.

I also played with the oneway property; it works good and was a great addition.

I plan to order a thermostat next week so hopefully I'll have one by Thanksgiving (that's the next time I'm back home :( ). Don't worry, my wife is testing your driver unknowingly while I'm away :D It looks like all that needs to be done to implement thermostats is the onchange scripts need to be written? Do you want me to take a stab at this after I get one installed?
 

Attachments

  • Leviton_Beta9_2.zip
    25.4 KB · Views: 11
Thanks for the compliment and for spotting the errors! Be on the lookout for any weirdness during Discovery and Polling.

I've looked at the Z-Wave-related source code in Karl Denninger's HomeDaemon application and, based on exploratory work done by Karl, it contains the appropriate ViziaRf codes for handling a thermostat's heating/cooling set-points, operating mode, etc.

I'll add the thermostat-handling code to the next version and, when you get a thermostat, you can modify the code wherever needed. Talk to you in a few weeks!
 
123, Discovery and Polling seem to be working fine. I'm only at 33 errors after 6 hours of polling 4 devices every 20 seconds. That's a very low error count in my book! That's 33 errors for EDIT: 4320 poll commands (I can't do math right)!

It also looks like your driver is smart enough to retry the command if there is an error, so this small error count doesn't really matter anyways.

Groups question: can non vizia rf devices be grouped? If so, maybe the driver should automatically send a poll command to update the lights if a group member is set as "one way." Right now, 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. I'm going to read up on this and possibly add a method to poll all group members.
 
... 33 errors for 259200 poll commands ...
For the beta version, we'll leave the Job counter in place but I can see that number growing to be very large!

... driver is smart enough to retry the command if there is an error..
Yes, up to three attempts are made and then the job is discarded and logged as an error. The number of attempts is adjustable (see "MaxRuns").

...can non vizia rf devices be grouped?
Currently, the driver has no way of knowing the device's brand (although there appears to be a way of determining it) so it doen't know what is, or is not, a Leviton Vizia RF device. In this driver, Groups are collections of lighting devices (of any brand).

Here's how I envisioned driver configuration:
  1. Run a Discovery to populate the Device folder with discovered Z-Wave devices.
  2. Go through the list of devices and, for each one that does not report its status, enable its "OneWay" property. Many switches, dimmers, and thermostats are one-way devices and must be polled.
  3. Now activate Polling by setting "PollingInterval" to 20 seconds or more. The interval should probably be increased if:
    • You're not particulary concerned about the time lag between a device's state-change and Premise's awareness of the event.
    • You have a lot of Z-Wave devices.
Currently, the driver initiates a Polling operation immediately after it completes a Discovery operation but only if the PollingInterval is zero (i.e. Polling is currently deactivated). The idea is that there's no need to explicitly request a Polling operation if it is already set to run periodically. The next scheduled polling cycle will take care of updating the discovered devices. This sounds reasonable but I now realize there's a flaw.

Immediately after Discovery, none of the discovered devices have had their "OneWay" flag enabled yet. Polling only handles devices whose "OneWay" flag is enabled so its'll just skip all the newly discovered devices. So automatically running polling right after discovery accomplishes nothing.

What I probably need to do is create a special flavour of polling that occurs only after Discovery and polls all devices regardless of the state of their OneWay flag.


...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.
 
Back
Top