[HowTo] Send status updates as UDP messages

Tips, Tricks and Scripts to enhance your home automation and workaround known device bugs, limitations and incompatibilities
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

[HowTo] Send status updates as UDP messages

Post by pz1 »

Last updated: 2016-02-25
Last tested with: v2.2.1
STATUS:stable

This document describes how RaZberry can send status updates as short UDP mesages. These messages consist of (SensorName.Value) pairs. This recipe is used in the communication with OpenRemote. See the full description at OpenRemote. Note: This recipe can also be used in other applications, since it does not depend on OR-specific things!

Note: On the Listener side there now is an extension on the rules that implements a watchdog. If no UDP messages are received since a prolonged time, the live Z-wave icon turns to red:
Capture.PNG
Capture.PNG (14.65 KiB) Viewed 18283 times
This part deals with the configuration settings on the Raspberry Pi, where you have to do some editing in files. Using Putty make a terminal connection. You can copy and paste(only touch right mouse button) the following instructions.
The remainder of the instruction assumes you have set your working directory to:

Code: Select all

cd /opt/z-way-server
Modern Z-Wave devices have the ability to report their stus changes to the Z-Wave controller that creates an even in return. The Z-Way stack can bind user defined actions to these events. In this case the action results in a UDP message being sent.

CAUTION: unsolicited status updates will only work if the Z-Wave controller is properly notified. This notification is done through the basic association mechanism. Most often association group 3 is used for that. With the RaZberry Expert tool you can check that the primary controller (node 1, RaZberry) is in that association group. In case of failure consult the documentation of the failing device first.
automation/storage/UDPORSock.js

Code: Select all

sudo nano automation/storage/UDPORSock.js
Below are some examples of functions bound to an event. They can be re-used. Adapt values between [] for your specific device. Please note that in the SwitchBinary example we have taken the opportunity to translate the outcome false|true into on|off, what is preferred at the receiving end. Other javascript operators (eg setting numbers of decimals) may be used as appropriate.

Code: Select all

var sock = new sockets.udp();
sock.connect("192.168.4.88", 9091); //Use IP, and port number of your OpenRemote Controller

this.bindFunc1 = function (zwayName) {
	if (zwayName != "zway")
		return; // you want to bind to default zway instance

	var devices = global.ZWave[zwayName].zway.devices;

	//from here insert your devices

	// Zwave>Me Binary Switch
	devices[2].SwitchBinary.data.level.bind(function () {
		var status = (this.value) ? "on" : "off";
		sock.send("ZWay_2," + status);
	});

	// Fibaro Universal Sensor-Temperature
	devices[13].instances[5].SensorMultilevel.data[1].val.bind(function () {
		var status = this.value;
		sock.send("ZWay_13_5_1," + status);
	});

	// Vision Door/window sensor
	devices[30].SensorBinary.data[1].level.bind(function () {
		var status = (this.value) ? "on" : "off";
		sock.send("ZWay_30_0_1," + status);
	});

	// End of your devices
};

// process all active bindings
if (global.ZWave) {
	global.ZWave().forEach(this.bindFunc1);
}

// and listen for future ones
global.controller.on("ZWave.register", this.bindFunc1);
For other types of devices the primary source of reference is the Z-Way Developer Documentation. If you are naughty you may peek in automation/modules/OpenRemoteHelpers/index.js. That is not recommended practice though!

Activate UDPSender
In principle the UDPSendStatusOR.js could be executed from the main.js file. The preferred and easiest way to it, is the RaZberry Home Automation engine. Therefore goto menu -Preferences-Modules-Scripting. Choose CustomUserCodeLoader. It is important to load this javascript code first in your modules setup.


Assessment
Be aware that UDP is not the most reliable protocol. There is no correction mechanism for missing data. So do not apply this recipe in mission critical applications. Some places are more susceptible for such errors.

See next post for testing UDP communication
Since 29-12-2016 I am no longer a moderator for this forum
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Test status updates via UDP messages

Post by pz1 »

Via a ssh session, you can use tcpdump to see if UDP messages are being sent by your raspberrypi. See here for a HowTo on that utility.

Below is an example command

Code: Select all

sudo tcpdump -A -v -s 10240 'udp port 9192'
Results from my Fibaro Universal sensor temperatures

