Categories
HowTo's VSCP

Howto: How to send Raspberry Pi CPU & GPU temperature readings to the VSCP daemon

https://github.com/grodansparadis/vscp/wiki/How-to-send-Raspberry-Pi-CPU-&-GPU-temperature-readings-to-the-VSCP-daemon

Categories
HowTo's VSCP

Howto: How to send Digitemp 1-wire readings to the VSCP daemon

https://github.com/grodansparadis/vscp/wiki/How-to-send-Digitemp-readings-to-the-VSCP-daemon

Categories
HowTo's VSCP

Howto: How to send 1 -wire temperature readings to the VSCP daemon

https://github.com/grodansparadis/vscp/wiki/How-to-send-1-wire-readings-to-the-VSCP-daemon

Categories
HowTo's VSCP

Howto: Smart P1 power meter (Ellevio)

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-21-06-37.png

A Swedish version of this document is here

A PCB to interface the smartmeter is available here

This is how the new electricity meter look slike that was installed here this week. Apparently, 5.4 million new meters will be out before 2025 (Swedish). Yes, I have been collecting data from its predecessor (which was only installed here for two years) for quite some time. S0 pulse was not available to ordinary people like me but the flashing IR diode was. So power and energy I have logged. I have another meter in my office too. Reads S0 and IR there and can thus distinguish between the house’s total electricity consumption and the office’s electricity consumption.

But the new electricity meter promised more. A serial interface for customers. A HAN gate. Yep, definitely something that definitely start a guy like me up. A few minutes after it was installed, the customer interface was activated. Just go to Ellevio’s “my pages” and activate. Smooth.

Unfortunately I did not go ahead with building the interface logic required to be able to read out values from the interface the day it got installed. Had to (impatiently) wait to the next day because I had other things to do. But it was very simple. A transistor, some resistors and a USB to series converter are all that is needed. After it is built a Raspberry Pi could read the information that the meter sends out. You could just as easily use an ESP32’a or an ESP8266, Arduino, or a PC of course. Nothing strange, expensive or advanced here.

The new meter provides current and voltage and active and reactive load on all phases separately. Add summed energy to that. Yes, both in and out. If you are someone who has a wind turbine or solar panels in the yard the in readings is for you. Goddies for those of us that like data. All data is sent out every ten seconds from the meter.

So what does the meter send?

As far as I understand, the protocol is called “P1 Companion Standard” which is based on IEC 62056-21 Mode D. The energy companies have issued an Industry Recommendation for local customer interface for electricity meters that describes function and protocol.

The serial format is unencrypted with speed and format 115200, N, 8.1. Just standard. However, it is sent inverted and with TTL levels so you have to take care of that.

The contact on the electricity meter is an RJ12 as below

This image has an empty alt attribute; its file name is upload_2020-9-29_11-11-43.png

The meter sends data on pin 5 when D_Rqst (RTS) is high. I have tested the circuit below with both 5V and 3.3V and both work great so interfacing most hardware should be no problem as long as it has a serial port or can emulate one.

If you look at what the interface on the meter looks like, you understand that both 3.3V and 5V work.

This image has an empty alt attribute; its file name is htb1z7hnxznuk1rksmfpq6auzfxal.jpg

A simple circuit is all that is needed to adapt this to a USB TTL serial adapter I used or to the serial channels on a Raspberry Pi, Arduino or other device.

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-20-56-50-1024x591.png

Select 5V for VCC if rx is to be connected to a 5V input (Arduino etc), otherwise select 3.3V (ESP32 / ESP8266 / Raspberry Pi etc). In my case, I use a USB to series adapter that can handle TTL levels. Remember to also connect the earth to the device that will read the data.

If you use a USB to series adapter like me and Raspberry Pi, it will be available as /dev/ttyUSB0, /dev/ttyUSB1, etc when connected. With the Minicom program you can look at the raw data. Install Minicom with

sudo apt install minicom

If you want to be able to open the port without “sudo”, you should add the user you are running under (usually “pi“) to dialout in the file /dev/group

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-21-17-14.png

Use the nano or vim editor or your own favorite editor to do this.

Now run Minicom with

minicom -b115200 -D/dev/ttyUSB0

Change the serial port to the port you use and add sudo if you did not do the change in /dev/group.

The command line switches speak for themselves. But for safety’s sake, we take them. -b sets the baud rate. -D indicates the port you want to communicate on. Of course you change to the port you use. If all goes well, the following is printed on the screen every ten seconds.

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-21-25-34.png

In the linked document above, there is an appendix 3 that tells what the type of data is for each line. Easy to parse with our code.

To exit Minicom, type

ctrl-A Z X

and select “yes” when asked “Leave Minicom?” Best to write it because the sequence is not the first one you come up with. Trivial if you know it, not so if you don’t.

It is not more than that. Now just write a program that reads these values and lists them in charts and tables. node-red is a great tool to use for this. node-red can read from a serial port directly or you can write a script like this in Python

import serial

sio = serial.Serial(
port='/dev/ttyUSB1',\
baudrate=115200,\
parity=serial.PARITY_NONE,\
stopbits=serial.STOPBITS_ONE,\
bytesize=serial.EIGHTBITS,\
timeout=12)

print("connected to: " + sio.portstr)
count=1

while True:
line = sio.readline().decode('ascii')
if (-1 != line.find("1-0:31.7.0")):
print("[" + line + "]")
print("Fas L1:"+line[11:-5]+ " " + line[-4])
print(float(line[11:-5]))

Preferably, you then send the data to an MQTT broker or similar instead of printing it. A little fun coding for a boring evening maybe.

I have put together the project vscp-python-p1-power-meter which sends sensor values to any MQTT broker. If you do not like VSCP, the code can be easily adapted for other formats. I think the code is pretty easy to understand. Configuration takes place in the config.ini file and you have documentation on the code page. Below is a screenshot from MQTT explorer showing MQTT VSCP data for voltage, phase 1 delivered in real time

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-22-51-43-1024x594.png

And below the current data for the same phase

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-22-56-10-1024x630.png

Note the diagram at the bottom right. A smooth feature in MQTT explorer to quickly visualize data.

This is what it can look like when data is presented in node-red

This image has an empty alt attribute; its file name is Screenshot-from-2021-04-21-21-59-57.png

But it is very easy to create your own website and present live data there if you first send it to an MQTT broker taht havae websockets enabled. If you send VSCP events over that interface instead of some other random data, you have a solution that is both scaleable and reusable at all levels. I may do a howto on that to later.

This is how it looks in node-red

For a live demo check here

A driver for the VSCP daemon is here

Categories
Arduino ESP8266 HowTo's VSCP wifi

Howto: Snailmail sensor

Mail delivery. That is the physical type. That land in a box. Outside. There is one problem with it. You don’t know when or if you get any. So quite often, especially when there is a blizzard, one walk out to the postbox to find that it is empty. And if you have mail almost every day like me one wounder. “Are they late or is there no post for me today?” This usually ends up in me taking another trip to the postbox later when the blizzard is even worse.

A flag – the American style – would be possible. Needing binoculars. The later a habit that also might disturb my neighbors. But now, after all I work with computer. Something more firmware + electronics is my way. A perfect topic for a VSCP howto.

So the problem is simple: I need a notification when mail arrives in my mailbox. It also need to be a VSCP based solution. After all, I came up with the damn protocol.

So I set out to do this.

I like to lean new things. I therefore decided to use Platformio and the esp8266 with the Arduino core for this project. En environment I have not been playing with before. For both there are plenty of “getting started” write-ups available on the net.

This was a design that needed a battery. I have previously noticed the deep sleep capabilities of the ESP8266 so it should work. The device should take only ~20uA when sleeping and about 70mA when doing it’s work. In this app, we talk about a device that just need to wake up for a short moment once (when mail arrives) or twice a day (when I collect the mail).

You have the different sleep modes for the ESP8266 in the table below.

For deep sleep RST and CH_PD on the ESP8266 should be connected together. RST needs a pull-up. Now when set to deep sleep a low pulse on RST will wake the device.

So I came up with this schematic

Nothing strange here. Notice that I added a 1-wire temperature sensor also to get the temperature reported also when the lid is opened. Eagle file are here.

There is suggestions around to use a one shoot at the input. I tested without and it looks like things work as expected so I skipped it. An input switch will bounce so the startup of the unit will probably be a bot chaotic. This will take more juice form the battery and I will change this later on if I find it to be a problem.

I also replaced the reed switch with a mechanical switch on the mailbox. I will probably change that back later on but it was a little harder to get the reed switch approach to fit mechanically and I did not have the time to fix it the way I wanted to when I mounted the hardware.

I never reached 20uA in deep sleep. Rather 200 uA but that is OK for this test (theoretically 260 days or ~8 months on two AAA cells). I will investigate this further when I get more time. But apart from that everything works as expected.

For the firmware you can find it here. It is written so it can be used both with VSCP and MQTT (JSON VSCP events is sent). There are switches at the top of the file to select the version to build. With large EEPROM both can be used simultaneously.

I wrote a general library for VSCP and Arduino with the thought that it can be useful for somebody. Full info is here.

The sample code connects to wifi, then it connects to a VSCP remote host or a MQTT broker. Then it sends five events and then go to deep sleep again. The events that is sent are

The two versions of temperature events should be considered as a demo of level I and level II events.

So time to test. Put everything in a box and mount it in the postbox. Our postbox is located a bit from my house

I have a directional wifi antenna in that direction for some stuff in our garage so wifi is OK (-85 dBm) at the location.

