Categories
HowTo's VSCP

#VSCP HOWTO: DM Send events

In a previous howto we looked at how to link server interfaces. Sometimes it is not necessary to establish a full link but just send an event to the rest of the system.  A typical example on this can be when an event comes in that signals a special state and you what the system to go perform other steps. Here you can send out the events needed to perform those steps.

There are currently three actions defined for this in the VSCP server

Send event

VSCP_DAEMON_ACTION_CODE_SEND_EVENT    0x40/64

This actions sends out a specified event and optionally set a boolean variable to true if the send was successful.  The full documentation is here.

If for example you want to send the event CLASS1.INFORMATION, Type=3, ON every second you can use

<row enable="true" groupid="Send event">

<comment>
 Periodic event
 Send CLASS1:INFORMATION, Type=3 ON event every second
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="65535"
 type="5"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x40</action>
 <param>
 0,20,3,0,,,0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15,0,1,35
 </param>

</row>

Send event conditional

VSCP_DAEMON_ACTION_CODE_SEND_EVENT_CONDITIONAL    0x41/65

This action works much as the previous action. The difference is that it just send the event if a named VSCP remote variable is true.  The full documentation is here.

If you like in the example above want to send the event CLASS1.INFORMATION, Type=3, ON every second you can use

<row enable="true" groupid="Send event conditional" >

<comment>
 Create variable that hold flag for sent event
 when the server is started ( CLASS2.VSCPD, Type=23 ).
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="65535"
 type="23"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x50</action>
 <param>
 bsent;bool;false;0;0x777;false
 </param>

</row>
 
 <row enable="true" groupid="Send event conditional" >

<comment>
 Create variable that hold flag send conditional event
 when the server is started ( CLASS2.VSCPD, Type=23 ).
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="65535"
 type="23"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x50</action>
 <param>
 bevent;bool;false;0;0x777;false
 </param>

</row>
<row enable="true" groupid="Send event conditional">

<comment>
Send event conditional
Send CLASS1:INFORMATION, Type=3 ON event
</comment>

<mask priority="0"
class="0xFFFF"
type="0xFFFF"
GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
class="65535"
type="5"
GUID="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x41</action>
<param>
bevent;0,20,3,0,,,0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15,0,1,35;bsent
</param>

</row>

The difference from the previous example is the introduction of the bEvent remote variable. This variable is initialized to false so before it is set to true no events will be sent.  We can look at the variable sin the admin web interface

Setting it to true

make the action trigger and the event is sent once a second while the bEvent variable is set to true.

 

 

Send event(s) from file

The last send event action send one or more events from a file instead of having them specified in the action parameter. This makes it possible to send several events from one trigger.  A typical scenario could be to trigger on button press and set a scene by presetting lamps and other things which will be set by the sent out list of events,

This action is fully specified here.  The file for the events to send out is XML based.  Apart from that it should be easy to set up from the documentation.

The events defined here in a file called sendevents simulate setting a scenario.

<events>

<event>
 <!-- 
 CLASS1.CONTROL, Type=5 TurnOn
 Turn on lamps in zone=1, subzon=0
 -->
 <head>0</head>
 <class>30</class>
 <type>5</type>
 <guid>00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</guid> 
 <data>0,1,0</data>
 </event>

<event>
 <!-- 
 CLASS1.CONTROL, Type=5 TurnOn
 Turn on lamps in zone=1, subzon=0
 -->
 <head>0</head>
 <class>30</class>
 <type>5</type>
 <guid>00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</guid> 
 <data>0,1,2</data>
 </event>

<event>
 <!-- 
 CLASS1.CONTROL, Type=5 TurnOn
 Turn on lamps in zone=1, subzon=22
 -->
 <head>0</head>
 <class>30</class>
 <type>5</type>
 <guid>00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</guid> 
 <data>0,1,22</data>
 </event>

<event>
 <!-- 
 CLASS1.CONTROL, Type=5 TurnOn
 Turn on lamps in zone=1, subzon=240
 -->
 <head>0</head>
 <class>30</class>
 <type>5</type>
 <guid>00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</guid> 
 <data>0,1,240</data>
 </event>

<event>
 <!-- 
 CLASS1.CONTROL, Type=6 TurnOff
 Turn off head light lamps in zone=1, subzon=1
 -->
 <head>0</head>
 <class>30</class>
 <type>6</type>
 <guid>00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</guid> 
 <data>0,1,1</data>
 </event>

<event>
 <!-- 
 CLASS1.CONTROL, Type=20 Dim lamp(s)
 Dim lamps in zone=1, subzon=0 at 30%
 -->
 <head>0</head>
 <class>30</class>
 <type>20</type>
 <guid>00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</guid> 
 <data>30,1,0</data>
 </event> 
 
