Extending Blockly with new openHAB commands

Given the nature of timestamps, unless the two operands are literally the same variable, they will never be equal. The Java ZonedDateTime has a resolution down to the nanosecond. It’s almost impossible to generate two separate timestamps that are the same at that resolution. That’s why ZonedDateTime doesn’t really even mess with equals.

So I would say, don’t bother with <= nor >=. == will only return true if the two timestamps are really the same variable. To actually compare two different timestamps for equality, you need to do it in a fuzzy way. Decide on a resolution, for example, equal within a second or equal within 100 milliseconds.

I think it should be the blueish logic color. It’s a logic block so I think that’s most appropriate.

In Stefan’s example he’s comparing dates though - this would be equal timestamps for the same date, wouldn’t it?

1 Like

We currently have this one already

image

How about adding a more generic one like so?

2 Likes

If you just have a date and no time then a LocalDate should probably be used. I don’t know what is backing the “date” block but my original comments and concerns had to do with ZonedDateTimes (and LocalDateTimes if we are being thorough).

Yes, making that more generic would work, but we would still need to support now.

These are all backed by ZonedDateTimes from day one which I am hesitant to change not to break anything.

I would have to add an additional one because otherwise it would break the rules that use the now-related one.

Hello together,

thank you very much for your effort to extend Blockly for OH.
I was planning to use Blockly for my rules and scripts exclusively. Due to the lack of some functionality I started to write my own Blockly libraries in OH.

I would like to compare to dates, The date-block generates a ZonedDateTime with the fields for time set to 0. Every time i want to check a specific time against another ZonedDateTime I have to alter the time fields returned from the date block with a custom block. This is functional but results in a huge block.

The FieldDatePicker is a nice way to select a date. I think a similar or combined one for the time-component of ZonedDateTime would be useful.

Is it possible to instantiate the FieldDatePicker with yaml and get the selected value to a block defined in a custom Blockly library?

1 Like

Apparently not - because you have to feed it the f7 object instance, which you cannot do in YAML. I’ll try to find a solution.

In OH 3.2

I’m doing a script (actually Groovy) which is called from a UI rule. But there’s not much help on that and if I figure the blockly code I can normally work back to Groovy.

So, I’m having problems getting the mqtt binding UI to send json output right so I thought I’d do it in my script. However, I can’t see how to find a link to the action to do the publish.

Previosly I’ve done this;

def mqttActions = getActions("mqtt","mqtt:broker:mqttbroker")
mqttActions.publishMQTT("sensors/garage/command/door1", "STATUS")

but when I do that in the rule i get;

2022-01-11 15:43:37.760 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'ec4c7f85d1' failed: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.getActions() is applicable for argument types: (String, String) values: [mqtt, mqtt:broker:mqttbroker]
Possible solutions: getFactory()

How do I get this with my script?

And more generally. I found I have access to a variable called triggeringItem which I can use in the Groovy script, but I only stumbled across it working because I’ve used in other scripting. Is there a definative list of all the things in scope which I have access to while executing my Groovy script from within a UI rule?

See JSR223 Scripting | openHAB

That shows almost everything that exists in your rule be default. For your first question you’ll notice actions which is access to the ThingActions class. That’s what getActions() really exists on. Rules DSL hides a lot of that sort of thing from you.

def mqttActions = actions.getActions("mqtt", ...

What isn’t in those docs is the event Object which also gets passed into your rule. This contains information about the event that caused the rule to run. See Event Object Attributes — openHAB Helper Libraries documentation for the most comprehensive docs I know of for what event will contain under what circumstances.

There is no equivalent to triggeringItem but there is event.itemName. You can get the state from items[event.itemName] (or what ever the syntax for working with a Map in Groovy is). You can get the actual Item using ir.getItem(event.itemName).

It might be the case that you also get the same implicit variable as Rules DSL rules get. If so see Rules | openHAB.

  1. I thought that too, but there is not getActions on it.
2022-01-11 16:44:42.180 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'ec4c7f85d1' failed: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: org.openhab.core.automation.module.script.internal.defaultscope.ScriptThingActions.getAction() is applicable for argument types: (String, String) values: [mqtt, mqtt:broker:mqttbroker]

Not sure what I’m meant to do the ScriptThingActions? to get to something I can call publish on.

  1. That list of things is scope was useful. I think it’s just missing triggeringItem from the list. It’s only defined when called from a ‘member of’ rule. But I think it should be in the list, as useful.

Got it!

it’s differently named…

def qttActions = actions.get(“mqtt”,“mqtt:broker:mqtt_broker”)

Then all I can say is that Groovy works differently somehow and you’ll have to figure it out on your own. I can’t help with that. In Nashorn JS and Jython which are both JSR223, what I wrote is how to get at the Thing Actions.

I’m not sure what ScriptThingActions are either. I can’t find that in the OH JavaDocs. It might be a private data member class or something.

Glad you got it. I should have looked up an example before just going from memory.

Typically in JSR223 the standard way is to use event since it’s more complete and explicit and doesn’t depend on “magic” the way that Rules DSL rules do. In other environments like JS Scripting or jRuby the Rules DSL implicit variables do not exist at all.

Note, that list of things that is in scope is the default preset. It’s what gets exposed in the rule by default no matter what. triggeringItem, triggeringItemName, newState, etc. are implicit variables that depend on how the rule was triggered. They are not part of the default preset. They are like the method arguments passed to the rule when it’s triggered. These do not belong as part of that table.

@rossko57 , thanks for explaining. a little clearer now. I might change my code to use event, just to keep it more in line with practice.

Thank you guys for the fantastic work done on Blockly: I’ve migrated so far 90% of my rules and I really enjoy this addition!

I was just wondering if there is already in place a better way to have more than 2 “and/or” conditions than this:

no big deal, but it’s not pretty :slight_smile:

You could put the inputs of one or more blocks on new lines instead of inline. Like so:

Or you could use variables to hold some of the partial results

1 Like

Sometimes I use that option to make the script more “readable”, but I was referring more to the possibility of adding an option in the block itself to select the number of “and” needed in that block.
Something like we have in the “list” block, where you can select the number of items/lines needed

1 Like

@stefan.hoehn: Are there any news on this topic or is it possible to access the event variable? I can not declare a variable in blockly to event.

Thanks for your work!

it is part of this pull request which has been merged at the 16th of January: add hsb block, dict get, triggeredEvent, check value, inline script by stefan-hoehn · Pull Request #1261 · openhab/openhab-webui · GitHub and will be part of 3.3

1 Like

Thank you! Sounds very good!

Is there a way to create a timer with pre-selected number item as time?

F.e.
pre select a number in a number item with stepper-list-item
Turn on a light
schedule a timer via blockly and take take the pre-selected number with unit (f.e. minutes)