Give value in rules for command

HI all,

Is it possible to set a value within rules to execute a command ?

So can I give a certain value to the kind of Command and/or the value with that command.

I work with velbus. So you can have a command ON or a command OF.

Can I give a value within rules to set that command.

I dont think so, because openremote designer will not let me let that field blank in Designer.

Or

can I set a value with that command. With velbus you can set the channel, or with a dimmer a percentage.

So, I saw some examples with an additional value in the command. Example:

rule “LED”
when
Event( source == “LED1STATUS”, value == “on” )
then
execute.command( “LED2” , “2” );
end

But that does not seem to work for me.

I see some examples with $param in the designer command, but that doesnt work with me either.

Those examples ar primarily for HTTP commands.

Can you give a value within rules for a command and do you have an example?

Thank you.

Hello

You've got a good question there :slight_smile:

Okay, so some basics.

The only commands within the Velbus Protocol to support ${param} are dimmer_level & memo_text (Although the ${param} isn't strictly required, you can put any value in and it will be replaced with the dynamic value)

So a rule with..

then
  execute.command( "dimmer01" , 25 );
end

Or

rule "Link button event to memo text"
when
  Event( source == "A button Sensor", value == "pressed" )
then
  execute.command( "memo_text" ,"Hello world:100");

end

Would work.

If I'm reading your question correctly, you just need a tiny tweak to your current rule to get the result you need.

You will need to set an On command and an OFF command for what you're trying to control...

rule "Link two things"
when
  Event( source == "A Sensor", value == "on" )
then
  execute.command( "Something ON" );

else
  execute.command( "Something OFF" );

end

I have something similar running for a client that watches a Velbus glass panel thermostat (heater status) and switches an IP (http addressable) relay.

rule "Sync VMBGP2 HEATER status"
when
  Event( source == "GP2-Heater-Status", value == "pressed" )
then
  execute.command( "IP_Relay_Ch1_ON" );

else
  execute.command( "IP_Relay_Ch1_OFF" );

end

You could take it a stage further and use a regex query to monitor more than 1 sensor and match part of that sensor name to the executed commands.

For example, you might have 10 sensors

1_sensor
2_sensor
3_sensor

Etc

And 10 pairs of commands

1_ON
1_OFF

2_ON
2_OFF

Etc

To save you writing 10 rules, a single rule would match the unique part of the sensor name to the unique part of the command names.

We have this running where multiple new Velbus thermostats are linked to existing heating control relays.

Does that help you?

Best wishes,

Stuart

HI Stuart

That certainly helps me to understand.

The dimmer is indeed the one I was working on now, but I saw the opportunities for other rules.

For the dimmer I tried to do it with:

then
execute.command( “LED2” , 25 );
end

But the rules use the Original value of the command. As you say, it doesnt matter to put $param instead,

And I can understand that, because the value vor Velbus must be the channel and than the dimmerpercentage. So 1:25

But I cant use the : sign, because it gives an error.

So does that mean that this option is of the table for openremote/velbus?

And I have to got the option B?

Thanks

Arrh...

I see what you're getting at :slight_smile:

The only variable that can be inserted into the dimmer_level command is the dimmer level, not the channel number AND dimmer level.

So if I'm understanding correctly, you want to define the channel number within rules.

The only way to do that is to create multiple commands with a command name with a unique identifier.

Then use something clever in rules to define the command you want, then set a level for that command.

I'll dig out an example rule for you to look at.

thanks, any examples are welcome

I do not want to define the channel number also

but I think it is required in the combination with openremote and velbus. As the value must be channel:percentage for it to work, like 1:25

So if there is a loophole

Phew, I see the issue... (I think)

So, in your device command you 'must enter something'.

So, I suggest you put.

1:50

So that if the command were to be used with a button it would set the dimmer level to 50%

Also, if the command is used within a slider, the new slider value will overwrite the 50%.

Likewise in a rule the new value from the rule will overwrite the 50%

So this simple rule should work :-

rule "Link two things"
when
  Event( source == "A Sensor", value == "on" )
then
  execute.command( "Dim to a level", 25 );

//else
// execute.command( "Something OFF" );

end

Richard Turner created a rule that seperates an RGB HEX colour value In-Memory command status (where the value is set by another In-Memory command linked to a colour picker UI element) into 3 seperate % values for use with 3 Velbus dimmer channels.

In-Memory command "186_RGB_Colour_Picker_Set" > linked to Colour Picker UI element

In-Memory status command linked to Sensor "186_RGB_Colour_Picker_Status"

3 seperate Velbus dimmer_level commands

186-4DC-Ch1R-Dim100
186-4DC-Ch2G-Dim100
186-4DC-Ch3B-Dim100

Does this help ?

rule "186-RGB To 3 Channels" when

// SOURCE here is an In-Memory status sensor that shows the RGB HEX value from a colour picker "186_RGB_Colour_Picker_Status"

  $evt:Event( source == "186_RGB_Colour_Picker_Status", $val : value)

then

  String valStr = $val.toString();
  
  if (valStr != null && valStr.length() == 6) {
  
    // Split a single 6 digit HEX RGB colour value into 3 seperate RGB values (in HEX format)
    String rStr = valStr.substring(0,2);
    String gStr = valStr.substring(2,4);
    String bStr = valStr.substring(4,6);
    
    // Convert 2 digit HEX values into DEC int values
    Integer r = Integer.parseInt(rStr, 16);
    Integer g = Integer.parseInt(gStr, 16);
    Integer b = Integer.parseInt(bStr, 16);

    // Convert 0-255 value to 0-100 whole number
    r = (int)Math.round(((double)r / 255d) * 100);
    g = (int)Math.round(((double)g / 255d) * 100);
    b = (int)Math.round(((double)b / 255d) * 100);

    execute.command( "Red_Set", r.toString() );. // In-Memory command used as a reference in the UI for debugging
    execute.command( "186-4DC-Ch1R-Dim100", r.toString() ); // A channel of a VMB4DC that is used to drive the Red elements of an RGB fixture

    execute.command( "Green_Set", g.toString() );. // In-Memory command used as a reference in the UI for debugging
    execute.command( "186-4DC-Ch2G-Dim100", g.toString() ); // A channel of a VMB4DC that is used to drive the Green elements of an RGB fixture

    execute.command( "Blue_Set", b.toString() ); // In-Memory command used as a reference in the UI for debugging
    execute.command( "186-4DC-Ch3B-Dim100", b.toString() ); // A channel of a VMB4DC that is used to drive the Blue elements of an RGB fixture
  }
end

Michal took this a step further when I started playing around with the HTTP driven DMX device by creating random HEX values to use asRGB strings.

Where a pulsing status is used to trigger the rule.
(Not the output state of an 'Interval Timer' relay channel in Velbus as this would give a constant state of "timer", I linked the interval timer relay channel to another relay (momentary action) so that the slave relay showed on and off states)

An interval timer in Rules might be a better option, but I wanted to be able to vary the interval pulse time in VelbusLink or use multiple actions wth different times.

This rule sees 1 trigger and creates 6 different RGB HEX values to be sent to 6 seperate SPi pixels, using the same single HTTP command to address the SPi / DMX adapter. Where the %{param} is used to (only) transfer the HEX value, the start pixel and end pixel information.

package org.openremote.controller.protocol;

global org.openremote.controller.statuscache.CommandFacade execute;

import java.util.*;

rule "Ch5 slave interval timer"

when

  Event( source == "01_VMB1RYNOS_ch5", value == "on" )

then

    java.util.Random randomGenerator = new java.util.Random();

    execute.command("DMX_Universal_Uni0",String.format("%06X", randomGenerator.nextInt(0x1000000)) + "&start=2&end=2");
    execute.command("DMX_Universal_Uni0",String.format("%06X", randomGenerator.nextInt(0x1000000)) + "&start=3&end=3");
    execute.command("DMX_Universal_Uni0",String.format("%06X", randomGenerator.nextInt(0x1000000)) + "&start=4&end=4");
    execute.command("DMX_Universal_Uni0",String.format("%06X", randomGenerator.nextInt(0x1000000)) + "&start=5&end=5");
    execute.command("DMX_Universal_Uni0",String.format("%06X", randomGenerator.nextInt(0x1000000)) + "&start=6&end=6");
    execute.command("DMX_Universal_Uni0",String.format("%06X", randomGenerator.nextInt(0x1000000)) + "&start=7&end=7");
    
end

Off topic a little, but this is a good example of a rule.

It uses a Regex to monitor multiple sensors with command names.

It extracts 2 unique elements in the sensor names and uses those to define which command is executed. ("Zone name" and "Time slot" from "Hall_Seditary_Status-query-01")

It also takes the time value from the sensor, adds 30 minutes and injects that new time value into the executed command.

(I'm not totally sure about how this dark magic works, but I'm very grateful that it does, it reduced 42 rules down to just one)

// Sync Seditary times to Active times with 30 minute offset

rule "Alarm Synchroniser"
when
    $evt:Event(source matches "^.*_Seditary_Status-query-\\d+$", $source : source)
then
   // The sensor value is the time of the seditary alarm as HH:MM
   String strValue = $evt.getValue().toString();
   String[] values = strValue.split(":");
  
   if (values.length != 2) {
      return;
   }

   int sensorNumber = 0;
   int hours = 0;
   int mins = 0;
   String alarmPrefix = "";

   try {
      // Extract the number from the sensor name
      Pattern p = Pattern.compile("^(.*)_Seditary_Status-query-(\\d+)$");
      Matcher m = p.matcher($source);
      m.matches();
      alarmPrefix = m.group(1);
      sensorNumber = new Integer(m.group(2));
      hours = new Integer(values[0]);
      mins = new Integer(values[1]);
      
      // Add 30 mins to the time and set this as the time for the active alarm
      mins += 30;
      execute.command(alarmPrefix + "_Active_Time_Set_" + sensorNumber, hours + ":" + mins);
   
   } catch (Exception e) {
      System.out.println("############## Alarm synchroniser exception: " + e.getMessage() + " #################");
      return;
   }

end

Well tried and some things and I am not yet there where I want to be.

I am still in a steep learning curve, so I all ask a follow up question.

This is working

rule “FF”
when
Event( source == “Command1”, value == “on” )
then
execute.command( “DD” , 41 );
end

And this works:

rule “JJ”
when
Event( source == “Command1”, value == “on” )
then
int number1 = 41;
execute.command( “DD” , number1);
end

But know I want extract the temperature from sensor, make a calculation with it, and put it into this DD command

I looked at several posts within this and other forums, but i cant seem to find something that works

This is almost similar:

https://openremote.github.io/archive-dotorg/forums/filtrete%20thermostat%203m50.html

rule “Huidige temperatuur”
when
CustomState(source==“sensor temperatuur”, $v: value)
then
double correctedValue1 = Double.parseDouble($v.toString()) - 32;
double correctedValue = (correctedValue1/9) * 5;
execute.command(“VTEMP”, String.format("%.1f \u2103", correctedValue));
execute.command(“VTEMPer”, String.format("%.1f ", correctedValue));
temp(String.format("%.1f ", correctedValue));
end

Or this:

https://openremote.github.io/archive-dotorg/forums/22876058.html

rule “Range Event Command Execution”

when

$evt: Range ( source == “Display Volume”, value == 100 )

then

execute.command (“TestMSG”, $evt.getValue());

end

But when I try use these concepts for my rules, and I update my console, it gives errors like:

String and integer or String and object van not be combined

Or that is not an event

What could be a rule to make this work?

Thank you

Richard

Hello Richard,

I'm really curious to know what you're attempting to do :slight_smile:

Michal's PID logic might be on a similar line?

I also think that you need some specialist help here :slight_smile:

With luck one of the magicians will step forward and help you to the next stage.

In the mean time, I'm working on a GitHub page with a list of sample rules.

https://github.com/openremote/Documentation/wiki/OpenRemote-Rules-examples---A-work-in-progress

One of the rules at the bottom extracts values, modifies them and injects the new value into a command.

I'll not say I'm even close to understanding this dark magic, so I can only wish you luck :wink:

Good luck.

Stuart

Hi Richard,

Thanks Michal and Stuart

The error I get with this exact rule:

rule “Huidige temperatuur”
when
CustomState(source==“TEMPkamerschuifpui”, $v: value)
then
double correctedValue1 = Double.parseDouble($v.toString()) - 32;
double correctedValue = (correctedValue1/9) * 5;
execute.command(“DD”, String.format("%.1f \u2103", correctedValue));
end

Where the command DD is a Dimmer_level command of velbus, where you set the dimmer percentage.

And the sensor TEMPkamerschuifpui gives the room temperature.

Than I get this error:

ERROR 2017-02-26 14:40:31,814 : Creating sensor failed. Error : The included command reference in a sensor (ID = 395429)
is not an event producer (Command id : 395429, Type : 289)
XML Element :


org.openremote.controller.exception.XMLParsingException: The included command reference in a sensor (ID = 395429) is not
an event producer (Command id : 395429, Type : 289)

And Stuart. the github site is indeed what would be very very helpfull for beginners like me. And what new people wo are thinking to use openremote will help to decide. I hope you continue that effort.

Thanks

Richard

Hello chaps,

I'll keep adding rules and explanations to that GitHub page for as long as magicians like Michal and Richard keep dreaming them up :slight_smile:

Now, I'm a little curious what you're trying to achieve with this rule.

Are you getting the room temperature from a Velbus glass panel?

Cheers
Stuart

This error message is complaining about the command which is linked with the sensor. Moreover, it is about a different sensor than the rule uses. The rule is checking “TEMPkamerschuifpui” sensor and the error message is complaining about name=“DDS”. Can you check this sensor and see how the command is defined? It might be, that if this is a pooling command you forgot to include the pooling interval parameter?

Kind regards,

Michal

Hi guys,
I came with similar question. I need to make 3 thermostats with change target temperature ability. I’m using rules from Example Home, but it is quite complicated to me to understand, so I’ll need some of your help. I just want to make sure I’m doing it right. As I understand, I need to create 3 In-Memory Virtual devices, make commands to Increase On, Decrease On and Status. To setup target temp start point I’m using this part:

rule “Initialise”
salience 10
then
execute.command(“TargetTemp”,_ReadFromFile(“TargetTemp”,“20.0\u00B0”));
end

rule “Store values”
timer(int: 2s)
when
(
Event($s:source==“TargetTemp”, $v:value, eval(!_ReadFromFile($s,"").equals($v))) ||
)
then
log($s+" old value: “+_ReadFromFile($s,”||")+"; new value:"+$v.toString());
_WriteToFile($s, $v);
end

