Extending Blockly with new openHAB commands

As I might think we want design a bit around the ephemeris I have copied your ideas from the github discussion to here:

From Yannick,

"I still don’t think it’s right to mix several functions that do unrelated things together. Having a block for each operation seems the right way to go.

One suggestion to have the ability to do offsets or not is to introduce new types that are only compatible with inputs in the Ephemeris blocks (and fill the input with a shadow “today” block by default), like this:

image

Then there must be a way to figure out the day/day-with-offset input in the code generation of the actual blocks, I haven’t checked yet."

I like the design as above, only that I think that the comparison shouldn’t be static but be rather coming from a drop down like so (Otherwise we would get more permutations of blocks).

image
(of course the “today” is a puzzle piece like you did above - I wasn’t clickly able to prototype that with the blockly demo tool)

Also the question would be if want “is a weekday” which basically is the same like NOT → "today is a weekend) but doesn’t sound as nice. Instead I could invert it internally and provide the weekday function for the block.

I agree with @ysc’s list of priorities.

My biggest priority though would be to implement those things that would bring Blockly at least up to Rules DSL in terms of what it can do. So the core actions (Actions | openHAB) would be at the top of my list, perhaps even above Item metadata.

I’ve found the ability to call other rules to also be super powerful so I might place that even above Item metadata.

I like what I see there. It seems simple enough and supports the core Ephemeris capabilities. I’m not sure Blockly needs to ever support custom day types or custom holiday files.

I’ve found the ability to call other rules to also be super powerful so I might place that even above Item metadata.

I have never done that. How can this be done? How does that look like in ECMAScript? Any Example?

// Run another rule
var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
var _bundle = FrameworkUtil.getBundle(scriptExtension.class);
var bundle_context = _bundle.getBundleContext()
var classname = "org.openhab.core.automation.RuleManager"
var RuleManager_Ref = bundle_context.getServiceReference(classname);
var RuleManager = bundle_context.getService(RuleManager_Ref);
RuleManager.runNow("tocall");
var map = new java.util.HashMap();
map.put("test_data", "Passed data to called function!")
RuleManager.runNow("tocall", true, map); // second argument is whether to consider the conditions, third is a Map<String, Object> which is a way to pass data to the called rule

From the called rule you can access the passed in data from the map using context.getAttribute("tocall");

As with Item metadata, there is a lot of up front stuff needed just to get to the RuleManager.

1 Like

Perhaps the Persistence Extensions (openhab-core/PersistenceExtensions.java at main · openhab/openhab-core · GitHub) can be used with this technique as well
(with some very simple controls to provide the function & ZonedDateTime, like “{dropdown average/maximum/minimum…} since {int} {dropdown:seconds/minutes/hours…} ago”)

Also there should be some review of all output types and type checks to avoid situations like these: Blockly handles comparison differently when taken from state directly or from intermediate variable · Issue #836 · openhab/openhab-webui · GitHub
(blocks refusing to assemble because of incompatible types)

How does Blockly handle Units of Measurement? That might actually be the highest priority to me given how often it shows up and how many problems it causes. Even if we don’t actually support the units themselves, we hopefully can at least make it work by calling .floatValue() on the states from Number Items.

The big problem is many bindings do not let you choose to use just a regular old number. You have to link the Channel to an Item with units.

Not too well I think. There could be a need for a “float value of” block.

Funny as this is my own issue and I am now in the position to fix it myself eventually :smiley:

Finally, after almost 2 weeks of trying to repair my OH production system and then finding the problem, I am back on track for blockly development… sigh…

Here is my latest design for the ephemeris blocks

with an example

generating

var ephemeris = Java.type("org.openhab.core.model.script.actions.Ephemeris");

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


if (ephemeris.isWeekend((0))) {
  logger.info('today is weekend');
}
if (!ephemeris.isWeekend((3))) {
  logger.info('today in 3 days is weekday');
} else {
  logger.info('today in 3 days is not a weekday');
}
if (ephemeris.isBankHoliday((0))) {
  logger.info('today is bank holiday');
}

