How to convert DSL in JavaScript for HUE-Dimmer via Blockly

Happy new year community,

new year, old problems. I currently prepare the switch from openhabian 2.6 to openhab 3.2, which should run within a Docker container on mit OMV server. For this reason I tried to translate my rules to Blockly. My current task is to write my first Blockly component to control a Hue bulb with the
fadingLightCommand-action, but I have no expierences in JavaScript or Blockly programming.

The hue binding offers the following feature

val hueActions = getActions("hue","hue:0210:00178810d0dc:1")
hueActions.fadingLightCommand("color", new PercentType(100), new DecimalType(1000))

With the Blockly editor I wrote the following component (after reading some tutorials, documentations … well and copy some things from other uesers)

uid: HUE_fading
tags: []
props:
  parameters: []
  parameterGroups: []
timestamp: Jan 2, 2022, 8:58:05 PM
component: BlockLibrary
config:
  name: Block Library c107d09908
slots:
  blocks:
    - component: BlockType
      config:
        type: block1
        message0: HUE brightness [%] %1 within [ms] %2 with Thing %3
        lastDummyAlign0: right
        args0:
          - type: input_value
            name: BRIGHTNESS
          - type: input_value
            name: FADIING_TIME
            text: some text
          - type: input_value
            name: THING_ID
        previousStatement: ""
        nextStatement: ""
        inputsInline: false
        colour: 0
        tooltip: ""
        helpUrl: ""
      slots:
        code:
          - component: BlockCodeTemplate
            config:
              template: >
                var hueActions = actions.get("hue",{{input:THING_ID}}); hueActions.fadingLightCommand("brightness", {{input:BRIGHTNESS}}, {{input:FADIING_TIME}});
  utilities:
    - component: UtilityJavaType
      config:
        javaClass: org.openhab.core.model.script.actions.Things
        name: things

The rule, where I use this component looks like. The Idear behind this is to use the Hue fading and override the fading command when the desired brightness is reached … don’t know wheater this will work or not :face_with_raised_eyebrow:, but this could become an other problem - currently I tried to understand mechanismns.

… but using this Blockly component results in Errors like


==> openhab.log <==
2022-01-02 20:12:54.211 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule 'aaaa': Fail to execute action: 2

So here are my questions

  • I discovered that the expected code line “var things = Java.type(‘org.openhab.core.model.script.actions.Things’);” inside the gererated code will not be generated … why?
  • Is the translation of the discriped Hue Binding (in DSL) correctly translated to JavaScript? If not how is the correct translation?

I hope that the experts within this forum might help me. So don’t be quiet, just answer … :wink:

Thanks and best regards
Stef

OK, so that example is Rules DSL. Unfortunately, for now at least, if you see an example and it doesn’t explicitly state that it’s a given rules language, assume it’s Rules DSL.

One of the best places to look for examples of Nashorn JavaScript is the Helper Libraries: GitHub - CrazyIvan359/openhab-helper-libraries at js-rewrite

Looking at the JSR223 docs shows:

actions | Instance of org.openhab.core.thing.binding.ThingActions

as one of the variables that is injected into the rule. Since you are after a Thing Action this should catch your eye.

So instead of getAction try actions.getAction(). I believe that will work.

If you are looking to add new Blockly blocks, also pay special attention to the examples already posted in the marketplace, for example Telegram Actions. That should give you a good template for how to create your blocks.