Code: Select all

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 10240 bytes
11:47:04.983522 IP (tos 0x0, ttl 64, id 13163, offset 0, flags [DF], proto UDP (17), length 45)
    raspberry.fritz.box.40810 > DS212.home.9192: UDP, length 17
E..-3k@.@..........!.j#.....ZWay_13_3_1,15.25
11:47:05.056422 IP (tos 0x0, ttl 64, id 13167, offset 0, flags [DF], proto UDP (17), length 44)
    raspberry.fritz.box.40810 > DS212.home.9192: UDP, length 16
E..,3o@.@..........!.j#.....ZWay_13_4_1,19.5
11:47:05.665795 IP (tos 0x0, ttl 64, id 13209, offset 0, flags [DF], proto UDP (17), length 45)
    raspberry.fritz.box.40810 > DS212.home.9192: UDP, length 17
E..-3.@.@..........!.j#.....ZWay_13_5_1,18.81
11:47:05.705917 IP (tos 0x0, ttl 64, id 13212, offset 0, flags [DF], proto UDP (17), length 45)
    raspberry.fritz.box.40810 > DS212.home.9192: UDP, length 17
E..-3.@.@..........!.j#.....ZWay_13_6_1,17.06
You can do the same at the receiving end to check if the data arrives.
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Send status updates as UDP messages

Post by pz1 »

I do experience problems after upgrading zway to a new version. UDP messages don't appear to come through to OpenRemote. I don't know what the cause is. I have tried several restart strategies. I guess it has something to do with either OpenRemote's Drools engine, or UPDListener channel still open at OpenRemote controller

What has worked is a total reboot of my Synology device where the OpenRemote controller lives, followed by a stop zway-services and next reboot of the raspi.
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Send status updates as UDP messages

Post by pz1 »

pz1 wrote:What has worked is a total reboot of my Synology device where the OpenRemote controller lives, followed by a stop zway-services and next reboot of the raspi.
This sequence has worked for me now three times.
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Send status updates as UDP messages

Post by pz1 »

Since the upgrade from v2.0.1-rc5 to v2.0.1-rc6, I can get this(configuration in the first post) to work anymore. From the log it looks like the javascript is loaded :

Code: Select all

