Using UDP datagrams to send status updates

Discussions about RaZberry - Z-Wave board for Raspberry computer
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Using UDP datagrams to send status updates

Post by pz1 »

In the first part of this post I maintain the latest version of my experimental code. It is not necessarily working though. After the line is the post that started this topic.

I did elaborate on the example of the bind function of Developers Guide 1.7 page 42.
The objective is to catch the status change of, in this case, a switch, and send the latest value to my OpenRemote Controller. The status.sh script takes care of that part. It does send (statusname,value)-pairs to the OpenRemote UDPListener. That script works.

In the new automation engine I have used the following code in CustomUserCode module.

Code: Select all

zway.devices[2].instances[0].SwitchBinary.data.level.bind(function() 
{
   var status = (zway.devices[2].SwitchBinary.data.level.value) ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh", "Switch2Status," + status ) ;
} );
The shell script is used was:

Code: Select all

#!/bin/bash
def_host=ds212
def_port=9091
HOST=${2:-$def_host}
PORT=${3:-$def_port}
echo -n "$1" | nc -4u -w 0 "$HOST" "$PORT"
exit
At the Openremote end I do use UDPListener, listening at port 9091. The updated status appears there in a label on screen (for those knowledgeable with OR).
The OpenRemote end is working now.

============= Below this line is - for reference only - my original first post. ============================

Code: Select all

