Premise Z-Wave Status using RZCOP/VRCOP help

Motorola Premise
... I tried just adding debugout sPkt to the global parser, but nothing would display under debugview? ...
You can try adding a "len(sPkt)" to display the length of the received data to get a better idea of what's going on. Or, better yet, use "asc(sPkt)" to display the ANSI integer value for the first character in sPkt. So if sPkt contains a single null character ("00"), the asc function will convert it to "0".

If it indicates a zero-length string (i.e. empty string) then there might be a problem with "RxTextLineTerminators". Maybe it thinks the received data has two consecutive line terminators. If Carriage Return and Line Feed serves as the delimiter then the following:

DATA<CR><LF><CR><LF>

might be misinterpreted as "DATA" and an empty string "".


Here's what the module's "ClassConstructor" method does:
this.RxTextLineTerminators = "0D OA"

That's wrong! The letter "A" is preceded by the letter "O" when it ought to be the number "0". I thought I had found the source of the problem and then discovered that Premise recognizes this is an invalid assignment, ignores it, and uses its default set of terminators: "0D 0A 00". Oh well.

You can try experimenting with RxTextLineTerminators to see if there's a combination that eliminates the empty string issue. Go to Devices > CustomDevices > ViziaRF, locate the RxTextLineTerminators property, and remove the null character "00".
 
123, you have good eyes 0 and O look identical under the Builders font! The init script also had the same error. You are right, rxTextLine has 0 length on the bad packet errors.

Even if I try 0D which should also work according the RZC0P programming manual (v1.2), I still get bad packets. If I have no LF, discover devices also hangs on the first device despite the manual saying a LF is optional!?! I also tried LF with no CR and still received the bad packet. I also tried 0A 0D and it didn't fix the problem.

Perhaps the simplist solution is for the newdata script to ignore packets with non zero lenght?

FYI: I even tried unplugging the RZC0P and that didn't fix the issue.

I've attached my xdo I used and the debugout log file.
 

Attachments

  • Vizia_0D_0A_fixed_with_additional_debug_view.zip
    72.5 KB · Views: 13
I looked through the log and it is evident that the driver receives many 'zero-length' messages from the RZC0P. The only way to truly understand what's going on would be to see the received messages in raw mode. In other words, it would instructive to see the data in Binary Mode in order to see how the messages are being delimited. It would help answer the following question: Does the RZC0P consistently delimit all messages with CR LF or just a CR or does it vary depending on the message. Perhaps PortSpy, or some other serial-communications program, could be used to view the raw bytes.

The simplest solution is to 'sweep the zero-length messages under a rug'. In OnChangeNewData, test the length of RxTextLine before submitting it to gViziaPacketParser; have it discard zero-length messages.
 
I have to think there must be a program to log port communications in binary mode. I don't think port spy will do this for us... I'll give it a try if you have a recommendation :)
 
You can try RealTerm. I believe I saw it mentioned on the HomeSeer forum and it appears to have the features needed to debug serial communications. It includes a nifty "Hex Font" that displays characters that are not normally visible.
 
Thanks 123. This looks promising. I can't install it until I get back home on Friday :)

I did try port spy last night though and verified that even in the lower window (below the ascii data) of port spy where the hex data shows up, there was nothing that would indicate a bad packet. I believe your idea of using a third party program to log the port will shed light on the issue.

PS EDIT: After reading the link you gave, Realterm looks very useful to me for future use. Thanks again!

You can try RealTerm. I believe I saw it mentioned on the HomeSeer forum and it appears to have the features needed to debug serial communications. It includes a nifty "Hex Font" that displays characters that are not normally visible.
 
Serial issue fixed! See attached pics.

The issue was that the original driver I posted that 123 greatly enhanced directly inherited from the Transport class. The driver also inherited from the SerialDevice class already inherited from the transport class, thus duplicating Transport class inheritance was causing the port to become unresponsive.

I'm still getting X002 responses from devices when poll intervals are short. I'm guessing this maybe normal? The X002 responses are tallied into TotalTransmissionErrors = 1894.
 

Attachments

  • transmission_test_2.JPG
    transmission_test_2.JPG
    10.2 KB · Views: 12
  • transmission_test.JPG
    transmission_test.JPG
    9.1 KB · Views: 1
I've modified the original beta 9.6 file a little. I removed the direct inheritance from the Transport Class and commented out the debugout statements.

I've also added a few features:
1. When a device property is set, all low priority jobs for that device are removed from the job queue just prior to the new command being sent. In other words, polling and other low priority operations for that device will skip a polling cycle. I really don't think this feature was necessary, but it is kind of neat.

2. I've replaced the multivalue Category with NodeID to aid in implementing 1. For things that aren't devices, a fictitious nodeID is used as follows:
994 - setting/getting location
995 - setting/getting device names
996 - discovery related tasks
997 & groupID - group related tasks
998 & sceneID - scene related tasks
999 - anything else such as manually scripted commands

Remember, this is ok since the RZC0P cannot have more than 232 devices bound to it.

In retrospect, I wish I'd kept category, because it was neat too! :)
 

Attachments

  • Leviton_BETA_9.8.zip
    38.6 KB · Views: 13
I reviewed the changes you made to the driver, notably the new method called "PurgeLowPriorityJobsByNodeID".

If you examine the driver's architecture, you'll notice that PropertyChanges do not tinker with the Job Queue. In other words, the sole entry-point into the JobQueue is via "SendCommand". The moment you allow multiple entry-points into the JobQueue, you get 'spaghetti code' and that means an increased potential for instability along with a decrease in maintainability.