``

To increase or decrease value I’m using that (respectively):

rule “Target Temp Inc”
timer(int:300ms)
when
Event(source == “TargetTemp”, $v: value, eval(_GetTemp(value) < 30))
Event(source == “TargetTempInc” , value == “ON”)
then
execute.command(“TargetTempInc”,“off”);
execute.command(“TargetTempDec”,“OFF”);
execute.command(“TargetTemp”, _ShiftTemp($v.toString(), 0.5));
end

``

And finaly to activate thermosat:

rule “Thermostat On”
when
Event(source==“TargetTemp”, $v: value)
Event(source==“Temp1”, value==$v)
then
String s = $v.toString();
Double t = java.lang.Math.max(16.0, Double.parseDouble(s.substring(0,s.length()-1))+0.3); // 0.3 hysteresis
execute.command(“Thermostat”, “ON” );
end

``

Is it correct?

I don't understand the last part about activating the thermostat. What it should do? You are calculating something there but exacted only simple ON command ignoring the calculation results.

The last part is when actual temperature meets target temperature+added hysteresis and activates thermostat. How should it look then? Cause these rules are quite complicated for me, and I don’t really know how it suppose to be

If you want to meet temperature and add hysteresis then it should look like

rule “Thermostat On”

when Event(source=="TargetTemp", $v: value) Event(source=="Temp1", eval(_GetTemp($v)-_GetTemp(value)>=0.3)) // 0.3 hysteresis then execute.command("Thermostat", "ON" ); end

