Group-Handling with blockly

cc @Christian_Kittel

First of all, I had to look what is happening and I will explain that (which is partly, I am sure, what you meant, Rich).

Buckle up, the explanation becomes a bit complicated (and bear in mind the time of writing :zzz:)

First let’s look at this

A) Why doesn’t “get xxx of item” connect?

This actually depicts an issue I have described in the blockly reference as a bug. Unfortunately a wrong blockly output type was used which does not allow the block to connect. There is a bug fix PR already waiting. Depending on the chosen attribute it now produces either a String or an oh_item, which works well.

The reason you made it possible to work with is via the Variable-Workaround which basically tricks blockly and let’s you assign anything which is a workaround for that bug. Hence, you can use it in any block and therefore in your if-statement.

B) Why does “get state of item” throw an exception?

First, the log works because it just asks any given block to produce its String-representation. That is why it works.

Now let’s look the following two examples in the for-loop:

with the related code that is generated

var member_list = Java.from(itemRegistry.getItem('Lights').members);
for (var member_index in member_list) {
  member = member_list[member_index];
  logger.info(itemRegistry.getItem(member).getState());
  logger.info(member.getName());
}

The second line in the loop uses (the bug fixed) “get xxx of item”, which is a more generic version of the up to now existing “get state of item” in fact expects a “oh_itemtype” as an input type and references the following block which produces “itemRegistry.getItem(‘MyItem’)”

oh_itemtype image

As a result the block
“get state of item” image
wants you to only allow the oh_itemtype to be attached like so

I just noticed that can even attach a thing-block which is hard to be prevented because neither the thing- nor the item-type is “typed”, so it connects everywhere. I am hesitant to add type-awareness to these at the moment because I fear the side effects that might break zillion other places

Anyways, as you can see above, if you use the right block it expects (a real item) it produces

logger.info(itemRegistry.getItem(member).getState());

because the “real item” produces

itemRegistry.getItem('myItem")


So why does the first line then throw an exception?

image

Well, it expects not a “real item” but only the item reference (the green block) which simply produces ‘myItem’ but member is not a String but an Object, so you get an exception (you cannot ask the registry to retrieve an item by providing an item).

But why does it then allow you to put into that block if it throws an exception?

The reason is that blockly assigns that to a variable which then loses its type in the code. So during the code generation I (the programmer of the blocks) have no clue what code should be generated (with our without itemRegistry). So the only smart idea (and now I am back at Rich) would be to generate a code that is capable of working with both by checking the type during runtime (by the way, Rich uses the new Javascript engine here with item which is not yet supported by Blockly
 I know Rich :wink: )

In summary, yes, Rich, it can be done because the whole situation above is too hard to explain anyone, so it must become more fool proof internally. Hence, I started a Proof of concept (even more :zzz:) and I was able to achieve that:

So both ways work now because it produces the following code (which doesn’t look nice but at least does work behind the scenes):

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var member_list = Java.from(itemRegistry.getItem('Lights').members);
for (var member_index in member_list) {
  member = member_list[member_index];
  logger.info((member instanceof org.openhab.core.items.GenericItem) ? member.state : itemRegistry.getItem(member).getState());
}
logger.info(('Lights' instanceof org.openhab.core.items.GenericItem) ? 'Lights'.state : itemRegistry.getItem('Lights').getState());

I also changed this for the “get xxx of item”-block.

The fix is now part of [blockly] Fix item.getAttributes by stefan-hoehn · Pull Request #1254 · openhab/openhab-webui · GitHub


(i have added this thread to Blockly Reference as a known issue)

1 Like