Extending Blockly with new openHAB commands

Reminder of new user target audience, and the difficulties they experience with their first simple rules

when it happens to involve a Quantity

Do you refer to this topic?

and a few lines below the quote of Yannick

So in the end we might indeed have to provide a comparison block explicitely for QuantityTypes which would use “compareTo” under the hood - even though I’m not very happy about it as it adds to the confusion.

and Rich further below saying that the new Javascript libraries could simplify that in the future even more.

Is that the topic you are referring to?

If yes, it would maybe make sense to add something to the blockly documentation as a hint when using comparison as I agree this happens to a lot of people.

Yes, I have no suggestion for the best solution but this is “pitfall number 2” for new users. A great number of sensor readings come with units in OH3. I’m not sure a note in docs will do.

In other rule systems we can, say, easily compare some temperature sensor with 20°C without even knowing or caring what units the sensor comes in.
It should be just as easy in Blockly, to my mind.

DSL example
if (mysensor.state > 20|°C) ...
The Item state knows it is a Quantity type and what to do, the trickiest part for the DSL user is making the constant a Quantity too.

1 Like

I looked into this a little bit already in hopes of adding it to the JS Scripting helper library but am working on some time utils first.

Unfortunately JavaScript doesn’t really have operator overloading so I can’t just overload + and write some code to check to see if the two operands have units and do something reasonable in both cases. So now I need to find some other approach. I’ve been thinking on it to come up with a good approach but have failed so far. Obviously I can add “add/subtract/multiply/divide/gt/lt/eq…” functions that can work with both but you’ll end up with something only slightly less annoying than what we have now.

I’m definitely open to ideas.

BTW: with my utilities we’ll be able to do stuff like

if(time.toZDT().betweenTimes(items.getItem('Sunset'), '05:00')) { // is now between sunset and 5am

This is all way out of my league, but doesn’t the Java QuantityType object come with all the necessary .multiply , .equals etc.methods? Suggesting an alternative of coercing the ‘operand’ into a Java type as well, instead of trying to make the QT javascript-y.

Type problems are the number one problem among OH rules writers, be they advanced and experienced or new comers. Anything we can do to manage type problems is a good thing. I’m adding the time utils stuff so no matter what, you are one function call away from having a time.ZonedDateTime so anything, be it the state of an Item, now, or just a disconnected “13:54:00” string, can be used without worrying about type.

On top of that, the openhab-js library has a policy, maybe goal is a better word, to present the users with as pure of an environment as possible. This means converting stuff to JavaScript as much as possible. Given how JS works, just about everything except date times and QuantityType can be handled just by converting the stuff to a String.

However, as soon as you hit a QuantityType, you have to:

  1. know that you have actually encountered a QuantityType which requires knowledge outside of the rule
  2. Only use QuantityTypes when working with that value or
  3. Normalize everything to primitive floats/string

Currently the openhab-js library basically strips the units off the QuantityTypes by default, giving you just a string of the number. That is not a satisfactory solution. Forcing the end users to have to use QuantityTypes directly every time they encounter one to even do a comparison is also not satisfactory. I’d prefer to get to a point that the library makes reasonable assumptions when it encounters a QuantityType in one operand and a primitive JS float or string in the other.

For example, if I compare a QuantityType kWh to a "naked’ JS number, automatically assume that the naked number is the same units as the QuantityType and do all the conversion in the background.

As another example, provide a syntax where one can more easily define a constant QuantityType like is available in Rules DSL (e.g. items.getItem('MyKwhItem').state < "123 kWh"; (unfortunately that specific syntax isn’t possible so I’m looking for alternatives) as opposed to items.getItem('MyKwhItem).rawState < new QuantityType('123 kWh')); with the caveat that QuantityType would need to be imported separately).

We both know QuantityTypes are both awesome and super powerful and at the same time a huge pain to work with and a major hangup for users experienced and new. Heck, it’s even a pain for some of the binding developers to deal with. My hope is to find a way to ease some of that pain similarly to how I’m doing for DateTime types.

If I can free the end users from needing to worry too much about type with QuantityTypes, then I’ll have made it so that the end users don’t usually need to worry about type at all any more. The library will make reasonable assumptions or provide dead simple conversion functions for every case. Docs will become simpler and end users will encounter fewer surprises. Win win win! :smiley:

2 Likes

hello is there a way to include these blocks now and test them and if so where can I find the code for the block libraries

What block libraries are you referring to?

In general Just go the Blockly documentation on openHAB docs. At the very end there is a link to a tutorial that Rich wrote which also explains how to include a library.

See Blockly Docs → Tutorials or other useful information

1 Like

@ysc I have provided another PR to redirect all help URLs to the official openhab blockly rules documentation. It should be straight forward to merge as it does not contain any real code changes.

Where is the “get previous state” block and i cant find it??

You can find it documented here in the run & process section

Thanks for point me there, but this is not what i was looking for.
with this block i get the previous state from an item that have Trigger the rule. i am trying to build a rule that when my window is open to sent an off command to my thermostat, when the window is closed again to get the previous state of my Thermostat.

Thanks
Nikos

Where did you get this image from?

I am not really getting what you mean with “window” and what your usecase is, though if you are referring to Persistence | openHAB (".previousState()") , I can tell you that has not been implemented (yet)

The photo is from a post of you : https://community.openhab.org/t/extending-blockly-with-new-openhab-commands/127169/192

and yes i am referring to persistence <item>.previousState() Gets the previous State of a persisted Item (returns HistoricItem)
My goal is when my window sensor change from close to open then sent an off value to my thermostat. Then when the window sensor change again from open to close to return the thermostat in the previous state that is already persistent in my database.

Thanks Nikos

Until Persistence previousState is implemented you could use a workaround

If your window state changed
set the variable to get state of your item “Thermostat”
if your window state is OPEN
send command off to your “Thermostat”
else
send command “variable” to your “Thermostat”

Fair enough, Nikos, I seem to have forgotten that during implementation or it simply got lost somewhere. I have added it to my list for a latter addition to the block. It should be rather easy to add it.

As an addition Roland’s idea you can also use the Rules Blockly - Value Storage | openHAB blocks to save your state in the rule and use that later (sure, not as elegant as just using the previous state from the persistence :wink: )

Thanks for your help.

supposed window its closed, thermostat have value 20
first trigger of the rule.
when the window state changed then the variable get the state of the thermostat (20). correct
if the window state is open then send command off to the Thermostat. correct
else
send command “variable” to your “Thermostat”. false ( the rule dont come here inside)

If now retrigger the rule,
now the window is open and thermostat is off.
when the window state changed the variable get the value of the thermostat off, because of the first trigger.
and now the else sent command the variable that have off to the thermostat. false

i hope i am clear enough.

Thanks again.

i have also try with the value storage but no luck for sure my mistake.
do you know when will be ready this block??

thermostate have value 20.

What is that value, is it the measured temperature or the valve position, or the target temperature?

the 20 is the setpoint temperature of the thermostat.