Switch wireless devices reliable through Drools in OpenRemote

This post summarises my experience with having a wireless appliance switched on and off at certain parts of a day. This is a nice example of using Drools timers and internal facts.

Wireless suffers the problem of unreliable communication in a noisy, long distance environment. Even in the same room sometimes the transmission fails, this is my experience with EnOcean, Z-wave and WeMo. Luckily, this problem can be solved in Openremote in a smart way by sensing back the switch state and deciding if retransmission is necessary. This is an unique characteristics of Openremote architecture not commonly found in other home automation controllers. The algorithm presented below addresses this problem and is in my humble opinion a must have for everyone who has a need of reliable wireless switching.

First I’ve declared a fact which will be used by the switching algorithm state machine.

declare SocketState
  @role(event)
  on : int
  // -1: idle
  //  0: switching off
  //  1: switching on 
end

rule "Init SocketState"
when
then
  insert(new SocketState(-1));
end

Next, the rule for initiating switching on the appliance every Friday at 6:10 AM:

rule "Lamp on"
  timer(cron: 0 10 6 ? * fri) 
when
  Event(source=="SocketSwitching1.STATE", value=="off")
  $s: SocketState(on!=1)
then
  $s.setOn(1);
  update($s);
end

Note that the rule is executed only when socket is not yet turned on and not in switching StcketState. All it does is setting the SocketState fact into switching on state and pass it to other rules with update() statement.

Now, we will be sending wireless telegrams to the switching socket every 5 seconds as long as its state is off. Usually the light go on immediately, however when it is noisy few retransmissions are necessary.

rule "Lamp on execute"
  timer(int: 0s 5s) // repeat every 5 seconds
when
  $s: SocketState(on==1)
  Event(source=="SocketSwitching1.STATE", value=="off")
then
  execute.command("SocketSwitching1.ON"); // Light ON
end

Finally when the socket state is changed to on it is marked by SocketState fact:

rule "Lamp on executed"
when
  $s: SocketState(on==1)
  Event(source=="SocketSwitching1.STATE", value=="on")
then
  $s.setOn(-1);
  update($s);
end

The same algorithm is used for switching the socket off on 6:25 AM.

rule "Lamp off"
  timer(cron: 0 25 6 ? * fri) 
when
  Event(source=="SocketSwitching1.STATE", value=="on")
  $s: SocketState(on!=0)
then
  $s.setOn(0);
  update($s);  
end

rule "Lamp off execute"
  timer(int: 0s 5s)
when
  $s: SocketState(on==0)
  Event(source=="SocketSwitching1.STATE", value=="on")
then
  execute.command("SocketSwitching1.OFF"); // Light OFF
end

rule "Lamp off executed"
when
  $s: SocketState(on==0)
  Event(source=="SocketSwitching1.STATE", value=="off")
then
  $s.setOn(-1);
  update($s);
end

Because ON and OFF states sent by socket can easily be missed in noisy environment an extra bit of robustness is achieved by declaring the ON state in case when non-zero power measurement message arrives:

rule "SocketSwitching1 state ON through power"
// Set state ON when power is not 0
when
  Event(source=="SocketSwitching1.POWER", value!="0")
  Event(source=="SocketSwitching1.STATE", value!="on")
then
  execute.command("SocketSwitching1.ON");
end

The last touch is to retract the last power measurement fact so the repeating same values are processed by the rules engine. Without this rule when power measurement value stays the same the “SocketSwitching1 state ON through power” rule will be triggered only once (this is due to implementation of Drools engine within Openremote).

rule "SocketSwitching1 retract last power measurement"
salience -100 // Because of retracting of the event
when
  $s : Event(source=="SocketSwitching1.POWER",$v:value)
then
  retract($s);
end

Integrating Eltako’s Socket Switching Actuator FSVA-230V

The FSVA-230V is EnOcean socket actuator with power measurement. After switching it reports it’s state and periodically it sends power measurement results. More informations about this device are on Eltako’s web site. Beside of switching socket and power measurement it also incorporates EnOcean repeater which can be used to extend the coverage.

The switching actuator can be learned to work with push buttons or window/door contacts. Currently it is possible to send a push button messages from openremote therefore they are used to drive the socket.

Actuator commands used to turn the switch off and on:

  • Command: SocketSwitching1.ON, Protocol: EnOcean, Device ID: 0x01, EnOcean Command: ON_ROCKER_A, EnOcean Equipement Profile (EEP): F6-02-01
  • Command: SocketSwitching1.OFF, Protocol: EnOcean, Device ID: 0x01, EnOcean Command: OFF_ROCKER_A, EnOcean Equipement Profile (EEP): F6-02-01