</events>

A DM that sets this scenario every minute looks like this

<?xml version = "1.0" encoding = "UTF-8" ?>

<dm>

<row enable="true" groupid="Send events from file" >

<comment>
 Send events in list sendevents 
 when the server is started ( CLASS2.VSCPD, Type=23 ).
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="65535"
 type="6"
 GUID="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x42</action>
 <param>
 /srv/vscp/sendevents
 </param>

</row>
 
 
</dm>

And running it we see in VSCP works that the events get sent

 

You can find sample files for tests here.

Categories
General HowTo's VSCP

#VSCP HOWTO: DM Check measurement

In another Howto we looked at the measurement compares that are available in the decision matrix (DM) record (VSCP HOWTO: COMPARE VALUES WITHOUT CODING). Here we will look at an action that work in a similar equal manner.

The check measurement action

VSCP_DAEMON_ACTION_CODE_CHECK_MEASUREMENT

is defined to make it possible to check a measurement against a literal value and just as we described in the howto about the check variable actions it stores the logical outcome of the compare in a boolean remote variable.

Also here equal to, less than, greater than etc is available.  A typical parameter row can look like this

0;0;99.5;gt;flag

This says that if a measurement comes in that have a value that is greater than 99.5 the remote variable “flag” will be set to true. In all other cases “flag” will be set to “false”.  The “0;0” that is the first two values of the parameter line is  unit and sensor index. In this case the measurement therefore must have unit=0 and sensor index = 0 as well for the test to be evaluated at all.

A complete example is available in the documentation of the action. You can find pre written samples here.

As a note. Instead of a literal value for the compare you can use another variable.  The parameter above can be rewritten

0;0;%variable:[critical_value];gt;flag

and instead of the literal “99.5” the value of the remote variable 99.5 is used for the compare.  VSCP DM escapes are evaluated before an action is carried out. There is many of them and they can be very useful when you want to make decision matrix rows act in a more dynamic way without go so far as to use full JavaScript or Lua.  You can read more about the VSCP DM escapes here.

It isn’t harder than that actually.

Categories
HowTo's VSCP

#VSCP HOWTO: DM – Check variables – store result

A common operation handling flowing data and measurements  is to compare results and the decision matrix (DM) has plenty of functionality built-in for this. Here we will look at three of the actions available for this.

They are

Check variable, set variable
VSCP_DAEMON_ACTION_CODE_CHECK_VARIABLE
Check variable, set to true
VSCP_DAEMON_ACTION_CODE_CHECK_VARIABLE_TRUE
Check variable, set to false
VSCP_DAEMON_ACTION_CODE_CHECK_VARIABLE_FALSE

What they all do is to compare (less than, greater than equal etc) a literal value with the content of a remote variable  and they

Check variable, set variable

This action check the value of a variable against a literal and the set the named boolean remote variable to the outcome of the logic operation. So

3.14;eq;pi;myflag

will set the remote variable myflag to true if the remote variable pi is equal to 3.14 (false otherwise) and

32;lt;temp;alarm

will set the boolean remote variable alarm to true when the remote variable alarm have a value that is greater than 32 and to false otherwise.. The last will look like this in its complete form

<row enable="true" groupid="Variable compare" >

<comment>
 Test the variables tamp if its greater than 32 
 every second
</comment>

<mask priority="0" 
 class="0xFFFF" 
 type="0xFFFF" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0" 
 class="65535" 
 type="5" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x58</action>
 <param>
 32;lt;temp;alarm
 </param>

</row>

Check variable, set to true

This is just a variant of the above. Instead of the result of the logical compare true is always stored when the calculated result is true.

So the example above

32;lt;temp;alarm

will no actually do the same as before. If the result is true it stores true and false if not.

Check variable, set to false

Another variant of the same. Instead of the result of the logical compare false is always stored when the calculated result is true.

So for the example above

32;lt;temp;alarm

alarm will be false when temp is greater than 32 and vice versa.

————————————————————————————

Some ready-made test code is available here.

 

.

Categories
HowTo's VSCP

#VSCP HOWTO: Min/max

Quite often one want to store min and max for measurement values  So of course you can do that with the VSCP server just by adding a row to the decision matrix.

The first thing you need is a remote variable to store the min/max in. You can add this remote variable to the variable xml file so it is created when the system starts or add it as a persistent variable to the database. Another way is to create the variable when the server starts right is the DM. We  use the last method here as it is makes things clearer in this how-to.

You can create a remote variable minimum and another maximum with the following two DM rows which triggers on the CLASS2.VSCPD, Type=23 Starting up  which is feed to the DM once when the VSCP server is started. .

<row enable="true" groupid="Min/max" >