[2014-12-21 16:13:13.259] [I] [core] Executing script:   /*** CustomUserCodeLoader ZAutomation module **************************************** ...
[2014-12-21 16:13:13.262] [D] [zway] RECEIVED ACK
[2014-12-21 16:13:13.263] [I] [zway] Removing job: Set controller node information frame
[2014-12-21 16:13:13.267] [I] [core] Instantiating module 19 from class CustomUserCodeLoader
[2014-12-21 16:13:13.270] [I] [core] --- Starting module Load custom JavaScript file
[2014-12-21 16:13:13.273] [D] [zway] SENDING: ( 01 03 00 05 F9 )
[2014-12-21 16:13:13.275] [D] [zway] RECEIVED ACK
[2014-12-21 16:13:13.275] [D] [zway] RECEIVED: ( 01 04 01 05 08 F7 )
[2014-12-21 16:13:13.276] [D] [zway] SENT ACK
[2014-12-21 16:13:13.276] [D] [zway] SETDATA controller.data.isPrimary = True
[2014-12-21 16:13:13.276] [D] [zway] SETDATA controller.data.isInOthersNetwork = False
[2014-12-21 16:13:13.276] [D] [zway] SETDATA controller.data.SISPresent = False
[2014-12-21 16:13:13.276] [D] [zway] SETDATA controller.data.isRealPrimary = True
[2014-12-21 16:13:13.276] [D] [zway] SETDATA controller.data.isSUC = False
[2014-12-21 16:13:13.277] [D] [zway] Job 0x05 (Get controller capabilities): success
[2014-12-21 16:13:13.277] [I] [zway] Adding job: Set new SUC/SIS
[2014-12-21 16:13:13.277] [I] [zway] Removing job: Get controller capabilities
[2014-12-21 16:13:13.288] [D] [zway] SENDING: ( 01 07 00 54 01 01 00 01 AD )
[2014-12-21 16:13:13.290] [D] [zway] RECEIVED ACK
[2014-12-21 16:13:13.290] [D] [zway] RECEIVED: ( 01 04 01 54 00 AE )
[2014-12-21 16:13:13.291] [D] [zway] SENT ACK
[2014-12-21 16:13:13.291] [I] [zway] Job 0x54 (Set new SUC/SIS): Failed
[2014-12-21 16:13:13.291] [D] [zway] Job 0x54 (Set new SUC/SIS): fail
[2014-12-21 16:13:13.291] [I] [zway] Removing job: Set new SUC/SIS
[2014-12-21 16:13:13.315] [I] [core] Executing script:     this.bindFunc1 = function(zwayName) { ...
[2014-12-21 16:13:13.423] [I] [core] Loading module SmartLight from modules/SmartLight
[2014-12-21 16:13:13.431] [I] [core] Executing script: /*** SmartLight Z-Way Home Automation module ************************************* ...
[2014-12-21 16:13:13.433] [I] [core] Loading module SecurityMode from modules/SecurityMode
[2014-12-21 16:13:13.441] [I] [core] Executing script: /*** SecurityMode Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.444] [I] [core] Loading module SensorValueLogging from modules/SensorValueLogging
[2014-12-21 16:13:13.449] [I] [core] Executing script: /*** SensorValueLogging Z-Way Home Automation module ************************************* ...
[2014-12-21 16:13:13.451] [I] [core] Loading module NotificationSMSru from modules/NotificationSMSru
[2014-12-21 16:13:13.456] [I] [core] Executing script: /*** NotificationSMSru Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.459] [I] [core] Loading module RoundRobinScenes from modules/RoundRobinScenes
[2014-12-21 16:13:13.463] [I] [core] Executing script: /*** RoundRobinScenes Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.466] [I] [core] Loading module HTTPDevice from modules/HTTPDevice
[2014-12-21 16:13:13.474] [I] [core] Executing script: /*** HTTPDevice Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.477] [I] [core] Loading module OpenWeather from modules/OpenWeather
[2014-12-21 16:13:13.482] [I] [core] Executing script: /*** OpenWeather Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.485] [I] [core] Loading module ImportRemoteHA from modules/ImportRemoteHA
[2014-12-21 16:13:13.493] [I] [core] Executing script: /*** ImportRemoteHA Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.496] [I] [core] Loading module RGB from modules/RGB
[2014-12-21 16:13:13.503] [I] [core] Executing script: /*** RGB Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.506] [I] [core] Loading module ScheduleSun from userModules/ScheduleSun
[2014-12-21 16:13:13.519] [I] [core] Executing script: /*** ScheduleSun module ************************************************* ...
[2014-12-21 16:13:13.531] [I] [core] Loading module DelayedScene from modules/DelayedScene
[2014-12-21 16:13:13.538] [I] [core] Executing script: /*** DelayedScene Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.541] [I] [core] Loading module CodeDevice from modules/CodeDevice
[2014-12-21 16:13:13.548] [I] [core] Executing script: /*** CodeDevice Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.557] [I] [core] Instantiating module 27 from class CodeDevice
[2014-12-21 16:13:13.565] [I] [core] --- Starting module Code device
[2014-12-21 16:13:13.599] [I] [core] Creating device toggleButton Code_Device_toggleButton_27
[2014-12-21 16:13:13.650] [I] [core] Instantiating module 28 from class CodeDevice
[2014-12-21 16:13:13.651] [I] [core] --- Starting module Code device
[2014-12-21 16:13:13.683] [I] [core] Creating device toggleButton Code_Device_toggleButton_28
[2014-12-21 16:13:13.705] [I] [core] Instantiating module 29 from class CodeDevice
[2014-12-21 16:13:13.705] [I] [core] --- Starting module Code device
[2014-12-21 16:13:13.731] [I] [core] Creating device toggleButton Code_Device_toggleButton_29
[2014-12-21 16:13:13.759] [I] [core] Instantiating module 30 from class CodeDevice
[2014-12-21 16:13:13.760] [I] [core] --- Starting module Code device
[2014-12-21 16:13:13.785] [I] [core] Creating device toggleButton Code_Device_toggleButton_30
[2014-12-21 16:13:13.810] [I] [core] Instantiating module 31 from class CodeDevice
[2014-12-21 16:13:13.811] [I] [core] --- Starting module Code device
[2014-12-21 16:13:13.836] [I] [core] Creating device toggleButton Code_Device_toggleButton_31
[2014-12-21 16:13:13.861] [I] [core] Loading module CustomUserCode from modules/CustomUserCode
[2014-12-21 16:13:13.865] [I] [core] Executing script:   /*** CustomUserCode ZAutomation module **************************************** ...
[2014-12-21 16:13:13.867] [I] [core] Loading module HomeKitGate from modules/HomeKitGate
[2014-12-21 16:13:13.875] [I] [core] Executing script: /* ...
[2014-12-21 16:13:13.878] [I] [core] Loading module BatteryPolling from modules/BatteryPolling
[2014-12-21 16:13:13.884] [I] [core] Executing script: /*** BatteryPolling Z-Way HA module ******************************************* ...
[2014-12-21 16:13:13.888] [I] [core] Starting automation...
[2014-12-21 16:13:13.982] [I] [core] Starting storage...
[2014-12-21 16:13:13.986] [I] [core] ZWay Automation started
[2014-12-21 16:13:14.528] [I] [core] Creating device switchBinary ZWayVDev_zway_2-0-37
[2014-12-21 16:13:14.786] [I] [core] Creating device switchBinary ZWayVDev_zway_3-0-37

Unfortunately nothing is happening on the receiving end on OpenRemote. Using the status.sh script on raspberry console I was able to manually sens a (sensor,value) pair to OpenRemote, where the OR sensor correctly updated.

The log says "Instantiating module 19" on "CustomUserCodeLoader" . Further down "Executing script: this.bindFunc1 = function(zwayName) { ..." is the beginning of my script.

I can't think of anything else to test/check. May the changes from rc5 to rc6 have lead to my problem?
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Send status updates as UDP messages

Post by pz1 »

pz1 wrote:Since the upgrade from v2.0.1-rc5 to v2.0.1-rc6, I can get this(configuration in the first post) to work anymore.
I left the system overnight. In the morning on the raspberry console I did a zway stop waited a minute or so, and did a start again. To my surprise two hours later I discovered that since that moment the UPD send is sending to openremote again.
Mysterious, because I had done a similar thing via the Z-Way Configuration Interface
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Send status updates as UDP messages

Post by pz1 »

In the latest RC there is a new module modsockets.so, which I assume can replace my system call to a script that calls netcat

Part of the code from the dirst post

Code: Select all

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

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
As there is no documentation yet about the new module, my question is:
How do I use the new library to replace the existing system call.
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: [HowTo] Send status updates as UDP messages

Post by pofs »

It is not very well tested yet, but for sending UDP message you can use the following code:

Code: Select all

var sock = new sockets.udp();
sock.sendto("Hello", "192.168.0.1", 1234);
// -or-
// sock.connect("192.168.0.1", 1234);
// sock.send("Hello");
// sock.send("there");
Socket gets closed either when you call .close(), or when it is not referenced anymore.
Of course, it is reasonable not to create a socket before each send, but to create it once on module startup and then just use it :)

In a similar way you can also create tcp sockets, both client and server.
I'll post more examples later.
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: [HowTo] Send status updates as UDP messages

Post by pz1 »

Thanks, I am pleasantly surprised that this has been added. Sooner than I expected.

So it should be something like this then? And possibly do it as a proper userModule with a config.json that let's the user set address/port. As well as some dependency? I do experience starting problems after reboot of Razberry and/or OpenRemote. I still do not understand why my UDP code has to start before Z-Wave is started

Code: Select all

var sock = new sockets.udp();
sock.connect("192.168.0.1", 1234);

this.bindFunc1 = function(zwayName) {
   if (zwayName != "zway") return; // you want to bind to default zway instance
     
   var devices = global.ZWave[zwayName].zway.devices;

//from here insert your devices

// Binary Switch
devices[2].instances[0].SwitchBinary.data.level.bind(function()
{
   var status = (this.value) ? "on" : "off";
   sock.send( "ZWay_2," + status ) ;
} );

// Last device before this point
};
global.controller.on("ZWave.register", this.bindFunc1);
For the time being I do intend to keep this as code with explicitly specified devices. I want to play a bit with operations on returned values (rounding, cancelling values that are obiously out of range)

PS: I intend to try this on new Rasberry 2 with UZB1 stick. So I won't be able to test until I can upgrade the stick
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: [HowTo] Send status updates as UDP messages

Post by pofs »

pz1 wrote:I still do not understand why my UDP code has to start before Z-Wave is started
Because you have only a subscription for future zwave binding creation. But if your code starts after zwave binding, bindFunc1 is never called.
See my complete example here: viewtopic.php?f=3422&t=20816&p=53488&hi ... ter#p53478
Post Reply