If you increase a light's Brightness, "OnChangeBrightness" simply uses "SendCommand" to transmit the new brightness level. "SendCommand" uses the JobQueue's methods (AddJob, RunJob) to submit the command to the queue. "GetNextJob" is responsible for determing the next job to process. Nothing else should be tinkering with the Job Queue.

In the latest version, seven PropertyChanges use "PurgeLowPriorityJobsByNodeID" to manipulate the Job Queue before calling SendCommand.

Each PropertyChange method should simply use SendCommand. SendCommand currently takes three parameters: Data, Priority, and NodeID. There's enough information there for "GetNextJob" to handle the details.

It is the responsibility of "GetNextJob" to determine the next Job to process. It currently handles High-Priority Jobs first, followed by Low-Priority jobs. It should be modified so that when handling a High-Priority Job, such as a user-initiated change in a thermostat's setpoint, it flushes any existing low-priority jobs for that thermostat using "PurgeLowPriorityJobsByNodeID".
 
123, good observations! I agree, the changes you're suggesting will make the code cleaner and easier to follow (less like spaghetti) ;) I'll post a refined version tonight or tomorrow.

Your thermostat comment is very insightful. I think the only device that PurgeLowPriorityJobsByNodeID may help is a thermostat that takes a second or so to process a command. Thus, the danger would be if a poll came along during that 500ms - 1000ms period, would it return the old value. Removing polls after you just send a command to a node makes sense from an efficiency point of view too, but the first reason is why I added the extra feature.
 
I think one extra line in "GetNextJob" should do the trick:
Code:
	' Get High-Priority Jobs
	set oJobs = this.GetObjectsByTypeAndPropertyValue(Schema.Modules.Leviton.Classes.Job.Path, "Priority", true)
		
	if oJobs.Count > 0 then
		this.CurrentJob = oJobs(0).ObjectID
		this.PurgeLowPriorityJobsByNodeID oJobs(0).NodeID ' Purge existing low-priority jobs associated with this NodeID
		this.ProcessCurrentJob
	else
		' No high-priority jobs so check for low-priority jobs generated by Polling
		set oJobs = this.GetObjectsByTypeAndPropertyValue(Schema.Modules.Leviton.Classes.Job.Path, "Priority", false)

		if oJobs.Count > 0 then
			this.CurrentJob = oJobs(0).ObjectID
			this.ProcessCurrentJob
		else
			this.CurrentJob = ""
			this.JobIndex = 0
			'debugout "No more jobs to process."
		end if
	end if

BTW, what is the reason for toggling the "OneWay" flag? I noticed in the PropertyChange scripts you set OneWay to false and then use a 5 second timer to put it back to true. I don't believe this is necessary if "PurgeLowPriorityJobsByNodeID" is placed in "GetNextJob".
 
123, I'm thinking that you would need both the 5 second timer and to purge all existing jobs.

My understanding is that the 5 second timer will get rid of all poll jobs for the device for 5 seconds after a high priority command has been sent. However, depending on traffic, you could still have old poll commands in the job queue from before the high priority command was sent. The latter is prevented by purging all low priority jobs for a node.

I may be totally missing something like before though, I apologize if this is the case ;)
 
Hmm... RunJob also calls ProcessCurrentJob Does this mean purgeLowPriortyJobsByNode line of code should go under processcurrentjob?
 
Nope. RunJob is executed only if there are no existing Jobs in the queue.

BTW, refresh my memory why we need to be concerned with low-priority polling commands that come after a high-priority command?

If I adjust a thermostat's setpoint, that's a high-priority command, and GetNextJob will purge all existing polling commands (low-priority) related to the thermostat, and then send the high-priority command. If it is immediately followed by a low-priority thermostat command, what harm can it cause? It won't be transmitted until the high-priority command has been sent.
 
What you are saying makes sense and you are definitely right about RunJob's purpose.

I don't remember completely why we toggled oneway. However, below may be a very good reason why we need to:

I believe it was something to do with the wayne dalton thermostat and the time it takes to process a command. Just because we receive E000 and X000, that doesn't mean the Wayne Dalton has processed the command. If I remember correctly (not at home to check), the cheap thermostat takes up to 2-3 seconds before you see the new temperature sent from Premise displayed on the physical thermostat. I think this means there may be some extra internal processing time that is needed...

Further, note that the RZC0P manual has these comments:
<E000 <- RS interface processed the input
<X000 <- Appropriate message has been send correctly

Neither of these indicate the device has processed the command successfully. X000 indicates that the command was sent to the device, but that's all it tells us. If the device has some internal processing time, this could mean there is a need to toggle oneway via a timer.

EDIT: Further discussion... Now if we assume this device with some internal delay has a fifo buffer, then the command we sent would be first in line and would be processed before any new polls that occur after the command was originally sent and the timer would not be needed.

However, if the device gives preference to query packets due to some internal limitation or by design, this may mean that Premise will display the incorrect value for a poll cycle and overwrite what the user has just changed in the automation browser. However, once the new value is completely processed by the device I would think that the value would be correct on the next polling cycle.

I think this is plausible on something like a thermostat depending on how the subsystems are designed. If you have a chip to handle zwave communications , it will forward a temp setpoint command to an internal thermostat controller. Once the command is forwarded, the receive buffer would be clear within the zwave communications chip. Now, suppose this temp controller takes x seconds to update and that a poll comes in. The zwave communications chip will then ask the temp controller what temp it is set for and it could reply with the old setting if it's been less than x seconds!
 
Back
Top