Sensor commands for reading the switch state and power measurements:

  • Command: SocketSwitching1.STATE, Protocol: EnOcean, Device ID: one from the log file or found with Dolphin tools, EnOcean Command: STATUS_ROCKER_A, EnOcean Equipement Profile (EEP): F6-02-01
  • Command: SocketSwitching1.POWER, Protocol: EnOcean, Device ID: as above, EnOcean Command: MR, EnOcean Equipement Profile (EEP): A5-12-01

Finally here are the sensors and a switch definitions:

  • Sensor: SocketSwitching1.POWER, Command: SocketSwitching1.POWER, Type: Custom, Custom state items: empty
  • Sensor: SocketSwitching1.STATE, Command: SocketSwitching1.STATE, Type: Custom, Custom state items:
    Name: Value:
    off ROCKER_BI
    on ROCKER_BO
  • Switch: SocketSwitching1.SWITCH, Sensor: SocketSwitching1.STATE, Command on: SocketSwitching1.ON, Command off: SocketSwitching1.OFF

Integrating Eltako F2L61NP EnOcean actuator with OpenRemote

20131018_095154The F2L61NP actor is a 2-speed fan relay which can be teach-in to work with many sensors – push buttons, temperature, humidity, occupancy, etc. For full specification please consult the data sheet. Unfortunately, at this moment Openremote can send only F6-02-01 EEP (push button), which means that if you need to couple other type of sensors with this actuator then a conversion need be done inside of the Openremote. Luckily it is quite simple with the Drools rule engine, however how to do this is outside of the scope of this post.

In order to learn this actor to work with Openremote a command to proxy push button press need to be defined:
on_rocker_b
Here, the Device Id can have any value between 1-255 and EEP must be F6-02-01. For EnOcean command the following values are possible:

  • PRESS_ROCKER_AI – Press bottom left button;
  • RELEASE_ROCKER_AI – Release bottom left button;
  • PRESS_ROCKER_AO – Press upper left button;
  • RELEASE_ROCKER_AO – Release upper left button;
  • ON_ROCKER_A – Press and release bottom left button = PRESS_ROCKER_AI+RELEASE_ROCKER_AI;
  • ON – Press and release bottom left button;
  • OFF_ROCKER_A – Press and release upper left button = PRESS_ROCKER_AO+RELEASE_ROCKER_AO;
  • OFF – Press and release upper left button;
  • PRESS_ROCKER_BI – Press bottom right button;
  • RELEASE_ROCKER_BI – Release bottom right button;
  • PRESS_ROCKER_BO – Press upper right button;
  • RELEASE_ROCKER_BO – Release upper right button;
  • ON_ROCKER_B – Press and release bottom right button = PRESS_ROCKER_BI+RELEASE_ROCKER_BI;
  • OFF_ROCKER_B – Press and release upper right button.

When you link one of these commands with a button in UI and press it when the actor is in the LRN mode then the coupling will be created.

Integrating Thermokon SR04PS EnOcean wireless room temperature sensor with OpenRemote

20131018_095424Solar energy harvesting temperature sensor with an optional battery for placement in shadow places.

Thermokon SR04PS wireless room temperature sensor is has 3 sensors on board:

  1. temperature (TMP);
  2. set point adjustment (SP);
  3. fan speed switch (FAN).

The data sheet is available on Thermokon website SR04.
In order to make these sensors available in Openremote follow the steps:

  1. Find the device Id using either EnOcean Dolphin View software or taking a look at EnOcean log file in Openremote which is under OpenRemote/logs/enocean subdirectory;
  2. Create new commands for reading out the sensors using the device Id from the previous point and the A5-10-04 EnOcean Equipment Profile (EEP):
    • SR04PS-TMP
      SR04PS-SP
      SR04PS-FAN
  3. Create 3 sensors and link them to commands created in the previous step.

Now you should have 3 new sensors available in the Openremote Designer ready for use during UI design or rules definition.

Integrating Eltako’s FTK EnOcean sensor with Openremote

ftkEltako’s FTK is a wireless window/door contact. For more information see FTK data sheet. One he biggest advantage of these sensor is that they resend their status periodically which ensures correct state even if one of more messages are missed.

In order to make this sensors available in Openremote follow the steps:

  1. Find the device Id using either EnOcean Dolphin View software or taking a look at EnOcean log file in Openremote which is under OpenRemote/logs/enocean subdirectory;
  2. Create a new command for reading out the sensor using the device Id from the previous point and the D5-00-01 EnOcean Equipment Profile (EEP):
    • ftk-co
  3. Create sensor and link it to the command created in previous step.