zway.devices[2].instances[0].SensorBinary.data.level.bind
(
function() {
   var status = (zway.devices[2].SwitchBinary.data.level.value ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh" + "Switch2Status," + status ) ;
} 
)
After a Z-Way restart I found the following error in the log.

Code: Select all

[2014-11-13 11:35:19.463] [I] [core] Instantiating module 12 from class CustomUserCode
[2014-11-13 11:35:19.468] [I] [core] --- Starting module Load custom JavaScript code
[2014-11-13 11:35:19.512] [I] [core] Executing script: zway.devices[2].instances[0].SensorBinary.data.level.bind ...
[2014-11-13 11:35:19.537] [C] [core] JavaScript compilation error: SyntaxError: Unexpected token ;
    at CustomUserCode.init (automation/modules/CustomUserCode/index.js:36:30)
    at AutomationController.instantiateModule (automation/classes/AutomationController.js:225:22)
    at AutomationController.reconfigureInstance (automation/classes/AutomationController.js:415:22)
    at ZAutomationAPIWebRequest.<anonymous> (automation/webserver.js:606:44)
    at ZAutomationAPIWebRequest.ZAutomationWebRequest.handleRequest (automation/request.js:251:30)
    at automation/request.js:31:35
    at WebServerRequestHandler (automation/main.js:221:10)
[2014-11-13 11:35:19.567] [I] [core] Notification: error (core): Can not init module CustomUserCode: Error: JavaScript compilation error: Uncaught SyntaxError: Unexpected token ;
[2014-11-13 11:35:19.587] [I] [core] Error: JavaScript compilation error: Uncaught SyntaxError: Unexpected token ;
    at Error (native)
    at CustomUserCode.init (automation/modules/CustomUserCode/index.js:36:30)
    at AutomationController.instantiateModule (automation/classes/AutomationController.js:225:22)
    at AutomationController.reconfigureInstance (automation/classes/AutomationController.js:415:22)
    at ZAutomationAPIWebRequest.<anonymous> (automation/webserver.js:606:44)
    at ZAutomationAPIWebRequest.ZAutomationWebRequest.handleRequest (automation/request.js:251:30)
    at automation/request.js:31:35
    at WebServerRequestHandler (automation/main.js:221:10)
What am I doing wrong? Are multiple statements not allowed in bind?
I did follow this Recipe to setup my RaZberry
Since 29-12-2016 I am no longer a moderator for this forum
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: Multiple statement in bind function?

Post by pofs »

Looks like you've missed closing bracket in the 4th line:

Code: Select all

var status = (zway.devices[2].SwitchBinary.data.level.value ? "on" : "off";
should be:

Code: Select all

var status = (zway.devices[2].SwitchBinary.data.level.value) ? "on" : "off";
Also check system() line, as there's no space between script name and args. Even better, use a comma separator between script name and args:

Code: Select all

system("/opt/z-way-server/automation/storage/status.sh", "Switch2Status," + status );
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: Multiple statement in bind function?

Post by pz1 »

Thanks pofs. Hurray, got this working. Noticed also a missing ; at the end and using SensorBinary instead of SwitchBinary. Mixing to many examples ;)

So code changed to:

Code: Select all

zway.devices[2].instances[0].SwitchBinary.data.level.bind(function() 
{
   var status = (zway.devices[2].SwitchBinary.data.level.value) ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh", "Switch2Status," + status ) ;
} );
The log said:

Code: Select all

[2014-11-13 15:00:38.637] [I] [core] Instantiating module 12 from class CustomUserCode
[2014-11-13 15:00:38.642] [I] [core] --- Starting module Load custom JavaScript code
[2014-11-13 15:00:38.685] [I] [core] Executing script: zway.devices[2].instances[0].SwitchBinary.data.level.bind(function()  ...
The shell script is used was:

Code: Select all

#!/bin/bash
def_host=ds212
def_port=9091
HOST=${2:-$def_host}
PORT=${3:-$def_port}
echo -n "$1" | nc -4u -w 1 "$HOST" "$PORT"
exit
At the Openremote end I do use UDPListener, listening at port 9091. The updated status appears there in a label on screen (for those knowledgeable with OR)

The next step do something at the OpenRemote side to actually get the sensor updated.
Since 29-12-2016 I am no longer a moderator for this forum
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: Using UDP datagrams to send status updates

Post by pz1 »

I did get this working now using two switches. (Not yet the OpenRemote end)
My first attempts resulted in the UI becoming unable to start up at all. On the Raspberry console I did notice many calls being made to the script calling the netcat command. Then I realised that OpenRemote was querying the RaZ every 2 seconds on all binary switches. These requests geberated many events.
Reducing the polling interval to 1 hour solved this problem. (Note that I won't need the polling any more once the OpenRemote side is fixed)

First post is updated with the latest code
Since 29-12-2016 I am no longer a moderator for this forum
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: Using UDP datagrams to send status updates

Post by pz1 »

I have a problem with bind function to one of the temperature sensors in a Fibaro Universal Sensor. It is the last function in my code. I have taken the SensorMultilevel example from the Developers Manual, with additionaly the instance[5] selector.
It doesn't seem to like:
zway.devices[13].instances[5].SensorMultilevel.data[1].level.bind(function()

Below are the code I use, and the relevant snippet from the log. Both binary switches do work well.

UDPSendStatusOR.js: (called via HA module)

Code: Select all

zway.devices[21].instances[0].SwitchBinary.data.level.bind(function() 
{
   var status = (zway.devices[21].SwitchBinary.data.level.value) ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh", "Switch21Status," + status ) ;
} );

zway.devices[2].instances[0].SwitchBinary.data.level.bind(function() 
{
   var status = (zway.devices[2].SwitchBinary.data.level.value) ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh", "Switch2Status," + status ) ;
} );

zway.devices[13].instances[5].SensorMultilevel.data[1].level.bind(function()
{
   var status = zway.devices[13].instances[5].SensorMultilevel.data[1].val.value;
   system("/opt/z-way-server/automation/storage/status.sh", "Fus2Temp3," + status ) ;
} );
LOG

Code: Select all

[2014-11-20 10:55:22.745] [D] [zway] SETDATA devices.23.data.infoProtocolSpecific = 5479424 (0x00539c00)
[2014-11-20 10:55:22.745] [D] [zway] Job 0x41 (Get node protocol information): success
[2014-11-20 10:55:22.746] [I] [zway] Removing job: Get node protocol information
[2014-11-20 10:55:22.747] [I] [core] Notification: error (core): Can not init module CustomUserCodeLoader: Error: Uncaught TypeError: Cannot read property 'bind' of undefined
[2014-11-20 10:55:22.756] [D] [zway] SENDING: ( 01 04 00 41 18 A2 )
[2014-11-20 10:55:22.758] [D] [zway] RECEIVED ACK
[2014-11-20 10:55:22.759] [D] [zway] RECEIVED: ( 01 09 01 41 53 9C 00 04 08 06 73 )
[2014-11-20 10:55:22.759] [D] [zway] SENT ACK
[2014-11-20 10:55:22.759] [D] [zway] SETDATA devices.24.data.basicType = 4 (0x00000004)

removed a few irrelevant lines

[2014-11-20 10:55:22.659] [D] [zway] Job 0x41 (Get node protocol information): success
[2014-11-20 10:55:22.659] [I] [zway] Removing job: Get node protocol information
[2014-11-20 10:55:22.666] [E] [core] result: Error: TypeError: Cannot read property 'bind' of undefined
    at automation/storage/UDPSendStatusOR.js:13:61
    at automation/modules/CustomUserCodeLoader/index.js:39:13
    at Array.forEach (native)
    at CustomUserCodeLoader.init (automation/modules/CustomUserCodeLoader/index.js:34:33)
    at AutomationController.instantiateModule (automation/classes/AutomationController.js:225:22)
    at AutomationController.<anonymous> (automation/classes/AutomationController.js:302:22)
    at Array.forEach (native)
    at AutomationController.loadModule (automation/classes/AutomationController.js:301:86)
    at AutomationController.<anonymous> (automation/classes/AutomationController.js:318:73)
    at Array.forEach (native)
[2014-11-20 10:55:22.669] [D] [zway] SENDING: ( 01 04 00 41 13 A9 )
[2014-11-20 10:55:22.671] [D] [zway] RECEIVED ACK
[2014-11-20 10:55:22.672] [D] [zway] RECEIVED: ( 01 09 01 41 53 9C 00 04 08 06 73 )
[2014-11-20 10:55:22.672] [D] [zway] SENT ACK
[2014-11-20 10:55:22.672] [D] [zway] SETDATA devices.19.data.basicType = 4 (0x00000004)

It looks like the selected sensor does autoupdate

Code: Select all

[2014-11-20 12:48:20.880] [D] [zway] Delivered to Z-Wave stack
[2014-11-20 12:48:20.893] [D] [zway] RECEIVED: ( 01 05 00 13 85 00 6C )
[2014-11-20 12:48:20.893] [D] [zway] SENT ACK
[2014-11-20 12:48:20.894] [I] [zway] Job 0x13 (SensorMultilevel V1-4 Get): Delivered
[2014-11-20 12:48:20.894] [D] [zway] SETDATA devices.13.data.lastPacketInfo.delivered = True
[2014-11-20 12:48:20.894] [D] [zway] SETDATA devices.13.data.lastPacketInfo.packetLength = 9 (0x00000009)
[2014-11-20 12:48:20.894] [D] [zway] SETDATA devices.13.data.lastPacketInfo.deliveryTime = 13 (0x0000000d)
[2014-11-20 12:48:20.894] [D] [zway] SETDATA devices.13.data.lastPacketInfo = **********
[2014-11-20 12:48:20.894] [D] [zway] SendData Response with callback 0x85 received: received by recipient
[2014-11-20 12:48:20.895] [D] [zway] SETDATA devices.13.data.lastSend = 664287 (0x000a22df)
[2014-11-20 12:48:20.895] [D] [zway] Job 0x13 (SensorMultilevel V1-4 Get): success
[2014-11-20 12:48:20.895] [I] [zway] Removing job: SensorMultilevel V1-4 Get
[2014-11-20 12:48:20.903] [D] [zway] RECEIVED: ( 01 12 00 04 00 0D 0C 60 0D 05 00 31 05 01 44 00 00 0B D1 2B )
[2014-11-20 12:48:20.903] [D] [zway] SENT ACK
[2014-11-20 12:48:20.903] [D] [zway] SETDATA devices.13.data.lastReceived = 0 (0x00000000)
[2014-11-20 12:48:20.904] [D] [zway] SETDATA devices.13.instances.5.commandClasses.49.data.1.deviceScale = 0 (0x00000000)
[2014-11-20 12:48:20.905] [D] [zway] SETDATA devices.13.instances.5.commandClasses.49.data.1.scale = 0 (0x00000000)
[2014-11-20 12:48:20.905] [D] [zway] SETDATA devices.13.instances.5.commandClasses.49.data.1.val = 30.250000
[2014-11-20 12:48:20.908] [D] [zway] SETDATA devices.13.instances.5.commandClasses.49.data.1.scaleString = "°C"
[2014-11-20 12:48:20.909] [D] [zway] SETDATA devices.13.instances.5.commandClasses.49.data.1 = Empty
[2014-11-20 12:48:41.007] [D] [zway] Job 0x13: deleted from queue
[2014-11-20 12:48:51.799] [D] [zway] RECEIVED: ( 01 08 00 04 00 18 02 84 07 6A )
[2014-11-20 12:48:51.800] [D] [zway] SENT ACK
[2014-11-20 12:48:51.801] [D] [zway] SETDATA devices.24.data.lastReceived = 0 (0x00000000)
Since 29-12-2016 I am no longer a moderator for this forum
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: Using UDP datagrams to send status updates

Post by pz1 »

Thanks to an old post of Kambriw, I did find the solution. Instead of level, I should have used val in the expression below
zway.devices[13].instances[5].SensorMultilevel.data[1].level.bind(function()
So apparantly the Instruction in the Developers Document 1.7 is wrong:
BindExampleManual.PNG
BindExampleManual.PNG (16.49 KiB) Viewed 10378 times
Since 29-12-2016 I am no longer a moderator for this forum
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: Using UDP datagrams to send status updates

Post by pz1 »

The OpenRemote end is working now. That closes the cycle. Next step is see if this solution does scale to more than the three devices I currently have.
Since 29-12-2016 I am no longer a moderator for this forum
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: Using UDP datagrams to send status updates

Post by pofs »

pz1 wrote:

Code: Select all

zway.devices[21].instances[0].SwitchBinary.data.level.bind(function() 
{
   var status = (zway.devices[21].SwitchBinary.data.level.value) ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh", "Switch21Status," + status ) ;
} );
Are you aware you could just use "this" inside handler? :)

Code: Select all

zway.devices[21].instances[0].SwitchBinary.data.level.bind(function() 
{
   var status = this.value ? "on" : "off";
   system("/opt/z-way-server/automation/storage/status.sh", "Switch21Status," + status ) ;
} );
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: Using UDP datagrams to send status updates

Post by pz1 »

I had a vague awareness that I should do something with "this", but as I have no recent programming experiences, I did not know how :) So thank you for pointing me to that.

I'll update my documentation to that end. I have something going for the OpenRemote community already in my private space. The relevant RaZberry piece will go in the Recipes section here.
Thanks again for the critical look.
Since 29-12-2016 I am no longer a moderator for this forum
hpd
Posts: 36
Joined: 20 Mar 2014 12:03

Re: Using UDP datagrams to send status updates

Post by hpd »

I followed the udp recipe.
But something is wrong with the user module in your example. CustomUserCodeLoader crashes after acces to this code.
It appears to me there is a missing closing bracket at the end. But I am not sure about it.
Z-Way 2.0.0-final on Raspberry Pi
Post Reply