OH3.2 Blockly - missing blocks to read map & channel triggerEvent

Hi,

Running OH3.2 and missing two blocks in blockly when designing a rule, but unsure if the issue is with me or not:

  1. In the list category there is a block to define a dictionary (what should result technically into a map if I understand correct), but I’m missing any block to read / get a record from the map or update the map. As this is some general non OH related stuff I googled it and a “get key” block should exist, but I cannot find it in my openhab instance.

  2. If you have a channel based trigger you can normally get the value of the triggeredEvent if you accept without blockly (e.g. On a remote control the channel name is “action” and the triggeredEvent will store which button was pressed). I would expect to find this information in Openhab → Run & Process → Contextual Info block, but had no success.

Question on both: Is this missing and already on the wishlist (or worth to be added?) or am I looking at the wrong place?

Thanks in advance

regarding 1)

This is kind of true. The dictionary was introduced by us (it is.a OH block) to allow passing parameters to other rules via a map. I only very late (but soon enough) noticed that there was a block missing that would be able to pick it up on the receiver rule side. So this is part of the release.

and then retrieving it via

image

However I guess what you are trying to do is

but there is no way of accessing this they keys from there. At least for the time being. Implementing such a block though is not a big deal and could be part of a next milestone release.

If this is not what you are looking for please be more specific what you expect.

regarding 2)

This should be the block you are looking for

see here and Event Object Attributesfor more details.

which generates the following code

logger.info(event.channel);

Hi @stefan.hoehn,

Thanks for your help here.

On 1)
Yes, you are right: I want to store the dictionary into a variable and access it within the same rule. Would be great if this can be added in future.

On 2)
Maybe a misunderstanding. Let me give you an example:
I have a osram remote control connected via zogbee2mqtt (but e.g. Philips rwl021 remote control working exactly same way) where a channel is based on the action property. Whenever a button on the remote control is pressed I get the following log entry:

2021-12-25 23:05:23.358 [INFO ] [openhab.event.ChannelTriggeredEvent ] - mqtt:topic:bde711c94b:d7b5723515:Action triggered circle_click

Where circle_click is related to the button I have pressed.

What I want to get in blockly is the “circle_click” but with your example I only receive the name of the channel, but not the event itself, that was triggered:

2021-12-25 23:05:23.386 [INFO ] [org.openhab.rule.71eb9e493f         ] - mqtt:topic:bde711c94b:d7b5723515:Action

Ok, got it. What exactly is the JavaScript command you use to receive that? Please compare that with the page I gave you that lists all the available commands.

Are you sure this is possible at all with DSL or ECMAscript?

That’s the event.event from your list.

In JavaScript a:

log.info(event.event);

is working (if I add the logger before) and in DSL rule there is the receivedEvent implicit variable, that’s documented here, but missing in your link.

Did you try the type attribute from the dropdown?

Yes, the type attribute from contextual info dropdown is logging the following

ChannelTriggeredEvent

Unfortunately you are right. I remembered that “event.event” was requested but during my testing I think I noticed it wasn’t available or at least I had issues seeing it. Now this usecase shows me that there ARE siituations where it makes sense.

I have created the following rule that is triggered by a Nanoleaf swipe and it reveals what you requir

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);

logger.info(ctx.ruleUID);
logger.info(event.type);
logger.info(event.channel);
logger.info(event.event);  // not available in blockly

[org.openhab.rule.testECMAChannelEvent] - testECMAChannelEvent
[org.openhab.rule.testECMAChannelEvent] - ChannelTriggeredEvent
[org.openhab.rule.testECMAChannelEvent] - nanoleaf:controller:4D2D1FEC7F78:swipe
[org.openhab.rule.testECMAChannelEvent] - LEFT

Here is your Xmas gift: Adding it was pretty easy: here it is already in my environment. It will be released latest with 3.2. M1

That’s brilliant, didn’t expect to receive it as a Christmas gift so quick.

Off topic that came into my mind:
If we assume that we will maybe more often run into situation where stuff in blockly is missing (because we can’t know all the use cases in the world), would it be an option to have a mixed blockly / JavaScript rule, where you can enter any custom script as fallback?

This maybe could be implemented as a blockly block, where the input is treated as a JS script and executed by the engine.

E.g. 90% of your rule can already be supported by blockly but a small piece in your rule is not working (like in this example), today this will prevent that you use blockly at all.

If there would be a script block, where you can enter any code that is executed by the JS engine, than you can start already with building 90% of your rule in blocky, add some missing pieces in JS. Once the missing parts are available in one of the next releases you only need to update a small portion of the rule.

This is actually already possible as you can call a script block already by using this block

The only downside though is that it is not possible to “return” anything from the rule as far as I know.

There is another alternative though: you can build your own blocks similar to building your own widgets which is described here. Although it is not an easy task for the common user, I am sure that some people in the community could easily provide that (feel free to jump in) and upload the block then.

Agree, but I was more thinking about to have another script run within the same context, sharing variables and also having the option to return something. But that’s fine for now, as we all need to have something on our wish-list for next christmas :slight_smile:

On the block libraries:
I currently have already written a toggle and copy block, where the toggle will change a switch item easily between ON and OFF and the copy will obviously copy an item state to another item, what I use for some proxy items to update.
Goal is to reduce complexity and have a more easy to read code.

Once I have converted more rules to blockly and have identified other useful snippets my plan is to publish them in a combined library.
image

1 Like

That looks cool as well. One note about toggles that I am always struggling with when I use it in the frontend is when the initial value = NULL - then the toggle doesn’t work. So you may keep that in mind and code that in…

Regarding the copy state block: could you just do the following (though yours looks more elegant) ?

Here’s another gift for you which is already which I intend to deliver with 3.2.M1:

What do you think about the inline-Script block? :wink:

which would the result into the following code altogether:

myDict = {'key0': 'abc', 'key1': 'def'};

myDict['key0']='123'
myDict['key2']='456'

logger.info(myDict['key0']);
logger.info(myDict['key2']);

The inline script and the additional dictionary blocks look great! Thanks a lot for this.

Regarding the copy:
Yes, your “send command(get state of item, item)” is technically exactly the same. My only intention was to make the blocks more easy to read (maybe it will help some beginners who are not so familiar with scripting).

Regarding the toggle:
I already thought about the NULL issue, but as this is only a onetime issue after initial item creation, I thought we do not need special handling.
Currently a toggle block is creating following script, where the NULL situation is covered in the else part and the item would change from NULL to ON

if (itemRegistry.getItem({{input:toggleItem}}).getState() == 'ON') { events.sendCommand({{input:toggleItem}}, 'OFF'); } else { events.sendCommand({{input:toggleItem}}, 'ON'); }

Good.

but as this is only a onetime issue after initial item creation

I have only mentioned this because it has already annoyed me so often in the past :wink:

I there any example how to check for the initial value == NULL?
I tried the following, but none works:


you can do it like the following

which creates the following code

 
if (nullVar == null) {
  logger.info('Variable nullVar equals null');
}

Thank you, Stefan. :slight_smile:
I will try this.

Unfortunately this does not work either:

during startup when my last received Telegram command is restored from persistence (from NULL) this leads to:

2022-06-14 06:32:27.839 [INFO ] [org.openhab.rule.TelegramCommando   ] - TelegramBotHomerBot_LastMessageText
2022-06-14 06:32:27.897 [INFO ] [org.openhab.rule.TelegramCommando   ] - NULL
  • Can you log out the prevState variable and show the log output?
  • Can you please paste the generated code here?