<comment>
 Create variable that hold min
 when the server is started 
 ( CLASS2.VSCPD, Type=23 ).
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="65535"
 type="23"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x50</action>
 <param>
 minimum;float;false;0;0x777;9999999;BASE64:test min
 </param>

</row>
 
 <row enable="true" groupid="Min/max" >

<comment>
 Create variable that hold min
 when the server is started ( CLASS2.VSCPD, Type=23 ).
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="65535"
 type="23"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x50</action>
 <param>
 maximum;float;false;0;0x777;-999999;BASE64:test max
 </param>

</row>

Here the  minimum variable is created as a non-persistent variable (it will not hold its value between sessions), it is created as a float and initiated to a “very high” value (9999999), The maximum variable is also created as a float and initiated to a “very low” number (-999999).

You can read more about the store remote variable action here.

The values for the minimum and maximum variables is selected so that minimum is initiated to a value that is higher than what is expected to be a lowest value that will be received by the system and the same for the maximum but the other way around.

So no we have the two variables. Suppose we now want to check the maximum and minimums for a temperature.  This means that we will look for a measurement event  with type = 6 temperature.  I write “measurement event” here as they come in a couple of flavors.  A DM row  like the following will handle the collection of minimum data

<row enable="true" groupid="Min/max" >

<comment>
 Test for minimum
 </comment>

<mask priority="0" 
 class="0xFFFF" 
 type="0xFFFF" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0" 
 class="10" 
 type="6" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x71</action>
 <param>
 minimum;1;1
 </param>

</row>

Here we filter on CLASS1.MEASUREMENT, Type=6 temperature (class=10, type=6) from any sensor (we normally should have selected on by entering a GUID for it).  The action 0x71 is the

VSCP_DAEMON_ACTION_CODE_STORE_MIN

and it will store the temperature value of the incoming VSCP event if it is lower than the value currently stored in the remote variable minimum. The 1,1 after the variable name  in the parameter says that the measurement should have unit=1 (Celsius in this case) and originate from sensor with index=1 on the remote node,

For the maximum the DM row looks like

<row enable="true" groupid="Min/max" >

<comment>
 Test for maximum
 </comment>

<mask priority="0" 
 class="0xFFFF" 
 type="0xFFFF" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0" 
 class="10" 
 type="6" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x72</action>
 <param>
 maximum;1;1
 </param>

</row>

The functionality is the same except that the

VSCP_DAEMON_ACTION_CODE_STORE_MAX

action is used here which compares the names variable for a highest value instead of a lowest value.

That it. We now have to variables maximum and minimum that  holds the maximum and minimum values for the temperature. We can read (and write) this value in all the interfaces, tcp/op, websocket, mqtt, REST etc and use it for other calculations or present it in a UI. With websocket this presentation is actual trivial using one of the ready-made widgets.

Also not that this work s for all measurement units (that is all SI defined and derived units)  in the same way.  No coding needed.

One last thing. Suppose you want to daily maximum/minimum instead of an all time maximum/minimum.  Easy

Add a DM row that triggers on

CLASS2.VSCPD, Type=9 Midnight

and store  the “very low”/”very high” value to the minimum. It is harder than that. In the same way you can do this on a weekly, monthly etc basis.

You can also use the escapes to  create a more dynamic variable that store the daily minimum/maximum. Try a store in variable

minimum-%isodate;float;true;0;0x777;%variable:[minimum]

which is set to trigger just before midnight. What you get here is a remote variable minimum-YYMMDD  where YYMMDD is the current date that is persistent and holds the value of the minimum remote variable collected for that date.

Try that with the rest..

 

Categories
HowTo's

#VSCP Howto: Linking server interfaces

The tcp/ip interface

This howto describes linking of VSCP server interfaces. With a server  interface we mean the VSCP tcp/ip control interface and especially the the VSCP link interface which is the required  tcp/ip commands that all VSCP nodes exporting a VSCP interface must make available. You find the full list here.

A VSCP server has an extended command set that can handle many special task needed on a full server. An embedded node however often just need the more limited set of commands but can of course add any other commands it like to export available if needed.

Why link servers

Why link servers one may ask. There can be many reasons for this Security can be one. You may link a VSCP server to a higher end server with just event going upwards not downwards and by that  prevent security threats as it will be impossible for the upward server to send events to the lower server. A typical scenario fr this is a server that show public data to an audience but where the source for the data is a real world system.

You maybe also just want to collect events from many subnets on a higher end server or some type of events on a special server.

Even more common is connections with lower end nodes that implement the tcp/ip interface and where you want to contact them from a server, to collect data, configure, control, instead  of the other way around.

How

There are many ways to do this. You can make a special driver. Make JavaScript or Lua scripts that handle this. Build your own application that acts as middleware. But there are of course read made tools available to.