Now you should have a new sensor available in the Openremote Designer ready for use during UI design or rules definition.

Integrating Eltako’s FTR55H EnOcean sensor with Openremote

Eltako’s FTR55H is a temperature controller with 3 sensors on board:

  1. temperature (TMP);
  2. day reference hand wheel (SP);
  3. night reduction slide switch (SLSW).

The datasheet is available on Eltako’s home page FTR55H.
In order to make these sensors available in Openremote follow the steps:

  1. Find the device Id using either EnOcean Dolphin View software or taking a look at EnOcean log file in Openremote which is under OpenRemote/logs/enocean subdirectory;
  2. Create new commands for reading out the sensors using the device Id from the previous point and the A5-10-06 EnOcean Equipment Profile (EEP):
    • ftr55h-tmp
      ftr55h-sp
      ftr55h-slsw
  3. Create 3 sensors and link them to commands created in the previous step.

Now you should have 3 new sensors available in the Openremote Designer ready for use during UI design or rules definition.

Simpleremote for home cinema demonstration

This demonstration shows integration of few home cinema components under the simpleremote concept. It shows how a cumbersome task of using a traditional remote control device in the modern home cinema setup can be simplified with the help of Openremote platform.

The test environment consists of:

  • Samsung TV UE46D7000 – LAN controlled;
  • Bose AV35 Home Theater – RS232 controlled;
  • Ferguson Ariva Satellite receive – LAN controlled;
  • Openremote eBox – controls everything;
  • EnOcean USB300 and PTM200 devices from EnOcean starter kit – energy harvesting devices (battery less).

During the demo you see how switching the source with Bose universal remote can be accelerated by the EnOcean 2 buttons switch. This is in fact not a demo but a real application which I’m using in my home everyday. Once I’ve made it I don’t want to switch sources traditional way anymore and I’m planning to buy more EnOcean switches and add them to my setup.

The integration of all components were possible thanks to the open source Openremote middleware. Although not visible on video, Openremote is the brain sitting behind all of this. I’m using a customized version of Openremote because not everything which I’m showing in this video is possible with the standard build. However, my changes are backward compatible, meaning that all Openremote legacy code would run on my version too. I’m planning to contribute my customization as soon as possible.

From the technical point of view the most interesting part is the usage of rules in Openremote to change buttons behavior based on a sensor value.
Here is code snippet a rule used for the ‘Switch TV’ button:

rule "Switch TV"
when
  ($evt : Event(source=="Button BI On", value=="ROCKER_BO_1")
       or Event(source=="V_TV STATUS", value=="ON"))
   $src : Event(source=="V1 STATUS")
then
  if($src.getValue().toString()=="TV")
  {
    execute.command("TV.PRECH");
  }else{
    System.out.println("Switch to TV");
    execute.command("BOSE.SELECT_TV");
    execute.command("TV.SOURCE_TV");
    TimeUnit.MILLISECONDS.sleep(500);
    execute.command("V1 ON","TV");
  }
end

As you see the button function depends on the “V1 STATUS” sensor value which keeps the current selected source.

If you want to know more about this example please leave a comment.

Temperature sensor’s calibration

Recently I’ve purchased EnOcean starting kit as I think that energy harvesting solutions have big potential. They are batteries free therefore maintenance free. This is a big advantage comparing to other technologies. Anyway, the set has a temperature sensor which I’ve added to my OpenRemote controller and after linking it to a label I’ve noticed that its value has 2.5 centigrade offset comparing to my thermostat. Although, EnOcean claims that the sensor is calibrated I trust more my thermostat, the offset is simply too much!

Luckily for OpenRemote this is not a big problem. The solution is as follows:

  1. have 2 sensors, the real that’s read from the device and a virtual linked to the user interface. Both should be custom sensors with the empty custom states list;
  2. for the virtual sensor, you would have “In-memory Virtual Command” VTEMP, command: STATUS and address: VTEMP;
  3. have a rule on the real value, do your computation, then call the write command.

The rule is (checked and tested to work correctly):

rule "Correct Temperature"
when
  CustomState(source=="Temperature", $v: value)
then
  double correctedValue = Double.parseDouble($v.toString()) - 2.5;
  double fahrenheit = (correctedValue*9) / 5 + 32;
  execute.command("VTEMP", String.format("%.1f \u2103 / %.1f \u2109", correctedValue, fahrenheit));
end

Note that the above code does more than only temperature correction. It also adds Fahrenheit so the final UI display is:
temperature_display