First … thanks to @rlkoshak and @ysc (who answers to my “old” thread https://community.openhab.org/t/copy-of-blockly-rules/130953/5

I rewrote my Blockly component to the following (based on some examples I found in this forum … thx to the authors)

uid: HUE_fading
tags: []
props:
  parameters: []
  parameterGroups: []
timestamp: Jan 2, 2022, 8:58:59 PM
component: BlockLibrary
config:
  name: Block Library c107d09908
slots:
  blocks:
    - component: BlockType
      config:
        type: HUE_fading
        message0: HUE brightness [%] %1 within [ms] %2 with Thing %3
        lastDummyAlign0: right
        args0:
          - type: input_value
            name: BRIGHTNESS
          - type: input_value
            name: FADIING_TIME
            text: some text
          - type: input_value
            name: THING_ID
        previousStatement: ""
        nextStatement: ""
        inputsInline: false
        colour: 0
        tooltip: ""
        helpUrl: ""
      slots:
        code:
          - component: BlockCodeTemplate
            config:
              template: >
                {{utility:things}}.getActions('hue',{{input:THING_ID}}).fadingLightCommand('color', {{input:BRIGHTNESS}}, {{input:FADIING_TIME}});
  utilities:
    - component: UtilityJavaType
      config:
        name: things
        javaClass: org.openhab.core.model.script.actions.Things

Also my Rule was modified to this to excute the new component only once

This all generates the following code which look good for me:

var dimTime, brightness;

var things = Java.type('org.openhab.core.model.script.actions.Things');


dimTime = 2500;
if (itemRegistry.getItem('Mod_20_EG_WC_Relais2_Hue_Brightness').getState() == 'ON') {
  if (itemRegistry.getItem('HUEWC_Helligkeit').getState() == '0') {
    print('Brightness = 0 --> ramp up to 100% ');
    brightness = 100;
  } else {
    print('Brightness <> 0 --> ramp downto 0%');
    brightness = 0;
  }
  things.getActions('hue','hue:group:02648f68d9:14').fadingLightCommand('color', brightness, dimTime);
} else if (itemRegistry.getItem('Mod_20_EG_WC_Relais2_Hue_Brightness').getState() == 'OFF') {
  print('Relais released --> stop dimming and freeze brightness');
  events.sendCommand('HUEWC_Helligkeit', itemRegistry.getItem('HUEWC_Helligkeit').getState());
}
print('* Exit Rule ----------------------------------------');

But the call of this Rule will results again in:

==> openhab.log <==
2022-01-03 19:11:18.466 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule 'aaaa': Fail to execute action: 2

From my point of view (well, a less educated guess), the JS code looks good - I got back

var things = Java.type('org.openhab.core.model.script.actions.Things');

But when I look to the action I’m not shure if the quotes at ‘hue’, the thing-ID ‘hue:group:02648f68d9:14’ and '‘color’ too are correct. Is there a significant difference between ’ and " ?

  things.getActions('hue','hue:group:02648f68d9:14').fadingLightCommand('color', brightness, dimTime);

If yes it would be easy to change ‘hue’ to “hue”, but I don’t know how to change this for the thing-ID :unamused: … but maybe this is not the problem.

When we look at the error message … “fail to execute action: 2” … is here a usefull hind burried? My assumption is, that the fadingLightCommand has a problem. In the HUE Binding discription the parameters brightness and dimTime has special types … could this be a problem?

In this context, no there is no significant difference. It’s best to be consistent and there is a preference to use ' where possible according to the style guides I’ve seen.

Just to be clear, a rule is made up of three main sections: triggers, actions, and conditions. Each section has zero or more entries. Each entry gets an ID which is a number. So when it’s complaining about action 2, it’s complaining about the Action of the rule that has ID 2. You likely only have the one Action in this rule so that’s not that big of a deal, but I just wanted to make this clear in case you think it’s talking about the second line of your script or the second block of your Blockly or something like that.

There is something so fundamentally wrong with the Action that OH can’t even give you a meaningful error beyond “can’t do it”.

I don’t see anything wrong with it, assuming those are the types that fadingLightCommand requires. I’d first look for syntax errors and stuff like that. Maybe copy the JS to a separate rule and run it there to see if you get a more meaningful error by taking Blockly out of the picture. If it works we’ve at least narrowed the problem down.

Is it possible to increase the notification level from error to a higher level like debug or something else to get more informations as only “error”?

Okay, I created loveless a new Rule with the same trigger conditions

and copied the generated code to ECMAScipt (javascript) and get … a different error message

==> openhab.log <==
2022-01-03 20:26:31.700 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule 'd03b88a74c': Fail to execute action: 3

Action 3 … hmmmm … what is it now again? I see … action 2 within the original Blockly implementation ist the JS code, while this code gets the ID 3 in the “loveless” implementation. So my conclusion of this experiment is, that the error will not be a side effect of Blockly.

So, maybe back to the parameters of the fadingLightCommand. How can I convert variables to special types? I think there might be a simple way within JS … if you could tell me how to cast the variables to PercentType and DecimalType:wink: My suggestion is, if the mistake/error is based on the wrong type, that the PercentType is the problem.

I think with OH 3.2 it’s already set to DEBUG. But you can edit log4j2.xml in $OH_USERDATA/etc to change the logging levels. Or you can change the level in the karaf console.

Click on the “Code” tab. You’ll see something like:

It’s just the unique ID for the Action that is failing.

No, it’s in the JavaScript.

Simplify. Comment everything out and then add stuff back little by little until the error reoccurs. That will tell you where the problem lies.

But you are not working with JS here. The Hue Action you got back is a Java Object. The fadingLightCommand is a Java method on that Java Object. It’s going to expect Java Objects as arguments.

Don’t guess what the problem might be. Right now we only know something is wrong. Narrow it down to a specific line.

I found the reason for the error … it is the type of the parameter objects fadingLight-Command the has to be PercentType and DecimalType. So the right code line is:

things.getActions('hue','hue:group:02648f68d9:14').fadingLightCommand("color", new PercentType(brightness), new DecimalType(dimTime));

So far so good … but the fading is not as interruptable as hoped. Means, that the brightness value of the bulb will updated, when the final brightness is reached. It can be caneled, but then I get the starting brightness, nit the current. Damned … :roll_eyes:

One way to solve this is to divide the whole dimming prozess in smal pieces like

With the wait-for statement the configuration is less comfortable, because the wait for time could’t be a variable …

And another problem is that I discovered the a color lamp will offer other funktionality than a white colored lamp … it has not one brightness value. Instead it has a vector of tree parameters … it’s an odysee, but I’m moving on.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.