If you want a connection from/to a remote node that is always active, yes it will be maintained, automatically bring up the link if it falls, the tcp/ip link driver is the solution. It lets you set up a link between two machines where one is a VSCP server and where the other machine also can also be a VSCP server but more usually is a lower end node exporting a VSCP tcp/ip interface.  The driver is extremely simple to use. Just add it, setup user connection data and set filters for outgoing and incoming events.  The tcp/ip link driver is described in full detail here. 

If you need to share a smaller selection of events with a remote node or just want to send events to a remote node when special things happen, or just want to filter events very hard, the decision matrix has an action that let you send events to a tcp/ip remote link interface.

Send event to remote host action

Its is the

VSCP_DAEMON_ACTION_CODE_SEND_TO_REMOTE    0x43/67

action that is used for remote connections. A typical DM entry looks like this

<row enable="true" groupid="send_remote_test" >

<comment>
 Test action send event
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="10"
 type="6"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x43</action>
 <param>
 192.168.1.6;9598;admin;secret;%event
 </param>

<index measurementindex="true">1</index>

 </row>

Here the  temperature event that triggers the action is sent to a remote server (%event). You can of course set up to send any event you like or send an event that is stored in a variable.

This action is described here.

A connection is opened and closed each time an event is sent so the driver is much more efficient to use for setups where a lot of events should be sent to a remote location.  The actual transfer is on its own thread so timing is pretty constant also for a slow remote connection.

 

 

Categories
HowTo's

#VSCP howto: Compare values without coding

Measurement events is a central part of any VSCP system of course. The standardisation of measurement makes it possible to hook in parts to a system and read write measurement values in a deterministic way.

The VSCP server can collect measurements from many sources, it can convert them, send them further to other destinations, save them in databases, diagram data,  well, do a lot with the values of measurements.

Many time one want to compare measurement values.  If a certain value is bigger than a set point an alarm may be sounded or some other action may be needed. Usually this is functionality that is handled by program code. This is possible in VSCP also of course. You can even put this code inside the VSCP server using Javascript or Lua or outside in executable files written in any language. But comparing measurement values is also build right into the decision matrix (DM) mechanism of the VSCP server also.

I show the XML format for setting this up here but the database can be used in the same way.

Every DM configuration row can have a measurement part that looks something like this

<measurement compare="eq"
                 unit="1"                                           value="5.014567" />

If this tag is in a DM row  additional checks will be performed on an event before an action is triggered. Here the value of the measurement will be compared to the value 5.014567  for equality and if they are equal AND the unit is the same (here 1) the action will be triggered.

A typical full row for a temperature check will look like

<row enable="true" groupid="measurement_compare_test" >

<comment>
 Test measurement compare: eq
 </comment>

<mask priority="0"
 class="0xFFFF"
 type="0xFFFF"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0"
 class="10"
 type="6"
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x10</action>
 <param>
     scripts/alarm.sh "match"%event
 </param>

<index measurementindex="true">1</index>

<!-- eq|neq|gt|gteq|lt|lteq -->
 <measurement compare="eq"
 unit="1"
 value="5.014567"/>

</row>

Here we have a row that will execute the external script alarm.sh when a temperature event with a temperature   given in degrees Celsius (unit=1) is received and the measurement value is equal to  5.014567

You can of course trigger other actions instead. Send another event, run a Javascript or a Lua script, do an http page post…

As you probably have expected  you can do other compares to,  like greater than, less than and so on. They are all listed here.

If you want to play further with this you have some test setups here.

More info about the decision matrix in the VSCP server is here and info about general decision matrix logic in VSCP is here.

Stay Hungry, stay foolish!

 

Categories
HowTo's

#VSCP Howto: Do something every five minutes

The when selection block of the decision matrix of the VSCP server looks like this

<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>
allowed_from – allowed_to

Here the action is allowed to is allowed from prehistoric times and way into the future. We can say it is allowed to occur forever/always. This is always specified in a time range pair <allowed_from> and <allowed_to>. To say forever/always you can also use a ‘*’ like in

<allowed_from>*</allowed_from>
<allowed_to>*</allowed_to>

which also means forever. Leaving them out and not specifying an allowed time range at all also will be interpreted as forever/always.

allowed_weekdays

The next thing you can do is to select which weekdays the action can occur at. This is always seven characters or a ‘*’ meaning every weekday.  Again leaving it out also means all days.

Some samples

Every day of the week <allowed_weekdays>mtwtfss</allowed_weekdays>

Every day of the week <allowed_weekdays>*</allowed_weekdays>

Only on mondays <allowed_weekdays>m------</allowed_weekdays>

Mondays and Fridays  <allowed_weekdays>m---f--</allowed_weekdays>
allowed_time

