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
- Raspberry Pi 3B+
- CAN4VSCP Frankfurt RS-232 module.
- CAN4VSCP power injector module.
- CAN4VSCP Paris module.
- CAN4VSCP Kelvin 1-wire module.
- CAN4VSCP Beijing module.
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
[{"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