``

I’ve deployed my rules, but looks like they do not work, as In-Memory sensors shows 0, and I’m unable to change the value. The log file is very long and says:
ERROR 2017-03-13 19:41:36,909 : Error in rule definition ‘modeler_rules.drl’ : wrong class format
java.lang.RuntimeException: wrong class format

``

ERROR 2017-03-13 19:41:36,931 : Cannot start event processor ‘Drools Rule Engine’ : java.lang.ClassNotFoundException: org/openremote/controller/protocol/Rule_Target_Temp_Inc_0DefaultConsequenceInvoker
org.drools.RuntimeDroolsException: java.lang.ClassNotFoundException: org/openremote/controller/protocol/Rule_Target_Temp_Inc_0DefaultConsequenceInvoker

``

TRACE 2017-03-13 19:48:49,831 : Unable to retrieve controller identity
org.openremote.controller.exception.ConnectionException: The required password for user ‘username’ was not found. Password manager error : Error accessing users password: {0}
at org.openremote.controller.service.BeehiveCommandCheckService$BeehiveCommandChecker.connect(Unknown Source)

``

what does it mean?

It means that you are using Java 8 with controller 2.5. Either decrease Java version to 6 or 7 or use the controller beta version 2.6.

I’ve updated the controller to version 2.6, errors seemed to be gone by now, only few left about remote connection and user credentials or so. But In-Memory sensor still shows 0 and it is unable to change its value. Can someone please check through my rules file, to check what is wrong is, as I believe there is something wrong with rules. And also are my In-Memory commands set correctly?

modeler_rules.drl (2.52 KB)