Extending Blockly with new openHAB commands

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.

In that case it would not work with the persisted value either.
don’t send the command off to the thermostat, instead send command 1 to the setpoint item,
the valve should then close automatically.
after the window get closed send the stored value to the thermostat.

You are right, the variable should be stored inside.

Thanks for your help, here is my blockly that its working like i want. maybe someone want it also.

Thanks Nikos

@rlkoshak @ysc

For quite a long time it annoyed me that you cannot log something directly that isn’t a string like this number

image

or this

so finally today I took a look at it and the reason is more than simple: We have actually addeda check on that block so that it only allows Strings to be connected. Even though this makes sure it is fool-proof but in most cases it does work with everything else as JavaScript is pretty clever to convert a Number to a String or many blocks return a String anyway (even if it was complex object) like here

So in a nutshell: I would recommend taking out the check as it would make a lot quite a bit simpler when the user wanted to log it (instead of artificially adding a " " or apply it to a variable first).

What do you think?

4 Likes