The last tag the <allowed_time> gives most control of when the action should occur. You can be VERY specific as in

<allowed_time>2028-12-02 14:32:30</allowed_time>

and the action can only happen this specific year, date and time down to the second. The allowed date range must always be valid and also the weekday must be set to allowed on this day.

You can also be looser and specify

<allowed_time>2028-*-* *:*:*</allowed_time>

which is anytime in year 2028.

But you can also specify

<allowed_time>*-*-* *:30:*</allowed_time>

which means that things can occur every half hour.

For anytime you can specify

<allowed_time>*</allowed_time>

or

<allowed_time>*-*-* *:*:*</allowed_time>

oer leave the tag out all together.

So how do one specify that something should happen every five minutes?

Just specify

<allowed_time>
*-*-* *:0/5/10/15/20/25/30/35/40/45/50/55:*
</allowed_time>

and trigger on the internal minute event with.

<mask priority="0" 
 class="0xFFFF" 
 type="0xFFFF" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0" 
 class="0xffff" 
 type="6" 
 GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

It’s as easy as that and you can of course use this technique for the other parts of the allowed_time tag as well.

 

 

Categories
General HowTo's

Howto: Practical use of #VSCP Remote Variables @thingspeak

See The story about an old fridge and VSCP module setup – refrigirator control part 1 , part 2, part 3, part 4  for earlier parts about this setup.

You have a VSCP system (or other system) setup that control something. and now you want to share some of this information up to the cloud.  One typical problem that you will see when doing this in a VSCP system is that data (we call it events in VSCP) is coming in with a higher rate than the rate you would want to publish it to the selected cloud service.  To solve this VSCP remote variables are perfect helpers.

A stream from a VSCP interface can typically look like this.

There is a lot of events coming in and often the frequency is even much higher that it is here. All the data above comes from a refrigerator and a fridge that is controlled by two Paris and one Kelvin NTC10K modules. Kelvin modules publish temperatures from a fridge, the kitchen and the upper and lower part of a refrigerator. The Paris module controls the compressors from these temperature measurements (ON/OFF events). The Turn-ON/OFF events originate from the Kelvin modules.  So when a temperature goes above a set point Turn-On events are sent from the Kelvin module after each temperature read and similar a Turn-Off event is sent when the temperature goes below the low set point. Nothing fancy really there.

We will look at one specific temperature only here, the fridge temperature.

This temperature comes from a Kelvin NTC10K module with GUID=FF:FF:FF:FF FF:FF:FF:FE B8:27:EB:0A 00:02:00:01  We find this out with the  VSCP Works tool which always is our friend when diagnosing a VSCP system.

We also see that the sensor is at  index 1 for this particular temperature sensor on the Kelvin NTC10K and that the temperature is sent in Celsius (Unit=1), exactly as we want to present it. Thus no conversions is needed.

Now, one way of sending this data to the cloud is to have a DM (decision matrix ) entry that send the data to the cloud every time it is received.

For this we just add an entry in the DM that calls a script when the  temperature event is received. This DM row would look like this

<row enable="true" groupid="thingspeak" >

<comment>
  Send value for fridge temperature to 
  Thingsquare
</comment>

<mask priority="0" 
 class="65535" 
 type="65535" 
 GUID=
"FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF
/>

<filter priority="0" 
 class="10" 
 type="6" 
 GUID=
"FF:FF:FF:FF FF:FF:FF:FE B8:27:EB:0A 00:02:00:01" 
/>

 <action>0x10</action>
 <param>
/srv/vscp/scripts/thingspeak.sh XXEIAQWY1XXNU6XX 2 %measurement.string
 </parm>

<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>

<index measurementindex="true">1</index>

</row>

Here the mask says that all bits of the VSCP class is of interest, all bits of the VSCP type is of interest and all bits of the GUID is of interest.  This is basically to say that the event we enter in the filter is the one we are interested in. So what we had entered in the filter is VSCP Class = 10 for measurement, VSCP type=6 for temperature and the GUID of the Klevin NTC 10K sensor that send the fridge temperature value.

Action is set to 0x10 (16) which says we should execute an external script. The param is the argument to this script.  The first part of the param is the path to the script to execute (which must exist and be executable)  and the rest is parameters. So here we execute the script /srv/vscp/scripts/thingspeak.sh and send three parameters

XXEIAQWY1XXNU6XX    2    %measurement.string

to itThe first parameter is the publishing key to the thingspeak service, the second is the number of the Thingspeak field we want to upgrade. The last parameter is the current temperature in the fridge. The %measurement.string will be replaced by the actual temperature before the script is executed. There are plenty of escapes one can use in decision matrices. 

The script that is called is simple and looks like this

