Help getting a rule working - Int value to HEX string


Yet again I'm failing to understand the basics of Drools to get a rule working.

Seriously, if anyone wants to create a chargeable service to create rules, I would probably be the first customer :slight_smile:

Anyway, today's problem...

I have a slider which has a range sensor that allows it to create a value between 0 and 256

I need to convert that Int to a HEX string between 0 and FF

This new HEX string will be passed to a HTTP command to a 6 Universe DMX output box to control some architectural lighting.${param}&start=1&end=3

( There will also be some LED SPi tape being driven from this box, but they will be controlled with colour pickers and different PIXEL commands to the DMX box, I.E. "${param}&start=2&end=7" where ${param} will be the RGB value )

The rule I have written looks like this :-

package org.openremote.controller.protocol;

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

import java.util.*;

rule "TV_Wht 3 channel dec to hex" when

  $evt:Event( source == "Wht-3ch-IM-status", $val : value)


  String valStr = $val.toInt();
  if (valStr != null ) {

    // Convert int to hex value
        Integer hex = String.format("%02X", $valStr);

    execute.command( "TV_White_3ch-set", hex.toString() );
    execute.command( "TV_WHT-Hex-IM-set", hex.toString() );


The errors I'm seeing in the boot log are these (Which don't mean anything to me)