@ysc Was it intentional that the today-block is black or should it have the OH color?

@rlkoshak Can you check if there is any other method we would need from here ? I don’t think so.

With that ephemeris is done. On to the next one.

@rlkoshak regarding

So the core actions (Actions | openHAB ) would be at the top of my list, perhaps even above Item metadata.

Which one would you like me to do first then?

  • edit: “real variable persistence via actions” is not possible
  • exec in /usr/bin/command
  • http call and ping
  • calling another script
2 Likes

posted openHAB specific block reference here
Let me know if pictures aren’t showing or some such :confounded:
and who can tell me how to make a post a wiki or just do so

Thank you, Andrew, for starting this :smiley:

The images come out fine so far.

I have several questions and recommendations

  1. Where would this page be located after the final write up? I would expect it to be near to Rules | openHAB but like https://www.openhab.org/docs/configuration/rules-blockly.html

I would therefore recommend to “write/design” it in that style.

  1. I wonder if it is possible to create subpages as I think the documentation could become pretty long. Unfortunately from it seems that this seems not possible? At least the menu to the left does not support it, does it?

  2. Can we move the documentation to github there and can collaboratively edit and review it?

  3. One of the added value of documentation is that it explains how to use something. With your notes I think you started doing that. Don’t get me wrong, I am happy you started it! :star_struck: What I love to see though is a comprehensive documentation eventually that allows openHAB users to quickly write rules without knowing too much about programming. So here’s my product vision for the blockly documentation pages :angel:

Therefore I would wish to read

  • what the block is meant for (and not only what it “does”). For example the things-block allows you to iterate over several blocks with a loop (see an example in this thread)
  • provide an example how it can be used (maybe not for each and any block but at areas where it is providing a more comprehensive understanding) - see this thread here for the many examples I have provided and I am sure we could do more
  • The blocks have tooltips that link (with sub-anchor) to the API-page that explains technical background, e.g. Ephemeris-Subsection. I would also add that link to the respective sections within your documentation.
  • Some of the blocks need setup to work. We should link to the respective pages within the openhab-doc-pages that explain the setup and it these are not yet comprehensive enough then also extend those. The reasoning behind that is that users who use blockly are probably not too technical and should find an easy to follow setup guide or at least a link to there, so they do not get frustrated to get it running quickly (for example voice tts).
  • I would love to have an introduction section about blockly on how to use them and link to respective official blockly pages that help the use get started even more quickly. That should also include some tips on how work with blockly (e.g. the code page) and how to “debug” it in case it doesn’t work as expected.
  • Maybe we can extend the pattern pages that Rick has provided over the years with examples how these can be done via blocklies now?

And having said that, of course I am happy to jump in and add to the documentation myself.

cheers
Stefan

good question Stefan
I remember Rich and Jerome having a discussion earlier in this thread about where the Blockly documentation would fit in and how it should be presented. I think that will have to be worked out. That is why I created a document here in the forum until such decisions can be made.

That is exactly right, I ‘started to do that’. Some of the blocks, I wasn’t sure exactly how they work and didn’t have time to try them out or look at the underlying code.
I agree with providing examples and links to more information ect. All great ideas

I figured, the say command for example requires a TTS service correct? That would need to be mentioned.

agreed

yes, yes agreed, if one of the mods can make the thread a wiki or tell me how to do so myself or move to git to work together is good with me.
The original doc is free to copy, modify or whatever

Initially no, but eventually ‘why not’ as it’s a new type dedicated to specify the day offset that thanks to a special output type, and the input check on the Ephemeris blocks, shouldn’t be useable outside the latter.

You may have noticed that I reverted the “item {}” and “thing {}” blocks under the openHAB category to the green-teal color that identiies text/strings (in the Text category), even if they’re not in the Text category themselves. IMHO this makes sense because these blocks only yield item names as Strings, only with a helpful UI, and can be manipulated with blocks from the Text category.