I mounted everything a bit after midnight last night.

And now this morning

VSCP Works tells that something has happened at 05:14:44

And yes there is a small package in the mail. Demo accomplished. Might even be useful when connected to node-red so I can get a notification on my phone using Telegram. There may be a short write-up about that also later.

This same setup can of course be used for PIR sensors, window sensors and similar. One can even change the data sent from VSCP to some format. It’s a free world.

Enjoy!

Categories
CAN4VSCP HowTo's VSCP

Power #Raspberry Pi Zero (W) from a #CAN4VSCP module. #VSCP #iot #m2m

In remote automation setups it can be very inconvenient to use a Raspberry Pi because of the need for a USB power supply. In a current setup of mine I have a bunch of CAN4VSCP boards and want to link them from a remote location to my central system. The Raspberry Pi Zero (W) is low cost, easy to work with and could serve as a good way to accomplish this.

In the official docs the recommendation for powering a Raspberry Pi Zero is 5V at 1.2 A power adapter. This is at first very disappointing for my project as a CAN4VSCP board only can deliver a maximum of one amp from +5V and the board itself takes about 100 mA of this.

But looking further reveals that the needed power is much less that the official requirements if just using WiFi and BT. 120mA is mentioned. Testing this I can verify this value but with some peaks up to 300 mA. Powering a Raspberry Pi Zero W from a CAN4VSCP board would therefore be possible.

I test this with a Vilnius A/D module that is feed with 24V from the CAN4VSCP bus and I experience no problems. The Vilnius A/D module have GND on pin 1 and +5V on pin 12 of the termination block and this can be a good place to get the power for the Raspberry Pi Zero. All 5V CAN4VSCP modules have +5V and GND somewhere on the termination block. Another possible location to get the power from is using the programming header, which also is available on all CAN4VSCP modules. This connector have +5V on pin 2 and GND on pin 3.

To reduce the power need I turn of HDMI on the board as discussed here and here. One can also turn of the LED’s to reduce power consumption even more. There is actually no need for this in my case.

To turnoff HDMI on startup add

@reboot /usr/bin/tvservice -o

to the root crontab job using

sudo crontab -e

This will turn of HDMI on startup. To put the same in /etc/rc.local is another option.

I will use a 3.3V TTL Frankfurt RS-232 module to connect to the CAN bus directly from the Raspberry Pi. Allowing a connection directly from the RX/TX GPIO pins. But more on this later in a separate howto.

I will try to use node-red together with the node-red-contrib-socketcan to connect this module with the main system. I can then choose to connect over MQTT or VSCP tcp/ip, websocket or whatever. It is mostly plug and play to set this up. I will do a separate howto about it to later. My concerns is that there may be a risk that this will be to slow for my needs and in that case I will do a separated link between socketcan and MQTT coded in C. But I will use node-red anyhow so it is still needed.

Installing node-red on a Raspberry Pi system (any Debian derived system) is very easy. Use the script at https://nodered.org/docs/getting-started/raspberrypi which looks like this

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

and after that everything is installed issue

sudo systemctl enable nodered

and

suso systemctl start nodered

to install node-red as an auto staring service.

Thats it.

Categories
General HowTo's node-red VSCP

#node-red + #VSCP + PIR + door sensors howto

In a previous howto (Getting started with node-red-contrib-vscp) we were looking at how to display temperature data from VSCP modules in node-red. In this howto we will look at the same hardware setup but concentrate on output from one module in the setup, the CAN4VSCP Beijing module.

Beijing is a general I/O module which in this setup is used to detect input from three PIR sensors and three magnetic door sensors. The inputs are currently used like this

0Magnetic door sensor office door.
1Magnetic door sensor cellar door.
2Magnetic door sensor main entrance door.
3Unused.
4PIR sensor cellar.
5PIR sensor main entrance.
6Unused.
7PIR sensor inside of office door.

The Beijing module will send a CLASS1.INFORMATION, Type=ON/OFF event when any of the sensors are activated. The data for the events are defined as follows

Data byteDescription
0index. Often used as an index for channels within a module.
1Zone for which event applies to (0-255). 255 is all zones.
2Sub-zone for which event applies to (0-255). 255 is all sub-zones.

The index byte ( byte 0) will this contain the index for the PIR or switch as of above. Zone and subzone is used to indicate the sensors position and here I use bits 7,6,5 of the zone to indicate the floor (1 in this case) and the rest of the bits are set to the room number on that floor (2 in this case). Zone is therefore set to 0b00100010 = 0x22 = 34. Subzones are set to the same as the sensor index. Any schema of your own preference can be used for this. It is entirely up to the user.

The Beijing module is set to nickname id = 1. This is important as we need to filter on this nickname in case more PIR’s/switches are added in the future.

So as an example. If the main door is opened a CLASS1.INFORMATION, Type=ON (3) event will be sent and when it is closed again a CLASS1.INFORMATION, Type=OFF (4) event will be sent. The data will in both cases be

  • Byte 0 = 2 for main entrance door.
  • Byte 1 = 34, the set zone.
  • Byte 2 = 2, subzone for main entrance door.

In our node-red flow we start as in the previous howto with a connection to pi11 the Raspberry Pi that is connected to the Beijing module.

This is a vscp-tcp-in node and it is configured like this

Nothing fancy or strange here.

Without filtering we will get all events on the bus. But we are only interested in the events coming from the Beijing module with nickname = 1. So in the filter above we have decided to set a filter that only let events through from that specific module. This filter is set to the GUID for the interface the Beijing module is located on with the LSB set to the nickname of the Beijing module. Here

FF:FF:FF:FF:FF:FF:FF:FD:C0:A8:01:2C:00:00:00:01

Filter setting is therefore

As a side note the vscpl1drv-can4vscp driver is used (CAN interface is the Frankfurt RS-232 module) and settings for it is

So now we will only get events from the Beijing module.

The next step is to create a flow for CLASS1.INFORMATION, Type=ON and CLASS1.INFORMATION, Type=OFF events like this

Both are VSCP filter nodes set up like this

and this

Just letting through the wanted events (it’s a filter – right).

We feed the output from each of these filters to a switch node

The filter nodes send the sensor index as msg.payload on there outputs. Both switch nodes is configured like this

We could have used a simple function node to handle this also of course. The main thing is that we now get a node-red message on the correct flow channel when a sensor is activated/deactivated. The content of the message is of no importance. We set this in the next step with a change node. We use the node-red-contrib-ui-state-trail to visualize the sensor states in the node-red UI.

Each of the change nodes just set the msg.payload to true or false to suite the UI node-red-contrib-ui-state-trail expected input. Like this (in the set to true case)

For the ui-state-trail nodes they are more or less configured the same, something like this

There are other possibilities here of course. But with settings like this the end result looks like this

You see current state of a sensor and get a 24 hour state trail. The front door is open here today as it is summer outside even here in the middle of Sweden.

There is one problem with this, and that is that we don’t have a state for a sensor before something actually happens at the sensor, that is if it detects movement or a door is opened/closed. This may be important or not for a specific setup.

Luckily the Beijing module also can be configured to send out i/o states with a preset interval. This ability solves this problem. The event used by Beijing for this is CLASS1.DATA Type=1 I/O which has it’s data content specified as

0Data coding.
1-7Data with format defined by byte 0.

For the Beijing module this is three bytes. The first byte, the VSCP data coding byte is set to zero. This says that the two bytes that follows is defined as bits and unit=0, sensorindex=0. The first of the two bytes holds output states and the second hold input states. This flow looks like this

First we filter out the CLASS1.DATA, Type=1 I/O events. Then we check which inputs are set and send true/false to the correct ui-state-trail node. The function node is simple and coded like this

// CLASS1.DATA, Type=1, I/O
// vscpData[0] - Datacoding
// vscpData[1] - Output states
// vscpData[2] - Input states

var msgarray = [
    { "payload": false },
    { "payload": false },
    { "payload": false },
    { "payload": false },
    { "payload": false },
    { "payload": false },
    { "payload": false },
    { "payload": false }
];

for ( i=0;i<8;i++) {
    if ( msg.payload.vscpData[2] & (Math.pow(2,i)) ) {
        msgarray[i].payload = true;
    }
}
return msgarray;

The function node has eight outputs. Each is feed to the correct ui-state-trail node. Thats it.

With this in place we can now add alarms and control of automatic lights without much extra effort. You should also notice that even if we here use the CAN4VSCP module Beijing we could have used a mix of other techniques to receive the same result and functionality. If we at some point want to replace one of the PIR sensors with a Bluetooth or Zigbee solution we just need to code that sensor output as a VSCP event and everything will work as expected. The VSCP protocol is the abstraction that unite them all. Protocols and transfer techniques.

For reference is the node red flow and the Beijing module configuration listed below.

Have fun!
/Ake

Node-red flow for howto