ERROR 2016-09-03 18:43:02,922 : Rule definition '255toHEX.drl' could not be deployed. See errors below.
ERROR 2016-09-03 18:43:02,961 : Rule Compilation error The method toInt() is undefined for the type Object
$valStr cannot be resolved
ERROR 2016-09-03 18:43:03,080 : There was an error parsing the rule definition '255toHEX.drl' : Could not parse knowledge.
java.lang.IllegalArgumentException: Could not parse knowledge.
  at org.drools.builder.impl.KnowledgeBuilderImpl.newKnowledgeBase(
  at org.openremote.controller.statuscache.rules.RuleEngine.getValidKnowledgePackages(
  at org.openremote.controller.statuscache.rules.RuleEngine.start(
  at org.openremote.controller.statuscache.EventProcessorChain.start(
  at org.openremote.controller.statuscache.StatusCache.start(
  at org.openremote.controller.deployer.Version20ModelBuilder.buildSensorModel(
  at org.openremote.controller.deployer.AbstractModelBuilder.buildModel(
  at org.openremote.controller.service.Deployer.startup(
  at org.openremote.controller.service.Deployer.startController(
  at org.openremote.controller.spring.SpringContext.initializeController(
  at org.openremote.controller.service.ServiceContext.init(
  at org.openremote.controller.bootstrap.Startup.loadServiceContext(
  at org.openremote.controller.bootstrap.servlet.ServletStartup.initializeServiceContext(
  at org.openremote.controller.bootstrap.servlet.ServletStartup.contextInitialized(
  at org.apache.catalina.core.StandardContext.listenerStart(
  at org.apache.catalina.core.StandardContext.start(
  at org.apache.catalina.core.ContainerBase.addChildInternal(
  at org.apache.catalina.core.ContainerBase.addChild(
  at org.apache.catalina.core.StandardHost.addChild(
  at org.apache.catalina.startup.HostConfig.deployDirectory(
  at org.apache.catalina.startup.HostConfig.deployDirectories(
  at org.apache.catalina.startup.HostConfig.deployApps(
  at org.apache.catalina.startup.HostConfig.start(
  at org.apache.catalina.startup.HostConfig.lifecycleEvent(
  at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(
  at org.apache.catalina.core.ContainerBase.start(
  at org.apache.catalina.core.StandardHost.start(
  at org.apache.catalina.core.ContainerBase.start(
  at org.apache.catalina.core.StandardEngine.start(
  at org.apache.catalina.core.StandardService.start(
  at org.apache.catalina.core.StandardServer.start(
  at org.apache.catalina.startup.Catalina.start(
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(
  at java.lang.reflect.Method.invoke(
  at org.apache.catalina.startup.Bootstrap.start(
  at org.apache.catalina.startup.Bootstrap.main(
INFO 2016-09-03 18:43:04,953 : Added rule definition 'ColourPicker-to-BGR.drl' to knowledge.
DEBUG 2016-09-03 18:43:05,030 : Adding rule definitions from 'ColourPicker-to-BGR.drl'...
INFO 2016-09-03 18:43:05,416 : Added rule definition 'TTS test rules V3.drl' to knowledge.
DEBUG 2016-09-03 18:43:05,457 : Adding rule definitions from 'TTS test rules V3.drl'...
INFO 2016-09-03 18:43:06,745 : Initialized event processor : Drools Rule Engine

Use $val.toString() instead of $val.toInt()

Thanks Michal,

I tried that and it came out with an error suggesting that it couldn't phrase a String as an Integer.

I'll try it again and post the exact error message.



Instead of
                    Integer hex = String.format("%02X", $valStr);


                    String hex = String.format("%02X", Integer.parseInt(valStr));

Arrr :slight_smile:

I'll give that a try later today.

Many thanks,


Thanks Michal

That rule seems to be accepted now.

The only problem now is that ALL of my in memory commands are broken.

I haven't changed anything other than the rules since they all worked perfectly.

(My plan was to get the IM commands working, like a slider with a range of 0-255 and a Colour picker, then get the rules to read those values)

Is there something that I should go looking for?



Please give more details about BROKEN. I don't see a reason why anything should be broken.

Yeah, I'm mystified.

Simply put, all of the sensors that were connected to "In-Memory" status commands are now only showing N/A

I've even cleaned out the design say that it only contains the commands I need for this feature.

I must have done something really odd to make them all stop working.

Do you have any suggestions were I can start looking?

On a side note, the HTTP to DMX box is being locked out after OpenRemote sends 2 commands.

The designer of the DMX box says that it supports 2 simultaneous open connections, so he suggests that maybe OpenRemote isn't closing the connections between commands?
Or isn't using the same connection to send multiple commands.

A simple HTTP request app on my Android can send plenty of commands without a single error.

IMHO, cold reboot can make miracles.

Yeah, I tried that out of frustration.

It didn't make a difference :frowning:

Which is why I think I've done something silly in the design to kill all the in memory.

I'll create a really simple design with just a single in memory group and set what happens.

Thanks for your help.




Well as you can imagine I did get just a little frustrated with that issue.


I setup a whole new machine, with a brand new Ubuntu 12 server and OR Pro 2.5.0

(I can't quite work out what to do to get JVelbusD working on it, but that's another story)

After many hours of head banging...

I created a separate set of In Memory commands and sensors to see if they would work.

The result of which was, YES, the new set worked, while the original still did not work.

So I've completely deleted the old In Memory commands and have started from scratch!!!


PERFECTLY :slight_smile:

I have also created dummy In Memory commands to hold the new HEX value of the 0-255 slider, and another set to hold the BGR version of the colour picker :-

And they work TOO! :slight_smile:

So all I need to do next is find out why the DMX box locks out for a short time (roughly 3 minutes) after OR has sent 2 HTTP commands.

For all those that might come looking for this magic rule... here it is...

As always, with great assistance from Michal and Richard :slight_smile:

package org.openremote.controller.protocol;

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

import java.util.*;
import java.util.regex.*;

rule "01_TV_Wht 3 channel dec to hex" when

  $evt:Event( source == "01_WHT_DMX_IM_value", $val : value) // this is a range sensor of 0 to 255


  String valStr = $val.toString();
  if (valStr != null ) {

    // Convert int to hex value
        String hex = String.format("%02X", Integer.parseInt(valStr));

// execute.command( "TV_White_3ch-set", hex.toString() );
    execute.command( "01_WHT_DMX_IM_HEX_set", hex.toString() ); // this is a second set of In Memory commands to debug


rule "01_RGB to BGR" when

  $evt:Event( source == "01_RGB_IM", $val : value) // This is a sensor linked to the In Memory command used by the Colour Picker to inject RGB value


  String valStr = $val.toString();
  if (valStr != null && valStr.length() == 6) {
    // Split colour into RGB
    String rStr = valStr.substring(0,2);
    String gStr = valStr.substring(2,4);
    String bStr = valStr.substring(4,6);

// execute.command( "DMX_6Px_Set", bStr.toString() + gStr.toString() + rStr.toString() );
    execute.command( "01_RGB_IM_BGR_SET", bStr.toString() + gStr.toString() + rStr.toString() ); // This is another set of In Memory commands to use when debugging