So if in the end we settle on an output type that represents date/time offsets, which could perhaps be used in both Ephemeris and persistence-based calculations, as discussed above, then we might choose a dedicated color for them and stick to it.

You may have noticed that I reverted the “item {}” and “thing {}” blocks under the openHAB category to the green-teal color that identifies text/strings

I actually hadn’t :slight_smile: so it is good you have just mentioned it.

The today-blocks are indeed already typed as

this.setOutput(true, ‘EphemerisDay’)

and it can only be applied to the Ephemeris-Check-Block.

Note that this is not a date-type because the API does not use a date but rather expects either today (=0) or “today+/-number” (=number). So the block is nothing different than the provided number in the end. We could have even completely left out the today-piece and just have the number but the idea you came up with with the today block looks much nicer, I think.

To be honest, I overlooked that there is a method to check the weekend by a date (see the third row)

isWeekend true if today is a weekend, false otherwise
isWeekend(<offset>) true if the day <offset> days from today is a weekend
isWeekend(<datetime>)

I used Date fields  |  Blockly  |  Google Developers as a new block type and now it is possible to also provide a date like so

Note that the date picker DOES NOT allow to the provide the date by variable containing a date! I can also not just allow a string because I need to know if a today or date field is provided to internally distinguish the read method to be used. They only way would be to provide a third date block that does not provide a date picker but would allow to provide a string instead directly. The issue with that though is that providing a date with the wrong format would result into an exception.

So, do we want to give the same greenish color or something else?

It looks really good. Thanks!

It’s of secondary priority but getBankHolidayName and daysUntil would be useful to a number of users.

Which ever use easiest I think. They are all pretty important though we will probably want to limit the http actions to just the simple cases.

I have to go back to

  • “real variable persistence via actions” - unfortunately I got it wrong. I thought this would be a method to persist values via openHAB but if course this is nothing but setting an item to a value and these methods allow the persistence functionality to be used to for example to retrieve an average or sum or lastValue…

So I would need someone who is willing to tell me what types of blocks we should really provide here and which not.

Ok, I’ll take care of getBankHolidayName and daysUntil at a later time.

Please recheck the above writing for ephemeris as I added a date option there.

I also added

Perfect! It’s looking really good and really useful. Thanks again for all the hard work!

1 Like

I’m not sure because that color denotes arbitrary Strings that can be manipulated - even if they are item names or thing UIDs - you can add suffixes, make substring replacements etc.

Ephemeris arguments I think are too specific to be considered arbitrary strings or numbers or dates, and the manipulation of these is probably not desirable. In the Voice & Multimedia category you have another example, the audio sinks and voices. While they are technically Strings the fact that they’re in another color entirely means the user should reuse them as-is and leave them be.

Note that you can update blocks based on e.g. the value chosen in a dropdown: see blockly/math.js at master · google/blockly · GitHub, the implementation of the blocks in the Math category. If you try the “0 is even” block and change the dropdown to “is divisible by” you’ll see that an input is appended to the block. Also in the “1 + 1” block you’ll see that the tooltip changes based on the chosen operation.

The file above has the implementation for those; it’s a little convoluted since they use mixins and mutators.

For reference in the Blockly repo (GitHub - google/blockly: The web-based visual programming editor.) you can find the block definitions of the standard blocks in blocks and the code generation in generators/javascript.

So do we want to take a different color like the sound gray one ?
image

for those who reading along the thread, this is what Yannick mentioned
image
image

Thanks for the hint - that is really interesting to know.
Now I remember that I have been reading something about that here where he explains how to do that.

Do you had a particular idea in mind where or in which case it would improve the new blocks or was it rather a general hint so I know (which I didn’t and appreciate to know now).

Thanks, it is about time I look closer into their blocks to learn from them. I am sure this could be a good treasure trove to get new ideas.