#!/bin/bash
 # Arguments
 # =========
 # 1 - Write key
 # 2 - Filed number 1 .. n
 # 3 - Value
 #echo() { :; } # comment line to enable debugging

update=$(curl --silent --request POST --header "X-THINGSPEAKAPIKEY: $1" --data "field$2=$3" "http://api.thingspeak.$

echo "Update #$update"

# Uncomment to get debug output
 #echo `date` - "$1 field$2=$3" >>debug

Pretty straight forward. Check the documentation up at Thingspeak for the full process.

So what we got now is a DM entry that will update the cloud data as soon as the measurement event comes in. If it, as in this case is received with a frequency less than ten seconds, this may be pretty wasteful of  server resources. Better to update the cloud data at even time intervals.  How do we do this using the VSCP server?

we use one of the built-in events of the VSCP server, the minute event which is feed to the DM exactly once every minute.

To do this we first write the fridge temperature to a variable every time the event is received. We select a non persistent variable as it is no use in saving this value between session. The DM entry for this looks like this

<row enable="true" groupid="fridge" >

<comment>
 Store current temperature for fridge in remote variable fridge_temp
 with typ float (5)
 </comment>

<mask priority="0" 
 class="0xffff" 
 type="0xffff" 
 GUID="FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:Ff:FF:FF:FF:FF" />

<filter priority="0" 
 class="10" 
 type="6" 
 GUID="FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:0A:00:02:00:01" />

<action>0x50</action>
 <param>fridge_temp;5;false;0;0x777;%measurement.string</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>

<index measurementindex="true">1</index>

</row>

So now whenever the event that holds the fridge temperature comes in it is written to the VSCP remote variable fridge_temp .

With VSCP Works we can list check that the variable is available

and it is, fridge temperature is currently -19.43 degrees Celsius.  As you can see we have added the other measurements of the fridge and the refrigerator to variables as well.

Now with the fridge temperature in a variable we can easily access the fridge_temperature remotely  using websockets in a webpage or if we prefer the REST interface  better it can be used instead.  But also the TCP/IP interface or the MQTT interface of the VSCP server can be used. Actually display the fridge temperature in a widget on a web pages is just connecting it to the variable.

But here we want to send the value to Thingspeak every minute so we add another row in the DM that looks like this

<row enable="true" groupid="thingspeak" >

<comment>
 Send fridge temperature varible value to Thingspeak
 </comment>

<mask priority="0" 
 class="0xffff" 
 type="0xffff" 
 GUID="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<filter priority="0" 
 class="65535" 
 type="6" 
 GUID="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" />

<action>0x10</action>
 <param>/srv/vscp/scripts/thingspeak.shXXEIAQWY1XXNU6XX 2 %variable:[fridge_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>

In this DM row we use the same script as above but now instead of triggering on the Class=10,Type=6 (A temperature measurement) we trigger on Class=65535, Type=6 which is the internal minute event. So now the fridge temperature will be sent up to the cloud server every minute instead of each time the measurement event is received. We can do this for all other fridge/refrigerator measurements also and send them all in one call up to the cloud server. Much more efficient.

You have the live result here.

Note the abstractions here. A driver on the VSCP server can collect data from a device of any type, transported over any net using any protocol  etc and it will end up well-defined here. This also works the other way around as the data can be sent out over any protocol, using any carrier and ending up on any device. One simple driver is all that distinguish one type from another and this driver can make everything look like it is a VSCP aware thingi from the VSCP servers point of view.

Task completed.

Hardware Setup: Here the VSCP Server is running on a Raspberry Pi. The fridge and the refrigerator and the modules is connected with CAN and the Pi uses the CAN4VSCP driver with the Frankfurt RS-232 module with a serial USB adapter to talk to the bus. Ethernet, Wifi, sub MHz RF, or whatever could have been used instead of CAN, but the powered CAN4VSCP bus is both low-cost, reliable and perfect in many other ways for a setup like this.

Categories
CAN4VSCP Bejing CAN4VSCP Kelvin NTC10KA HowTo's

Refrigerator project Part 4 #IoT #m2m #VSCP

This (upper cabinet of refrigerator)

and this (lower cabinet of refrigerator)

 

is live data from the refrigerator project described herehere and here.

First of all, this is quite a complex way to do this, it could have been solved in an easier way. But I wanted to test the modules Grodans Paradis AB made and put them to work.

Two CAN4VSCP based modules has been use for this project. The Kelvin NTC10K module is used to sense temperatures and the Beijing I/O module is  used to turn /on/off the compressor.

Configuration

Kelvin NTC10K

The module is fully describe here.

The Kelvin NTC10K (on nickname = 5) have one thermistor connected to input one which is located in the upper cabinet of the refrigerator and the one thermistor connected to input two which is connected to a sensor that is located in the lower cabinet.  Both has been set to send out temperature every ten seconds

As noted also the on-board sensor send out temperature data, It sends out the data with a longer interval (0x3C = 60) which is once a minute.  This value can be used to sense the room temperature but is always a bit high as the sensor is placed on the pcb. One can adjust this in the sensor calibration registers

Most thermistor needs a calibration and here it can be set with a two complement number that can calibrate a temperature with an accuracy of  two decimals.

If you want temperatures sent to some sort of central server this is actually all you need to configure.  The values will be sent with the set interval. The default unit is degrees Celsius but this can be changed. In our case we also need some other features enabled. This configuration we do in the control registers for each sensor

Temperature Sensor 0 and temperature sensor 2 just send out the temperature with the set interval. They are set to 1 which means they send the temperature in degrees Celsius.

For temperature sensor 1 more features has been enabled. It is configured with 0xB9 which is 10111001 in binary.

As Bit 0/Bit 1 forms 1 the temperature will be presented in degrees Celsius as for the other sensors.

Bit 3 is set so low alarm is enables.

Bit 4 is set so high alarm is enabled.

Bit 5 is set which means that CLASS1.CONTROL, TurnOff events and CLASS1.CONTROL, TurnOn events will be sent instead off CLASS1.ALARM,  Alarm occurred. So an OFF event will be sent when the temperature goes below the low alarm level and an ON event will be sent then the temperature goes above the high alarm level.

Bit 7 is set which means alarm events will be sent continuously, not just when a limit is passed.

For this to work we need to set the low alarm level

which is set to four degrees Celsius. And also the high alarm value

which is set to six degrees.

The hysteresis value is set to two as default and we leave it at that.

So what will happen here?

If the temperature is below four degrees Celsius CLASS1.CONTROL, TurnOff events will be sent out every second. This will continue until the temperature is above the low alarm temperature + the hysteresis, that means at 6 degrees.  When the temperature go over 6 degrees Celsius CLASS1.CONTROL, TurnOn events will be sent out every second until the temperature goes below the set high alarm point minus hysteresis, that means 4 degrees Celsius.

In addition to the TurnOn/TurnOff events the temperatures will also be sent out for us to diagram or collect in a database or do other things with.

Before we setup the Beijing module to handle the TurnOn/TurnOff events we need to mark out TurnOn/TurnOff events so they can be identified to the refrigerator. We can do this with the nickname id (node id) which in this case is set to 5. But this value could be changed if a module is replaced but it can also be good not to use this id for other purposes as well.  So instead we use the zone/subzone. For the Kelvin NTC10K we can set a zone/subzone for each sensor.  And we set

the zone to hex 23 (35 decimal) and the subzone for each temperature sensor to it’s index. So temperature sensor 0 get subzone= 0, sensor 1 get subzone=1 and so on.

There is no magic here. One can set up any number schema one likes.

This is how a temperature event looks like for sensor 1

And this is how a CLASS1.CONTROL, TurnOn event  looks like

Beijing I/O module

The module is fully described here.

The Beijing module can do many things. But as we have a relay that control the compressor of the refrigerator connected to I/O channel we are only interested in configuration of this channel.

The I/O channels of the Beijing module is set as outputs by defaults

We have set bit 1 as an input here for a task we want to go through in this write-up (refrigerator door sensor).

Note also that the nickname (node id) is set to 4.

We also need to match the zone with the one we set for the Kelvin NTC10K (0x23) and also the subzone (0x01) for I/O channel 0 .

That is all we need to configure.

To complete the  task we also need to program the decision matrix of the Beijing module. In this matrix we program what the Beijing should do when certain events is received by the module.

In our case there is the two events from the Kelvin NTC 10K module we are interested in.

If CLASS1.CONTROL, TurnOn is received we want I/O to be turned on or stay on, that is the compressor of the refrigerator should be turned on.

If CLASS1.CONTROL, TurnOff is received we want I/O zero to be turned off or stay off, that is the compressor of the refrigerator should be turned off.

The decision matrix have actions it can perform when an event matches a selection criteria. For us the SET and CLR actions is what we need.

The rest of the actions are described here.

We program the decision matrix like this. One row for each action we want to be carried out

In the first row, which looks like this

we enable the row,  don’t check the originating address as we discussed above, and the originating address is not hardcoded, the zone of the received event should match the zone of the our module (0x23) and the subzone should match that for the channel set in the action parameter (I/O 0 = 0) or the module subzone depending on chosen action.

the class mask tells which bits of the class filter that is of interest. Here all is of interest (0x1FF) and the class filter is set to 0x1E which is 30 and is the code for CLASS1.CONTROL

The type mask tells which bits of the type filter is of interest. Here all is of interest (0xFF) and the type is set to 0x05 which is the code for CLASS1.CONTROL, TurnOn

So if a CLASS1.CONTROL, TurnOn event is received with zone=0x23 and subzone=0x01 the Beijing module will carry out the chosen action. We want I/O 0 to be turned on so the compressor is turned on and the action set output of I/O channel high will do that for us.  This action expects the I/O channel as action parameter so we set it to x00.

So now out CLASS1.CONTROL, TurnON events will turn on the compressor.  The Beijing will confirm the I/O change with a CLASS1.INFORMATION, On event.

The DM row for the CLASS1.CONTROL, TurnOff is then setup in  the same way.

Thats it. We have now made a self contained unit consisting of two modules that can work autonomously.

The cloud

The  fridge project explains how to share the generated data to the cloud.  I will do another write-up about this later. But it’s not more to it then to program the decision matrix of the VSCP daemon to send data to the cloud.  You have live data for this setup here as a sample. This data is on a CAN4VSCP bus in this house and is collected by a Raspberry Pi and is sent up to ThingsSpeak.

VSCP have other means of displaying data and more will come in the next version.

 

Categories
CAN4VSCP Bejing CAN4VSCP Kelvin NTC10KA CAN4VSCP Paris HowTo's VSCP

Refrigerator control Part 3 #VSCP #IoT #m2m

The refrigerator again. It takes more time then expected of course. It always do. This time because I have a lot of other things to attend to at the moment.  I understand if you ask some questions about this project. So I answer them here (before you actually ask them)

Why this project?

Our refrigerator broke down two weeks ago. And we need one also in my family.  Of course we do, open source programmers may not afford much buying stuff but we also want our milk to be cold.  Luckily it is winter here now and we have some other storage that is at about four/five degrees so it is no immediate panic,  but as weather is getting better (the spring is coming)  this is not a good long-term solution.

When our fridge broke down some years ago I decided to try to rescue it and if it was possible I would take standard VSCP modules to do so.  The compressor was OK and if it is this is a simple  project mostly.  This project has worked perfectly well since then and became a nice VSCP demo project.

Yes, Yes, YES it’s an overkill using VSCP standard modules for this. An Arduino or some other simple board would have done the job. But I wanted to use the modules to see if they did their job also over time. The best way to actually see if things are working the way you thought is to put them in some critical system in your house (the heating in our house is already controlled this way). If there is some bugs or design problems things will be solved by necessity. To have them in a demo system on a workbench is just not the same thing.

So for the refrigerator the first question was to check if the compressor still worked. If it was dead it is just a pieces of junk and not a refrigerator.  But just as with the fridge it was the control logic that had broken also this time. Make me wonder how many perfectly fine refrigerators/fridges are thrown away out there that could have new  control added for a few bucks and do the job they were designed for for many years more.

How?

As with the fridge I decided to go for standard VSCP modules for the refrigerator project to make it a demo project.  It is easier this time as I have the CAN4VSCP bus connected to the fridge that stands next to the refrigerator. I just need to connect the two together.

So I put in a Kelvin NTC10K module and a Bejing I/O module in the refrigerator and hook it up to the CAN4VSCP bus so I am able to monitor temperatures and change temperature settings and get possible alarms from the unit.  As with all VSCP modules they form a self-contained unit.  There is actually no need for a server after they have been configured. The second video here show the configuration process and the first show how the modules are connected together.

The Kelvin NTC 10K module is a module that one can connect a couple of temperature sensors to.  It can be programmed to alarm at low and high temperatures and as in this case turn on and off things when certain temperature thresholds are reached.

In the fridge project a Paris module is used together with the Kelvin NTC module. The Paris module is constructed to control relays and have all the electronics on board to do that. It also include protection timers and a lot more.

In the refrigerator project I decided to use the Beijing module instead of the Paris module. Mostly because it did not matter to have standard I/O channels  as I use a solid state relay to switch on and off the compressor, but my main reason was that  I got a chance to use it in a real life demo system.

So the Kelvin NTC10K module sense the temperature in the refrigerator and the Beijing module is used to switch the compressor on or off and to sense if the refrigerator door is open or not and if it is light the lamp inside the box.

It is possible to  sound s siren if the door to the refrigerator is opened between midnight and six in the morning. But some things just hit you right in the face so I will not implement that functionality. At least not now.

Next?

Connect cables and putting it in the refrigerator where the old control logic was located. No programming is needed just configuration.  The second video above show a bit of this configuration but I will go through it in a more precise way in a future post. Hopefully things will work as thy should tomorrow. The VCSP modules are very flexible and can be used in most control situations to form self-contained systems that can be connected together and be connected to the world in a safe and secure way.