[{"id":"82af1478.db09a8","type":"ui_statetrail","z":"d55b6e63.6443a8","group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"Office door state","label":"Office door state","states":[{"state":true,"col":"#009933","t":"bool","label":"Open"},{"state":false,"col":"#999999","t":"bool","label":"Closed"}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1120,"y":860,"wires":[[]]},{"id":"433ab88d.14a528","type":"vscpfilter","z":"d55b6e63.6443a8","vscppriority":"","vscpclass":"20","vscptype":"3","vscpguid":"","name":"CLASS1.INFORMATION, ON","x":200,"y":1000,"wires":[["e7c014db.d982f8"]]},{"id":"dba27e7e.901248","type":"vscpfilter","z":"d55b6e63.6443a8","vscppriority":"","vscpclass":"20","vscptype":"4","vscpguid":"","name":"CLASS1.INFORMATION, OFF","x":210,"y":1100,"wires":[["62cdb0fe.3fad38"]]},{"id":"e7c014db.d982f8","type":"switch","z":"d55b6e63.6443a8","name":"","property":"payload.vscpData[0]","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"4","vt":"num"},{"t":"eq","v":"5","vt":"num"},{"t":"eq","v":"6","vt":"num"},{"t":"eq","v":"7","vt":"num"}],"checkall":"true","repair":false,"outputs":8,"x":430,"y":1000,"wires":[["6a7f782a.68e4f"],["8354a8b7.540938"],["59434168.7bf8f"],["8f7c7c69.bf4ee"],["1ba6d376.51f02d"],["3d18e2c3.e0faee"],["23a97f1c.51cf"],["32f01e41.9a4f92"]]},{"id":"6a7f782a.68e4f","type":"change","z":"d55b6e63.6443a8","name":"office=true","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":860,"wires":[["82af1478.db09a8"]]},{"id":"95de756f.fc4cf","type":"ui_statetrail","z":"d55b6e63.6443a8","group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"Cellar Door State","label":"Cellar Door State","states":[{"state":true,"col":"#009933","t":"bool","label":"Open"},{"state":false,"col":"#999999","t":"bool","label":"Closed"}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1130,"y":900,"wires":[[]]},{"id":"8354a8b7.540938","type":"change","z":"d55b6e63.6443a8","name":"Cellar=true","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":900,"wires":[["95de756f.fc4cf"]]},{"id":"f7dc6e17.85bd28","type":"ui_statetrail","z":"d55b6e63.6443a8","group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"Front door state","label":"Front Door state","states":[{"state":true,"col":"#009933","t":"bool","label":"Open"},{"state":false,"col":"#999999","t":"bool","label":"Closed"}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1120,"y":940,"wires":[[]]},{"id":"59434168.7bf8f","type":"change","z":"d55b6e63.6443a8","name":"front=true","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":940,"wires":[["f7dc6e17.85bd28"]]},{"id":"1dadefe2.73b87","type":"ui_statetrail","z":"d55b6e63.6443a8","d":true,"group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"Unuse","label":"Unused","states":[{"state":true,"col":"#009933","t":"bool","label":""},{"state":false,"col":"#999999","t":"bool","label":""}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":false,"blanklabel":"","x":1090,"y":980,"wires":[[]]},{"id":"8f7c7c69.bf4ee","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":980,"wires":[["1dadefe2.73b87"]]},{"id":"6162e7b8.cc655","type":"ui_statetrail","z":"d55b6e63.6443a8","group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"PIR Cellar","label":"PIR Cellar","states":[{"state":true,"col":"#009933","t":"bool","label":"Detect"},{"state":false,"col":"#999999","t":"bool","label":"Rest"}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1110,"y":1020,"wires":[[]]},{"id":"1ba6d376.51f02d","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1020,"wires":[["6162e7b8.cc655"]]},{"id":"159222d2.262acd","type":"ui_statetrail","z":"d55b6e63.6443a8","group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"PIR Main entrance","label":"PIR Main entrance","states":[{"state":true,"col":"#009933","t":"bool","label":"Detetc"},{"state":false,"col":"#999999","t":"bool","label":"Rest"}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1130,"y":1060,"wires":[[]]},{"id":"3d18e2c3.e0faee","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1060,"wires":[["159222d2.262acd"]]},{"id":"bfc9343a.c2fde8","type":"ui_statetrail","z":"d55b6e63.6443a8","d":true,"group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"Unused","label":"Unused","states":[{"state":true,"col":"#009933","t":"bool","label":""},{"state":false,"col":"#999999","t":"bool","label":""}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1100,"y":1100,"wires":[[]]},{"id":"23a97f1c.51cf","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1100,"wires":[["bfc9343a.c2fde8"]]},{"id":"f2f76475.1e32a","type":"ui_statetrail","z":"d55b6e63.6443a8","group":"86ca358f.1ef4f8","order":6,"width":"12","height":"2","name":"PIR Office Door","label":"PIR Office Door","states":[{"state":true,"col":"#fe0000","t":"bool","label":"Open"},{"state":false,"col":"#999999","t":"bool","label":"Closed"}],"periodLimit":"24","periodLimitUnit":"3600","timeformat":"HH:mm","tickmarks":4,"persist":false,"legend":"3","combine":true,"blanklabel":"","x":1120,"y":1140,"wires":[[]]},{"id":"32f01e41.9a4f92","type":"change","z":"d55b6e63.6443a8","name":"PIR Office = true","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":1140,"wires":[["f2f76475.1e32a"]]},{"id":"62cdb0fe.3fad38","type":"switch","z":"d55b6e63.6443a8","name":"","property":"payload.vscpData[0]","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"4","vt":"num"},{"t":"eq","v":"5","vt":"num"},{"t":"eq","v":"6","vt":"num"},{"t":"eq","v":"7","vt":"num"}],"checkall":"true","repair":false,"outputs":8,"x":430,"y":1360,"wires":[["c625622d.26fd08"],["e3c1ac7f.8d3a1"],["4648539f.147a04"],["a363d163.6b4ec8"],["8c44a2c4.ed5de8"],["99117390.c4adb8"],["ee2b8418.ba485"],["2a250160.c423b6"]]},{"id":"c625622d.26fd08","type":"change","z":"d55b6e63.6443a8","name":"office=false","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":1220,"wires":[["82af1478.db09a8"]]},{"id":"e3c1ac7f.8d3a1","type":"change","z":"d55b6e63.6443a8","name":"Cellar=false","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":1260,"wires":[["95de756f.fc4cf"]]},{"id":"4648539f.147a04","type":"change","z":"d55b6e63.6443a8","name":"front=false","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":1300,"wires":[["f7dc6e17.85bd28"]]},{"id":"a363d163.6b4ec8","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1340,"wires":[["1dadefe2.73b87"]]},{"id":"8c44a2c4.ed5de8","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1380,"wires":[["6162e7b8.cc655"]]},{"id":"99117390.c4adb8","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1420,"wires":[["159222d2.262acd"]]},{"id":"ee2b8418.ba485","type":"change","z":"d55b6e63.6443a8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":1460,"wires":[["bfc9343a.c2fde8"]]},{"id":"2a250160.c423b6","type":"change","z":"d55b6e63.6443a8","name":"PIR Office = false","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":1500,"wires":[["f2f76475.1e32a"]]},{"id":"8d3f89ae.3e49d8","type":"vscp-tcp-in","z":"d55b6e63.6443a8","name":"pi11","host":"e596ab59.2b98c8","username":"admin","password":"__PWRD__","filter":"3f11c8c2.e2dcd","keyctx":"pi11a","x":70,"y":860,"wires":[["433ab88d.14a528","dba27e7e.901248","14d7cd7f.7e456b"]]},{"id":"14d7cd7f.7e456b","type":"vscpfilter","z":"d55b6e63.6443a8","vscppriority":"","vscpclass":"15","vscptype":"1","vscpguid":"","name":"CLASS1.DATA, I/O","x":170,"y":1740,"wires":[["e712b13e.7d21a8"]]},{"id":"e712b13e.7d21a8","type":"function","z":"d55b6e63.6443a8","name":"Check input states","func":"\n// CLASS1.DATA, Type=1, I/O\n// vscpData[0] - Datacoding\n// vscpData[1] - Output states\n// vscpData[2] - Input states\n\nvar msgarray = [\n    { \"payload\": false },\n    { \"payload\": false },\n    { \"payload\": false },\n    { \"payload\": false },\n    { \"payload\": false },\n    { \"payload\": false },\n    { \"payload\": false },\n    { \"payload\": false }\n];\n\nfor ( i=0;i<8;i++) {\n    if ( msg.payload.vscpData[2] & (Math.pow(2,i)) ) {\n        msgarray[i].payload = true;\n    }\n}\nreturn msgarray;","outputs":8,"noerr":0,"x":690,"y":1740,"wires":[["82af1478.db09a8"],["95de756f.fc4cf"],["f7dc6e17.85bd28"],["1dadefe2.73b87"],["6162e7b8.cc655"],["159222d2.262acd"],["bfc9343a.c2fde8"],["f2f76475.1e32a"]]},{"id":"86ca358f.1ef4f8","type":"ui_group","z":"","name":"States","tab":"7cdacae9.143d2c","order":3,"disp":true,"width":"12","collapse":false},{"id":"e596ab59.2b98c8","type":"vscp-tcp-config-host","z":"","name":"pi11","host":"192.168.1.44","port":"9598","timeout":"10000","interface":"","keepalive":"10000"},{"id":"3f11c8c2.e2dcd","type":"vscp-tcp-config-filter","z":"","name":"Only events from Beijing","filterPriority":"0","maskPriority":"0","filterClass":"0","maskClass":"0","filterType":"0","maskType":"0","filterGuid":"FF:FF:FF:FF:FF:FF:FF:FD:C0:A8:01:2C:11:22:00:01","maskGuid":"FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF"},{"id":"7cdacae9.143d2c","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Beijing module configuration

Can be loaded with VSCP works.

<?xml version = "1.0" encoding = "UTF-8" ?>
<registerset>
<register offset='0' page='0'>
<value>0x00</value>
<description>Zone
Zone this module belongs to</description>
</register>
<register offset='1' page='0'>
<value>0x00</value>
<description>Sub zone
Sub zone this module belongs to</description>
</register>
<register offset='2' page='0'>
<value>0x00</value>
<description>Sub zone I/O 0
Sub zone for I/O channel 0</description>
</register>
<register offset='3' page='0'>
<value>0x01</value>
<description>Sub zone I/O 1
Sub zone for I/O channel 1</description>
</register>
<register offset='4' page='0'>
<value>0x02</value>
<description>Sub zone I/O 2
Sub zone for I/O channel 2</description>
</register>
<register offset='5' page='0'>
<value>0x03</value>
<description>Sub zone I/O 3
Sub zone for I/O channel 3</description>
</register>
<register offset='6' page='0'>
<value>0x04</value>
<description>Sub zone I/O 4
Sub zone for I/O channel 4</description>
</register>
<register offset='7' page='0'>
<value>0x05</value>
<description>Sub zone I/O 5
Sub zone for I/O channel 5</description>
</register>
<register offset='8' page='0'>
<value>0x06</value>
<description>Sub zone I/O 6
Sub zone for I/O channel 6</description>
</register>
<register offset='9' page='0'>
<value>0x07</value>
<description>Sub zone I/O 7
Sub zone for I/O channel 7</description>
</register>
<register offset='10' page='0'>
<value>0x08</value>
<description>Sub zone I/O 8
Sub zone for I/O channel 8</description>
</register>
<register offset='11' page='0'>
<value>0x09</value>
<description>Sub zone I/O 9
Sub zone for I/O channel 9</description>
</register>
<register offset='12' page='0'>
<value>0x00</value>
<description>I/O direction MSB
Most significant part of I/O directions register. Set bit to zero for output and
one for input.

Bit 7 - Reserved.
Bit 6 - Reserved.
Bit 5 - Reserved.
Bit 4 - Reserved.
Bit 3 - Reserved.
Bit 2 - Reserved.
Bit 1 - Direction for I/O channel 9 - (RA0). 0=output. 1=input.
Bit 0 - Direction for I/O channel 8 - (RA1). 0=output. 1=input.
</description>
</register>
<register offset='13' page='0'>
<value>0x00</value>
<description>I/O direction LSB
Least significant part of I/O directions register.Set bit to zero for output and
one for input.

Bit 7 - Direction for I/O channel 7 - (RA2). 0=output. 1=input.
Bit 6 - Direction for I/O channel 6 - (RC7). 0=output. 1=input.
Bit 5 - Direction for I/O channel 5 - (RC6). 0=output. 1=input.
Bit 4 - Direction for I/O channel 4 - (RC5). 0=output. 1=input.
Bit 3 - Direction for I/O channel 3 - (RC4). 0=output. 1=input.
Bit 2 - Direction for I/O channel 2 - (RC3). 0=output. 1=input.
Bit 1 - Direction for I/O channel 1 - (RB1). 0=output. 1=input.
Bit 0 - Direction for I/O channel 0 - (RB0). 0=output. 1=input.
</description>
</register>
<register offset='14' page='0'>
<value>0x00</value>
<description>I/O channel 0 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='15' page='0'>
<value>0x00</value>
<description>I/O channel 1 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='16' page='0'>
<value>0x00</value>
<description>I/O channel 2 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='17' page='0'>
<value>0x00</value>
<description>I/O channel 3 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='18' page='0'>
<value>0x00</value>
<description>I/O channel 4 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='19' page='0'>
<value>0x00</value>
<description>I/O channel 5 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='20' page='0'>
<value>0x00</value>
<description>I/O channel 6 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='21' page='0'>
<value>0x00</value>
<description>I/O channel 7 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='22' page='0'>
<value>0x00</value>
<description>I/O channel 8 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='23' page='0'>
<value>0x00</value>
<description>I/O channel 9 status register
Read or write the state of I/O channel 0 in this register.
0 - is returned for an inactive input or a low output. A written zero will set an
output channel low.
1 - is returned for an active input or a high output. A written one will set an
output channel high.
</description>
</register>
<register offset='24' page='0'>
<value>0x98</value>
<description>Output 0 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='25' page='0'>
<value>0x98</value>
<description>Output 1 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='26' page='0'>
<value>0x98</value>
<description>Output 2 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='27' page='0'>
<value>0x98</value>
<description>Output 3 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='28' page='0'>
<value>0x98</value>
<description>Output 4 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='29' page='0'>
<value>0x98</value>
<description>Output 5 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='30' page='0'>
<value>0x98</value>
<description>Output 6 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='31' page='0'>
<value>0x98</value>
<description>Output 7 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='32' page='0'>
<value>0x98</value>
<description>Output 8 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='33' page='0'>
<value>0x98</value>
<description>Output 9 control register
The output control bits enable/disable intelligent functionality for a channel set
as output.
Bit 0 - Enable pulse.
Bit 1 - If set: Alarm sent when protection timer triggers.
Bit 2 - Protection timer enable.
Bit 3 - Send On event when output goes to active state.
Bit 4 - Send Off event when output goes to inactive state.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable output.
</description>
</register>
<register offset='34' page='0'>
<value>0x83</value>
<description>Input 0 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='35' page='0'>
<value>0x83</value>
<description>Input 1 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='36' page='0'>
<value>0x83</value>
<description>Input 2 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='37' page='0'>
<value>0x83</value>
<description>Input 3 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='38' page='0'>
<value>0x83</value>
<description>Input 4 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='39' page='0'>
<value>0x83</value>
<description>Input 5 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='40' page='0'>
<value>0x83</value>
<description>Input 6 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='41' page='0'>
<value>0x83</value>
<description>Input 7 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='42' page='0'>
<value>0x83</value>
<description>Input 8 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='43' page='0'>
<value>0x83</value>
<description>Input 9 control register
The input control bits enable/disable intelligent functionality for a channel set
as input.
Bit 0 - Send On/TurnOn event when input goes to active state.
Bit 1 - Send Off/TurnOff event when input goes to inactive state.
Bit 2 - 0 = Send On/off events. 1=Send turnon/turnoff events (if activated).
 Different meaning in button input mode where 0 = TurnOn and 1 = TurnOff.
Bit 3 - Alarm event sent if input goes low.
Bit 4 - Alarm event sent if input goes high.
Bit 5 - Continuous alarm.
Bit 6 - Activate Button imput mode. Only TurnOff or TurnOn is sent when an input
goes low and button input mode is activated.
Bit 7 - Enable input.
</description>
</register>
<register offset='44' page='0'>
<value>0x00</value>
<description>Module Control register
It is possible to control general module behaviour in this register.
Bit 0 - Turn of input event repeat.
Bit 1 - Reserved.
Bit 2 - Reserved.
Bit 3 - Reserved.
Bit 4 - Reserved.
Bit 5 - Reserved.
Bit 6 - Reserved.
Bit 7 - Enable weak pullups.
 </description>
</register>
<register offset='45' page='0'>
<value>0x00</value>
<description>Input stream sample time
This is the time in seconds between input stream samples. Set to zero to disable.
CLASS1.DATA is sent with data coding=0(bits), unit=0, sensor=0 for the inputs/outputs
as set here. First byte is outputs, second byte is inputs. </description>
</register>
<register offset='46' page='0'>
<value>0x03</value>
<description>Debounce count
This is the number of counts a button input signal should be low to be regarded as
actice. Each count represents 10 ms. </description>
</register>
<register offset='47' page='0'>
<value>0x02</value>
<description>Short pulse duration
This is the duration for the short pulse action. Each count represents 10 ms.  A
zero vaue gives a pulse that is the shortest possible. </description>
</register>
<register offset='0' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 0 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='1' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 0 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='2' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 1 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='3' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 1 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='4' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 2 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='5' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 2 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='6' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 3 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='7' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 3 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='8' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 4 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='9' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 4 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='10' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 5 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='11' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 5 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='12' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 6 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='13' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 6 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='14' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 7 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='15' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 7 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='16' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 8 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='17' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 8 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='18' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 9 MSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='19' page='1'>
<value>0x00</value>
<description>Output pulse time register for output 9 LSB
This is the pulse time for the each output expressed in seconds. This can be used
to make an output turn on and off with a certain preset interval. The min pulse time
is 1 second and the max time is 65535 seconds which is about 18 hours. Set to zero
(default) for no pulse time i.e. the output will be steady on/off.
To start a pulse sequence first write the pulse time to this register and then set
the corresponding bit in the output status register to start the output. The pulse
train is terminated by writing on or off (1 or 0) to the output status register.
</description>
</register>
<register offset='20' page='1'>
<value>0x00</value>
<description>Output protection time register for output 0 MSB
This is the output protection time. An output will be inactivated if not written
to before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='21' page='1'>
<value>0x00</value>
<description>Output protection time register for output 0 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='22' page='1'>
<value>0x00</value>
<description>Output protection time register for output 1 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='23' page='1'>
<value>0x00</value>
<description>Output protection time register for output 1 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='24' page='1'>
<value>0x00</value>
<description>Output protection time register for output 2 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='25' page='1'>
<value>0x00</value>
<description>Output protection time register for output 2 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='26' page='1'>
<value>0x00</value>
<description>Output protection time register for output 3 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='27' page='1'>
<value>0x00</value>
<description>Output protection time register for output 3 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='28' page='1'>
<value>0x00</value>
<description>Output protection time register for output 4 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='29' page='1'>
<value>0x00</value>
<description>Output protection time register for output 4 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='30' page='1'>
<value>0x00</value>
<description>Output protection time register for output 5 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='31' page='1'>
<value>0x00</value>
<description>Output protection time register for output 5 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='32' page='1'>
<value>0x00</value>
<description>Output protection time register for output 6 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='33' page='1'>
<value>0x00</value>
<description>Output protection time register for output 6 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='34' page='1'>
<value>0x00</value>
<description>Output protection time register for output 7 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='35' page='1'>
<value>0x00</value>
<description>Output protection time register for output 7 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='36' page='1'>
<value>0x00</value>
<description>Output protection time register for output 8 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='37' page='1'>
<value>0x00</value>
<description>Output protection time register for output 8 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='38' page='1'>
<value>0x00</value>
<description>Output protection time register for output 9 MSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='39' page='1'>
<value>0x00</value>
<description>Output protection time register for output 9 LSB
This is the output protection time. A output will be inactivated if not written to
before this time has elapsed.
Set to zero to disable (default). The max time is 65535 seconds which is about 18
hours.
The registers can be as an example be used as a security feature to ensure that
an output is deactivated after a preset time even if the controlling device failed
to deactivate the output. </description>
</register>
<register offset='0' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will not be checked and events from all nodes will be accepted. </description>
</register>
<register offset='1' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/sub zone of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='2' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='3' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of thsi decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='4' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='5' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='6' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='7' page='2'>
<value>0x00</value>
<description>Decision matrix row 0: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='8' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will not be checked and events from all nodes will be accepted. </description>
</register>
<register offset='9' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/subzone
information of an event. That is the zone/sub zone of the machine must match the
one of the event to trigger the DM row. </description>
</register>
<register offset='10' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='11' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='12' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='13' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='14' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='15' page='2'>
<value>0x00</value>
<description>Decision matrix row 1: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='16' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will not be checked and events from all nodes will be accepted. </description>
</register>
<register offset='17' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/sub zone of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='18' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='19' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='20' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='21' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='22' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='23' page='2'>
<value>0x00</value>
<description>Decision matrix row 2: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='24' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will not be checked and events from all nodes will be accepted. </description>
</register>
<register offset='25' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/sub zone of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='26' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='27' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='28' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='29' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='30' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='31' page='2'>
<value>0x00</value>
<description>Decision matrix row 3: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='32' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will notbe checked and events from all nodes will be accepted. </description>
</register>
<register offset='33' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/sub zone of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='34' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='35' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='36' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='37' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='38' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='39' page='2'>
<value>0x00</value>
<description>Decision matrix row 4: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='40' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Oaddr 
Originating address. Set to nickname for node that should trigger  action. Oaddr
is the originating address. We are only interested in messages from the node given
here. 0x00 is segment controller and 0xff is a node without a nickname. If bit 6
of flags is set oaddr will not be checked and events from all nodes will be accepted.
</description>
</register>
<register offset='41' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/sub zone of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='42' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='43' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='44' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='45' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='46' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='47' page='2'>
<value>0x00</value>
<description>Decision matrix row 5: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='48' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will not be checked and events from all nodes will be accepted. </description>
</register>
<register offset='49' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/subzone one of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='50' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='51' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='52' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='53' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='54' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='55' page='2'>
<value>0x00</value>
<description>Decision matrix row 6: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='56' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Oaddr 
Originating address. Set to nickname for node that should trigger action. Oaddr is
the originating address. We are only interested in messages from the node given here.
0x00 is segment controller and 0xff is a node without a nickname. If bit 6 of flags
is set oaddr will not be checked and events from all nodes will be accepted. </description>
</register>
<register offset='57' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: flags 
Flags. Set selection behaviour.
The enable bit can be used to disable a decision matrix row while it is edited.
The zone and use sub zone bits can be activated to have a check on the zone/sub
zone information of an event. That is the zone/subzone one of the machine must match
the one of the event to trigger the DM row. </description>
</register>
<register offset='58' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Class mask (low eight bits) 
The lowest eight bits of the class mask that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class mask is stored in bit 1 of the flag byte. </description>
</register>
<register offset='59' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Class filter (low eight bits) 
The lowest eight bits of the class filter that defines the events that should trigger
the action of this decision matrix row.
Bit 8 of the class filter is stored in bit 1 of the flag byte. </description>
</register>
<register offset='60' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Type mask
Type mask that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='61' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Type filter
Type filter that defines the events that should trigger the action of this decision
matrix row.</description>
</register>
<register offset='62' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Action
This is the action or operation that should be performed if the filtering is satisfied.
Only action code 0x00 is predefined and means No-Operation. All other codes are application
specific and typical application defined codes could do measurement, send predefined
event etc.</description>
</register>
<register offset='63' page='2'>
<value>0x00</value>
<description>Decision matrix row 7: Action parameter
A numeric action parameter can be set and its meaning is application specific.</description>
</register>
<register offset='128' page='0'>
<value>0x00</value>
<description>Alarm Status Register</description>
</register>
<register offset='129' page='0'>
<value>0x01</value>
<description>VSCP Major version number</description>
</register>
<register offset='130' page='0'>
<value>0x06</value>
<description>VSCP Minor version number</description>
</register>
<register offset='131' page='0'>
<value>0x00</value>
<description>Node Control Flags
 test</description>
</register>
<register offset='132' page='0'>
<value>0x00</value>
<description>User ID 0</description>
</register>
<register offset='133' page='0'>
<value>0x00</value>
<description>User ID 1</description>
</register>
<register offset='134' page='0'>
<value>0x00</value>
<description>User ID 2</description>
</register>
<register offset='135' page='0'>
<value>0xFF</value>
<description>User ID 3</description>
</register>
<register offset='136' page='0'>
<value>0xFF</value>
<description>User ID 4</description>
</register>
<register offset='137' page='0'>
<value>0x00</value>
<description>Manufacturer device id 0</description>
</register>
<register offset='138' page='0'>
<value>0x0F</value>
<description>Manufacturer device id 1</description>
</register>
<register offset='139' page='0'>
<value>0x0B</value>
<description>Manufacturer device id 2</description>
</register>
<register offset='140' page='0'>
<value>0x16</value>
<description>Manufacturer device id 3</description>
</register>
<register offset='141' page='0'>
<value>0x01</value>
<description>Manufacturer sub device id 0</description>
</register>
<register offset='142' page='0'>
<value>0x00</value>
<description>Manufacturer sub device id 1</description>
</register>
<register offset='143' page='0'>
<value>0x00</value>
<description>Manufacturer sub device id 2</description>
</register>
<register offset='144' page='0'>
<value>0x00</value>
<description>Manufacturer sub device id 3</description>
</register>
<register offset='145' page='0'>
<value>0x01</value>
<description>Nickname id</description>
</register>
<register offset='146' page='0'>
<value>0x00</value>
<description>Page select register MSB</description>
</register>
<register offset='147' page='0'>
<value>0x00</value>
<description>Page select register LSB</description>
</register>
<register offset='148' page='0'>
<value>0x01</value>
<description>Firmware major version number</description>
</register>
<register offset='149' page='0'>
<value>0x01</value>
<description>Firmware minor version number</description>
</register>
<register offset='150' page='0'>
<value>0x06</value>
<description>Firmware sub minor version number</description>
</register>
<register offset='151' page='0'>
<value>0x01</value>
<description>Boot loader algorithm</description>
</register>
<register offset='152' page='0'>
<value>0x08</value>
<description>Buffer Size</description>
</register>
<register offset='153' page='0'>
<value>0x03</value>
<description>Number of register pages used.</description>
</register>
<register offset='208' page='0'>
<value>0x01</value>
<description>GUID Byte 15, MSB
GUID=01:00:00:00:00:00:00:00:00:00:00:00:06:00:00:0F</description>
</register>
<register offset='209' page='0'>
<value>0x00</value>
<description>GUID Byte 14</description>
</register>
<register offset='210' page='0'>
<value>0x00</value>
<description>GUID Byte 13</description>
</register>
<register offset='211' page='0'>
<value>0x00</value>
<description>GUID Byte 12</description>
</register>
<register offset='212' page='0'>
<value>0x00</value>
<description>GUID Byte 11</description>
</register>
<register offset='213' page='0'>
<value>0x00</value>
<description>GUID Byte 10</description>
</register>
<register offset='214' page='0'>
<value>0x00</value>
<description>GUID Byte 9</description>
</register>
<register offset='215' page='0'>
<value>0x00</value>
<description>GUID Byte 8</description>
</register>
<register offset='216' page='0'>
<value>0x00</value>
<description>GUID Byte 7</description>
</register>
<register offset='217' page='0'>
<value>0x00</value>
<description>GUID Byte 6</description>
</register>
<register offset='218' page='0'>
<value>0x00</value>
<description>GUID Byte 5</description>
</register>
<register offset='219' page='0'>
<value>0x00</value>
<description>GUID Byte 4</description>
</register>
<register offset='220' page='0'>
<value>0x06</value>
<description>GUID Byte 3</description>
</register>
<register offset='221' page='0'>
<value>0x00</value>
<description>GUID Byte 2</description>
</register>
<register offset='222' page='0'>
<value>0x00</value>
<description>GUID Byte 1</description>
</register>
<register offset='223' page='0'>
<value>0x0F</value>
<description>GUID Byte 0, LSB</description>
</register>
<register offset='224' page='0'>
<value>0x77</value>
<description>Module Description File URL, MSB
http://www.eurosource.se/beijing_2.xml</description>
</register>
<register offset='225' page='0'>
<value>0x77</value>
<description>Module Description File URL</description>
</register>
<register offset='226' page='0'>
<value>0x77</value>
<description>Module Description File URL</description>
</register>
<register offset='227' page='0'>
<value>0x2E</value>
<description>Module Description File URL</description>
</register>
<register offset='228' page='0'>
<value>0x65</value>
<description>Module Description File URL</description>
</register>
<register offset='229' page='0'>
<value>0x75</value>
<description>Module Description File URL</description>
</register>
<register offset='230' page='0'>
<value>0x72</value>
<description>Module Description File URL</description>
</register>
<register offset='231' page='0'>
<value>0x6F</value>
<description>Module Description File URL</description>
</register>
<register offset='232' page='0'>
<value>0x73</value>
<description>Module Description File URL</description>
</register>
<register offset='233' page='0'>
<value>0x6F</value>
<description>Module Description File URL</description>
</register>
<register offset='234' page='0'>
<value>0x75</value>
<description>Module Description File URL</description>
</register>
<register offset='235' page='0'>
<value>0x72</value>
<description>Module Description File URL</description>
</register>
<register offset='236' page='0'>
<value>0x63</value>
<description>Module Description File URL</description>
</register>
<register offset='237' page='0'>
<value>0x65</value>
<description>Module Description File URL</description>
</register>
<register offset='238' page='0'>
<value>0x2E</value>
<description>Module Description File URL</description>
</register>
<register offset='239' page='0'>
<value>0x73</value>
<description>Module Description File URL</description>
</register>
<register offset='240' page='0'>
<value>0x65</value>
<description>Module Description File URL</description>
</register>
<register offset='241' page='0'>
<value>0x2F</value>
<description>Module Description File URL</description>
</register>
<register offset='242' page='0'>
<value>0x62</value>
<description>Module Description File URL</description>
</register>
<register offset='243' page='0'>
<value>0x65</value>
<description>Module Description File URL</description>
</register>
<register offset='244' page='0'>
<value>0x69</value>
<description>Module Description File URL</description>
</register>
<register offset='245' page='0'>
<value>0x6A</value>
<description>Module Description File URL</description>
</register>
<register offset='246' page='0'>
<value>0x69</value>
<description>Module Description File URL</description>
</register>
<register offset='247' page='0'>
<value>0x6E</value>
<description>Module Description File URL</description>
</register>
<register offset='248' page='0'>
<value>0x67</value>
<description>Module Description File URL</description>
</register>
<register offset='249' page='0'>
<value>0x5F</value>
<description>Module Description File URL</description>
</register>
<register offset='250' page='0'>
<value>0x32</value>
<description>Module Description File URL</description>
</register>
<register offset='251' page='0'>
<value>0x2E</value>
<description>Module Description File URL</description>
</register>
<register offset='252' page='0'>
<value>0x78</value>
<description>Module Description File URL</description>
</register>
<register offset='253' page='0'>
<value>0x6D</value>
<description>Module Description File URL</description>
</register>
<register offset='254' page='0'>
<value>0x6C</value>
<description>Module Description File URL</description>
</register>
<register offset='255' page='0'>
<value>0x00</value>
<description>Module Description File URL, LSB</description>
</register>
</registerset>
Categories
HowTo's node-js node-red VSCP

Getting started with node-red-contrib-vscp

In this howto I will give a short introduction on how to setup a system that use node-red-contrib-vscp (1.2.1) and the node-red-contrib-vscp-tcp (1.2.1) nodes.

The system we will talk to is called pi11 here at the office. It is mounted as a test system on a wall in one of the rooms just inside the entrance (office entrance below).

The setup is used to monitor some doors and two temperatures (the room in which it is mounted in and in the main entrance). The setup also control a very load alarm beeper. We will describe control of it in another post.

Hardware wise the setup consist of a

It runs Raspbian Buster with the VSCP daemon and node-red running on it.

Connecting to this setup with vscpworks will show the events generated.

You see mostly heartbeats from the nodes and from the VSCP daemon but also some temperature readings. Above is the temperature reading for the main entrance selected (sensor index 0) and below for the room (sensor index 6).

We will only deal with the temperatures in this howto but below is the sequence generated when someone walk out of the office and back in again.

This involves a gang of PIR sensors and some magnetic sensors but I will go thru that setup in a separate howto later.

For the temperature readings you may notice that one is coded as a float and one is coded as a string. This is the two formats the CAN4VSCP Kelvin 1-wire module can send measurement events on. We could have instructed the driver in the VSCP Daemon to automatically translate them to Level II measurement event if we wanted. But for this demo it is just good and a bit more real world if they are of different coding.

Note also that the unit for both temperatures are set to 1, meaning that it is in degrees Celsius. Other possibilities here would be 0 (Kelvin) and 2 (Fahrenheit).

Here we do our node-red setup on the pi11 system itself. We could of course have done it on a machine in some other part of the office or in another part of the world instead.

First we test the connection to the VSCP daemon to see if we see any events in node-red

We need to have node-red-contib-vscp-tcp installed or this. Install it in the Manage Palette in node-red.
[{"id":"69a3065d.809ce","type":"vscp-tcp-in","z":"d55b6e63.6443a8","name":"pi11","host":"4aea1560.bc50a4","username":"admin","password":"PWRD","filter":"","keyctx":"fghuy","x":210,"y":80,"wires":[["c754d7c6.1a22a8"]]},{"id":"c754d7c6.1a22a8","type":"debug","z":"d55b6e63.6443a8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":430,"y":80,"wires":[]},{"id":"4aea1560.bc50a4","type":"vscp-tcp-config-host","z":"","name":"Localhost","host":"localhost","port":"9598","timeout":"10000","interface":"","keepalive":""}]

We have a setup that is like this

That is a connection to the VSCP Daemon on the local host using default credentials (not very secure). No filter is set up so all events will be delivered.

The server setup looks like this

Nothing very exciting here either.

If we deploy this setup we will see VSCP events in the debug window.

The actual event is in msg.payload

And above is the VSCP event from temperature sensor 0 (databyte 0 is 72 = 0x48 = 010 01 000b (coding,unit,sensorindex) . The rest of the data is the temperature as a string (“12.500”), as the coding is 010b = string. And the string is in degrees Celsius as the unit is 01b.

Don’t get afraid. There is a node-red node that handle all this for you. Install node-red-contrib-vscp and use the event2value. It will take care of all this for you.

If we insert it in the flow

[{"id":"69a3065d.809ce","type":"vscp-tcp-in","z":"d55b6e63.6443a8","name":"pi11","host":"4aea1560.bc50a4","username":"admin","password":"PWRD","filter":"","keyctx":"pi11a","x":210,"y":80,"wires":[["fa389899.e0f0a"]]},{"id":"c754d7c6.1a22a8","type":"debug","z":"d55b6e63.6443a8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":670,"y":80,"wires":[]},{"id":"fa389899.e0f0a","type":"event2value","z":"d55b6e63.6443a8","btransparent":true,"bvalue2payload":false,"name":"","x":450,"y":80,"wires":[["c754d7c6.1a22a8"]]},{"id":"4aea1560.bc50a4","type":"vscp-tcp-config-host","z":"","name":"Localhost","host":"localhost","port":"9598","timeout":"10000","interface":"","keepalive":""}]

and check Transparent in it’s setup

We will still get the events in the debug window. But if we investigate a temperature event we see that there is a msg.measurement object also added,

The msg.measurement object is only added to measurement events. It contains all relevant values associated with measurements. The original event is still available in msg.payload.

If we we uncheck the Transparent checkbox only measurement events will be passed through the event2value node.

We can also instead check the other checkbox like this

Now we will get an even simpler handling of measurement values. The value to payload checkbox will put the value in msg.payload. All measurement data is available as before in msg.measurement and the original event is preserved in msg.event.

Many times, if not even always, we want to take care of a measurement value and do something with them. Most standard nodes in node-red expect the value to be located in msg.payload. Just as we explain above it is easy to adopt to this standard while still preserved important information such as unit, origin etc. The need to separate data from a specific sensor into it’s own line of flow is often needed in this. The GUID for a VSCP node is one thing to filter on and in this the VSCP filter node can do the work. But other items relates to measurements such as unit, sensorindex, zone, subzone may also have a need to be filtered on.

This can be done with a standard node-red function node. with code like

if ( msg.measurement.sensorindex === 6) {
    return msg;
}

From here we can do some real work. For example display the two temperatures in the UI with a flow like this.

resulting in this UI output

[{"id":"e8317c43.6b84b","type":"vscp-tcp-in","z":"d55b6e63.6443a8","name":"pi11","host":"e596ab59.2b98c8","username":"admin","password":"PWRD","filter":"","keyctx":"pi11a","x":130,"y":640,"wires":[["bfbea091.cafac8"]]},{"id":"d983e233.3832b","type":"event2value","z":"d55b6e63.6443a8","btransparent":true,"bvalue2payload":true,"name":"","x":490,"y":640,"wires":[["62ad61e2.4f2e38","5e5cbfa3.097938"]]},{"id":"8ccd6651.e136b","type":"ui_gauge","z":"d55b6e63.6443a8","name":"Office Entrance","group":"7b0c853e.555bac","order":0,"width":0,"height":0,"gtype":"gage","title":"Office Entrance","label":"˚C","format":"{{value}}","min":"0","max":"35","colors":["#00b500","#e6e600","#ca3838"],"seg1":"20","seg2":"25","x":880,"y":640,"wires":[]},{"id":"bfbea091.cafac8","type":"vscpfilter","z":"d55b6e63.6443a8","vscppriority":"","vscpclass":"","vscptype":"","vscpguid":"","name":"","x":300,"y":640,"wires":[["d983e233.3832b"]]},{"id":"b09eb66.ccf27c8","type":"ui_gauge","z":"d55b6e63.6443a8","name":"Main Entrance","group":"7b0c853e.555bac","order":0,"width":0,"height":0,"gtype":"gage","title":"Main Entrance","label":"˚C","format":"{{value}}","min":"0","max":"35","colors":["#00b500","#e6e600","#ca3838"],"seg1":"20","seg2":"25","x":880,"y":720,"wires":[]},{"id":"62ad61e2.4f2e38","type":"function","z":"d55b6e63.6443a8","name":"","func":"if ( msg.measurement.sensorindex === 0) {\n return msg;\n}","outputs":1,"noerr":0,"x":650,"y":640,"wires":[["8ccd6651.e136b"]]},{"id":"5e5cbfa3.097938","type":"function","z":"d55b6e63.6443a8","name":"","func":"if ( msg.measurement.sensorindex === 6) {\n return msg;\n}","outputs":1,"noerr":0,"x":650,"y":720,"wires":[["b09eb66.ccf27c8"]]},{"id":"e596ab59.2b98c8","type":"vscp-tcp-config-host","z":"","name":"pi11","host":"192.168.1.44","port":"9598","timeout":"10000","interface":"","keepalive":"10000"},{"id":"7b0c853e.555bac","type":"ui_group","z":"","name":"Temperatures","tab":"7cdacae9.143d2c","order":1,"disp":true,"width":"6","collapse":false},{"id":"7cdacae9.143d2c","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

As the filtering on measurement items is such a common thing to filter on there is a node m-filter that allows for this.

This node can filter on

  • unit
  • sensorindex
  • index
  • zone
  • subzone

This means that we can replace the above flow with

Where the upper m-filter is

That is events from temperature sensor 0 (sesorindex=0) with unit=1 (Degrees Celsius)

And the other

That is events from temperature sensor 6 (sesorindex=6) with unit=1 (Degrees Celsius).

The result in the UI is the same as before

[{"id":"69a3065d.809ce","type":"vscp-tcp-in","z":"d55b6e63.6443a8","name":"pi11","host":"e596ab59.2b98c8","username":"admin","password":"PWRD","filter":"","keyctx":"pi11a","x":110,"y":460,"wires":[["67cb55bc.a4b854"]]},{"id":"fa389899.e0f0a","type":"event2value","z":"d55b6e63.6443a8","btransparent":true,"bvalue2payload":true,"name":"","x":470,"y":460,"wires":[["18fa4e78.ba8042","65526990.3e0138"]]},{"id":"3cf5f43a.efd9d4","type":"ui_gauge","z":"d55b6e63.6443a8","name":"Office Entrance","group":"7b0c853e.555bac","order":0,"width":0,"height":0,"gtype":"gage","title":"Office Entrance","label":"˚C","format":"{{value}}","min":"0","max":"35","colors":["#00b500","#e6e600","#ca3838"],"seg1":"20","seg2":"25","x":860,"y":460,"wires":[]},{"id":"67cb55bc.a4b854","type":"vscpfilter","z":"d55b6e63.6443a8","vscppriority":"","vscpclass":"","vscptype":"","vscpguid":"","name":"","x":280,"y":460,"wires":[["fa389899.e0f0a"]]},{"id":"eb7dd64e.3636f","type":"ui_gauge","z":"d55b6e63.6443a8","name":"Main Entrance","group":"7b0c853e.555bac","order":0,"width":0,"height":0,"gtype":"gage","title":"Main Entrance","label":"˚C","format":"{{value}}","min":"0","max":"35","colors":["#00b500","#e6e600","#ca3838"],"seg1":"20","seg2":"25","x":860,"y":540,"wires":[]},{"id":"18fa4e78.ba8042","type":"m-filter","z":"d55b6e63.6443a8","unit":"1","sensorindex":"0","index":"","zone":"","subzone":"","name":"","x":650,"y":460,"wires":[["3cf5f43a.efd9d4"]]},{"id":"65526990.3e0138","type":"m-filter","z":"d55b6e63.6443a8","unit":"1","sensorindex":"6","index":"","zone":"","subzone":"","name":"","x":650,"y":540,"wires":[["eb7dd64e.3636f"]]},{"id":"e596ab59.2b98c8","type":"vscp-tcp-config-host","z":"","name":"pi11","host":"192.168.1.44","port":"9598","timeout":"10000","interface":"","keepalive":"10000"},{"id":"7b0c853e.555bac","type":"ui_group","z":"","name":"Temperatures","tab":"7cdacae9.143d2c","order":1,"disp":true,"width":"6","collapse":false},{"id":"7cdacae9.143d2c","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

It is now equally easy to save data into databases, tables, show them in diagram or further process the measurement data. We will present some other examples here later.

It is also worth mentioning that we do not filter on GUID above for simplicity. This is a must if there are temperature measurements coming in from several VSCP devices. In this case only one node generated temperature measurements so it is possible to skip that step.

Also note how VSCP abstract the transport mechanism. In this case it is tcp/ip, but the vscp-tcp-in node could be replaced by the CANAL node which allow for CAN transport or even other transports, or MQTT or some other method could be used.

It is also worth noting that the hardware that do the actual measurement is replaceable (and reusable) without any code changes.

Have fun!
/Ake

ps More info about the VSCP IoT/m2m framework can be found here. ds

Categories
General HowTo's VSCP

Howto: Read a #VSCP mdf file with node.js

The Module Description file is a XML file that all VSCP devices must have and which describe the device. It can either be stored on the device itself or more common linked by the device and stored on some external server storage. Software that wants to configure a device can fetch this file to get the knowledge to do so. Typically a user interface use this file to guide a user through device configuration. A good thing is that one software can handle and configure any device.

A sample MDF file is here an here.

Read a mdf file from a device, parse it and display the module name. A device can consist of several modules, there will always be one and result.vscp.module[0] will always refer to the first. Most devices contains only one module. You can get the number of modules with result.vscp.module.length

Below are some Javascript examples on how to get information from the MDF-file.

Display the module name

const axios = require('axios');
const xml2js = require('xml2js');

let parser = new xml2js.Parser();

axios.get('https://www.eurosource.se/ntc10KA_3.xml')  
  .then((response) => {
      parser.parseString(response.data,
                         (err, result) => {
        console.dir(result.vscp.module[0].name);    
      });
  })  
  .catch((err) => {    
    console.log(err);  
  });

Similar to above sample get a link to the manual for a device

console.log(result.vscp.module[0].manual[0].$.path);

List all registers with

console.dir(result.vscp.module[0].registers[0].reg);

Iterate through all registers an display there names

axios.get('https://www.eurosource.se/ntc10KA_3.xml')
  .then((response) => {
    parser.parseString(response.data, (err, result) => {
      for (let reg of result.vscp.module[0].registers[0].reg) {
        console.log(reg.name[0]._);
      }
    });

  })
  .catch((err) => {
    console.log(err);
  });

List register descriptions with

console.log(reg.description[0]._);

You get the language code for a register name or a register description with

console.log(reg.name[0].$.lang);

List abstractions with

axios.get('https://www.eurosource.se/ntc10KA_3.xml')
  .then((response) => {
    parser.parseString(response.data, (err, result) => {
      for (let reg of result.vscp.module[0].registers[0].reg) {
        console.dir(result.vscp.module[0].abstractions[0].abstraction);
      }
    });

  })
  .catch((err) => {
    console.log(err);
  });



List number of events the module can generate and the events

console.dir('# events: ' + result.vscp.module[0].events[0].event.length);
console.dir(result.vscp.module[0].events[0].event);

If you want an url to a picture of the module

console.log(result.vscp.module[0].picture[0].$.path);

If you want the manual

console.log(result.vscp.module[0].manual[0].$.path);

or a firmware image

console.log(result.vscp.module[0].firmware[0].$.path);

The number of firmware images available

axios.get('http://www.eurosource.se/paris_010.xml')
  .then((response) => {
    parser.parseString(response.data, (err, result) => {
  console.log(result.vscp.module[0].firmware.length);
    });
  })
  .catch((err) => {
    console.log(err);
  });

The release date for a specific firmware

console.log(result.vscp.module[0].firmware[3].$.date);

The way this works should be obvious by now. Enjoy!

Categories
HowTo's VSCP

HowTo: SMS Alarms

The problem

Just last week a house burned down to the ground here in my hometown. The family of two adults and three kids just made it out. This reminded me of the importance of alarms. My family as any family I guess have had some incidents over the year. In our case with a four floor building, cellar, office, apartment where we live and the attic it can be hard to, despite alarm equipment, to recognize what is happening in the cellar when your are in the apartment watching a film or even worse, sleeping. We have had our incident over the years as most people do. I use VSCP here of course. This system is intelligent enough to close down functionality  when things get bad. But a few weeks ago I had a bad incident. I have a VSCP node that control the water boiler in the cellar for warm water. This is a very simple setup. A relay, a sensor and a control node. I can thus remotely control sense and control the temperature of the hot water in the house. Sitting in the office I noticed a strange sound. I usually play music loud so it had been going on for some time I guess. I went around the house investigating the sound and when I came down to the cellar I heard that the boiler literally boiled hard. Not a good thing. There is a risk for a steam explosion from this so I got really worried. I turned of the power. Opened valves for hot water in the office and got steam and boiling water coming out. I checked the control unit and it had turned of the relay. Still the temperature was way over the limit. There is an independent security unit inside the boiler that should turn off power when it get over a certain temperature. Apparently this mechanism had not done it’s job. Also the security valve that prevent to hot water from going out in the system also malfunctioned otherwise I should not have got steam hot water out of the office valve. Two faults. The pressure security mechanism on the other side worked. But the boiler never got up to the 10 bar needed to release it. So things were actually not to bad. Bit could gone worse if I had been away for example. I later checked the cause and detected that the relays had gone stuck in the on position.  Something that happen to relays some times when load is heavy or control is a bit jumpy.  I also tested the overheat protection and it worked as it should, probably it would have just needed a bit more time to cut the power. The blender protecting the water line from to hot water was the only faulty component. Still this was a bit scary. I need to be alarmed if this happen again.

GSM Modem

I previously sold professional GPRS modems in the FrogShop from Caimore. Still have some around so I decided to put one to work. You can find may similar on Aliexpress or ebay. and even lower cost modules intended for Arduino or similar as the one below. They all have there pros and cons.

SIM Card

Next thing is to find a SIM card. In Sweden this is not a simple thing if you just want a module that sends a few SMS’s per year. The solutions available are highly overpriced. I know there are other and better options available in other countries. I just select a cash card to get started.

Software

Initially I thought about writing a driver for the VSCP daemon and this may still be an option, we will see. I have for a long time used Smstools a wonderful package for uses like this. With the help of the decision matrix of the VSCP daemon it will be possible to do plenty without a driver. So this is the solution I go for. There is a nice getting started tutorial for smstools here. Thus no need for me to write one again. The only thing i ned to do to get things working is to set the device and the baudrate lines in /etc/smsd.conf file
device = /dev/ttyUSB0
as I use an USB adapter for serial communication. And
baudrate = 115200
as i use that higher speed. Then I just restart the smsd daemon with
sudo service smsd restart
and everything is working.

Sending SMS’s

We are just interested in sending SMS’s here so we stick to that. But receiving SMS’s (we look at that in a later post) is also equally simple. To send a SMS one just copy a formated file into the folder /var/spool/smsd/outgoing. So to send an SMS to +467012345678 one send a file
To: 467012345678
ALARM: The water in the boiler is way to hot!
Write this to a file and copy it to /var/spool/smsd/outgoing and the SMS will be delivered to the set recipient. You can set the header to
To: 467012345678
Flash: yes

ALARM: The water in the boiler is way to hot!
to send a flash SMS (is displayed on the users screen directly but not saved). It can hardly be simpler.

Voicecall

Another possibility is to make a call to a receiver instead. Add Voicecall to the header like this
To: 46730533146
Voicecall: yes
TONE: 5 #,#,#
Here the mentioned precipitant will receive a call and when answered five groups of three “#” DTMF tons will be sounded. Tones that can be used to tell the recipient about the cause of the alarm. I will for instance use the number of “#” sounds as an indication of what floor the alarm happened. Possible with different tones for different alarms.

vscpd and smstools

So now lets put this to work for our VSCP based system. Alarm related events is collected in the class CLASS1.ALARM. The CLASS1.ALARM, Type=2, Alarm occurred is intended for alarm conditions.  So if we let sensors that generate alarms send this event and trigger on it in the decision matrix of the VSCP daemon we can send our SMS and voicecalls from there. The zone and subzone can be used as markers for where the alarm occurred. The originating GUID can also be used to identify this.
<row enable="true" groupid="alarm" >

	<comment>Send alarm.</comment>
	
	<mask priority="0" class="65535" type="65535" guid="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" >
	</mask>
	
	<filter priority="0" class="1" type="2" guid="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" > 
	</filter>
	
	<action>0x10</action>
	<param >/home/vscp/doalarm.py %zone %subzone event.guid %isodate %isotime "Current boiler temp is %vardecode:[boiler-temp]"</param>
	
	<allowed_from>0000-01-01 00:00:00</allowed_from>
	<allowed_to>9999-12-31 23:59:59</allowed_to>
	<allowed_weekdays>mtwtfss</allowed_weekdays>
	<allowed_time>*-*-* *:*:*</allowed_time>
</row>
So what do we have here? We trigger on any alarm occurred event regardless of priority and from which originating GUID (which unit) it comes from. It would have been possible to do several DM rows for different GUID’s (originating nodes) of course to handle alarms from them different. The time block (form <allowed from> to the end) just say that this can happen anytime. Leaving this block out has the same meaning. And last the important action.  In this case, execute external program (0x10) and in the parameter for the action the actual program to execute is specified with the path to it (/home/vscp/doalarm.py) is given. The rest of the action parameter line is arguments to this external program.
  • %event.zone – Zone for alarm event.
  • %event.subzone – Subzone for alarm event.
  • %event.guid – GUID for alarm event.
  • %isodate – Date on ISO format for alarm.
  • %isotime – Time on ISO format for alarm.
  • %vardecode:[//alarmtext//] – Specific text for alarm.
The description of the decision matrix is here. Zone and subzone is numericals that can be used to specify the place and equipment that generated the alarm. I have floor plan in zone and a room on that floor plan in subzone. The vardecode writes out the content of the given variable if it is present. We will come back to it later. When this row is added the external script will be executed when CLASS1.ALARM, TYPE=2 is generated by a node and received by the VSCP daemon. It is good if the script can do both voice calls and SMS sends and that both can be sent to a list of numbers.

The doalarm.py script

import sys
import uuid

filename_voice = str(uuid.uuid4())
filename_sms = str(uuid.uuid4())

# Dir that holds outgoing SMS messages
OUTDIR="/var/spool/sms/outgoing"

# Voicel recipients (comma separated list, empty for non)
VOICE_RECEIVERS="4673xxxxxxxx,4676yyyyyyyyy"

# Set to true for flash SMS
bflash = False

# SMS recipients (comma eparated list, empty for non )
#SMS_RECEIVERS="4673xxxxxxxx,4676yyyyyyyyy"
SMS_RECEIVERS=""

SMS_TEXT="An alarm condition has occured!"

# -----------------------------------------------------------------------------

voicetone="5 "
for x in range(0, int( sys.argv[1] ) ):
	voicetone = voicetone + "1,"

voiceRcvList = VOICE_RECEIVERS.split(",")

cnt=0
if VOICE_RECEIVERS != "" :
	for receiver in voiceRcvList:
		print( OUTDIR + "/" + filename_voice + str(cnt) )
		with open( OUTDIR + "/" + filename_voice + str(cnt), "w") as text_file:
			text_file.write( "To: {0}\n".format(receiver) )
			text_file.write( "Voicecall: yes\n\n" )
			text_file.write( voicetone )
		cnt = cnt + 1

SMSRcvList = SMS_RECEIVERS.split(",")

if SMS_RECEIVERS != "" :
	for receiver in SMSRcvList:
		print( OUTDIR + "/" + filename_voice + str(cnt) )
		with open( OUTDIR + "/" + filename_voice + str(cnt), "w") as text_file:
			text_file.write( "To: {0}\n".format(receiver) )
			if bflash:
				text_file.write( "Flash: yes\n" )
			text_file.write( "\n\n" )
			text_file.write( SMS_TEXT+"\n" )
			text_file.write( "Zone={0} SubZone={1} Time={2} Date={3}\n".format(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4] ) )
			text_file.write( "{0}".format(sys.argv[5]) )        
		cnt = cnt + 1
This is the script. It is written i Python to make things simple to edit and/or change. You can find the script in the VSCP repository. Just edit the variables in the beginning of the script to fit your setup and you are set to go. Note that the voice call will do five groups of a series of “1”-press DTMF where the count is the same as the supplied zone parameter. In my case this is the floor plan so I know instantly where something happened and runa way and fix it. The SMS also give me more info.

The variable

To come back to the variable that is sent as a parameter. Perfect is to save a  measurement value in another part of the DM. Like this
<row enable="true" groupid="temperature" >
    <mask priority="0" class="65535" type="65535" GUID="FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF" > </mask>
    <filter priority="0" class="10" type="6" GUID="FF:FF:FF:FF:FF:FF:FF:FF:3C:00:08:01:92:9D:3D:10" > </filter>
    <action>80</action>
    <param>boiler-temp;float;true;0;0x777;%measurement.float</param>
    <comment>Store boiler temperature in variable</comment>
    <allowed_from>0000-01-01 00:00:00</allowed_from>
    <allowed_to>9999-12-31 23:59:59</allowed_to>
    <allowed_weekdays>mtwtfss</allowed_weekdays>
    <allowed_time>*-*-* *:*:*</allowed_time>
</row>

An alternative way to do it

Another way is to do measurement compares, as in this case check the boiler temperature, you can read more about this method here and it is in many ways the same as the one we described above but more specific for boiler temp alarm.

And next?

Now you should be able to add your own alarms to your VSCP setup. Maybe something that will do good work in your remote cottage, alarming  freezing conditions before bad and costly things happens. In my house we will now sleep much better knowing that we will get alarms when things go wrong. I promised to continue with a follow up on how to react on incoming SMS mesages. This makes it possible to remotely control things as well such as turning on the heat in that remote cottage I mentioned above. I will try to write that story up soon. Time is my enemy, or rather lack of it. Cheers /Ake