Journey to JSR223 Python 1 of 9

I’m OK with changing the names. Submit an issue and we can discuss in the repo.

I looked and didn’t find them. One of the challenges I’m finding with the Helper docs is you have to know what to search for to find anything useful. As I gain experience this will get better but it isn’t always clear of obvious what to search for or where to browse to to find what I need. Even now, I can’t find anything even when I search for sendCommandCheckFirst and there is no util entry under core in the docs.

I do remember those methods from lewie’s JS library but when I couldn’t find them (I forgot what they were called) I assumed that they didn’t make the cut, or you would pipe in and tell me where they are. :wink:

I thought I remember reading that UoM wasn’t supported yet so I didn’t even think to look. I still don’t see that at the link. Do you mean there needs to be an Issue and eventual PR to document UoM?

So I cheated a little bit. The actual place I observed this was in the body of a Timer. I had a timer function that just had a logging statement and I messed that statement up as described. There was nothing at all in the logs. So perhaps it is only completely silent when it errors in a Timer lambda, which raises the question “What other errors get suppresses in Timer lambdas?” I should probably move this “lesson learned” to my second posting (when I rewrite it) and make the context a bit more clear.

I’m glad you guys are chiming in and seeing these posts. Granted, I know more than most so am not a perfect “noob” user. But I will provide more documentation on my progress translating my Rules and therefore learning the language and libraries. I hope my experiences are useful to both other new users and the maintainers to identify potential trouble spots.

2 Likes

It will be there tonight after I push. A lot of the docs are fed by docstrings, so when in doubt, you might try checking in the modules if you don’t find something in the docs. Having trouble finding these as a beginner is good feedback. Do you think a layout change might help, or is this just something that will come with experience?

Definitely ping me if there’s anything I can help with! There’s nothing too small. That goes for anyone trying to get into Jython/JS/Groovy/etc. rules!

It’s in there… third example down. Just type ‘QuantityType’ in the search. I’ll add a separate entry.

Yes… timers do eat errors!

I’m not sure. Maybe providing enough synonyms in the docs so the search function in the docs works would be helpful. Let me do some more and I’ll see if I can think of something better. Right now I’m spending 80% of all my time on the “But How do I…” page and I suspect I’m not alone in that. So if I were to put any major focus it would be on that page. Maybe it would be useful to have some links to the reference docs from there which will help some users orient themselves to the doc’s overall organization.

Not sure how I missed that. But this is a good example where synonyms would help the search. I suspect I was searching for “UoM” or “Unit of Measure” or variations of that.

1 Like

Sorry to hear.
Hope you find time and the spirit to do it over … looking forward to read it.

Thanks for this tutorial … how-to

Would you please tell me why you are converting your rules?
Will Rules DSL be obsolete in the near future?
Or is JSR223 so much better?

What would you recommend?
Should a beginner (me) with little coding skills try to learn the new language and do the covertion too?

1 Like

Lots of reasons.

  • I like to learn new things. I can write Rules DSL Rules in my sleep now.
  • More and more people are using JSR223 Python on the forum and I’d like to be a resource to them too.
  • Reports are that they run faster, though that hardly matters in the home automation context.
  • To help contribute to the docs for them (maybe the code someday).
  • To provide a comprehensive set of before and after examples for others looking to migrate as well.
  • Prime myself for the development of Rule Templates that others in the community can use. No more copy and paste of code from the forum.
  • While I have defended the Rules DSL over the years, as a coder, I myself am more comfortable using Python or JavaScript than Rules DSL.

I expect that Rules DSL will be deprecated in OH 3. That doesn’t mean unsupported but it does mean that all the docs, all the example, and all the defaults will be geared towards UI created Rules and JSR223 Rules, which though they have some differences, are executed by the same Rules Engine.

When a more usable UI is released for developing Rules, that will be the primary way new users and particularly non-coder users will develop their own Rules. The UI developed Rules will use JSR223 scripts like the above in cases where custom code is required.

For a certain class of OH user, namely those who already know how to code, JSR223 Rules are objectively better. For others, it isn’t so clear. The UI in PaperUI is kind of unusable at the moment (a replacement is under development). Setting up JSR223 with the helper libraries is a few extra steps which some users may not be willing to do. And tooling for development (i.e. JSR223 equivalent of VSCode with the openHAB Extension) is much less capable.

You will be fine sticking with Rules DSL. It isn’t going anywhere in the near term or mid term. I’d recommend waiting until the replacement for PaperUI’s Rule UI is released and then consider migrating your Rules to that.

But if you want to get more into coding or don’t want to wait then by all means. Take the plunge.

2 Likes

Thank you for the detailed comments.

from core.utils

And I was struggling with the literal translation of the rules DSL code as I couldn’t find the simple sendCommand.
Sure I finally found it in the ‘how do I’ section but it would have been better to point there this early.

Then a line like events.sendCommand("Terrasse_Bewegung_Timer",ON) for me still results in the error below, again making me wonder why. Ok, found out “ON” needs to be in quotation marks, but why is ON no string ? Why does sendCommandCheckFirst work with either ON or "ON" then ?
These little subleties such as implicit data types are really confusing because you never know if it’s your Python (lack of) knowledge or specific of (not) having imported the right package and most important, which package to import. And where’s the list of those ?

Actually I find the most challenging part for a migrator to date is to find out which lib/class commonly used stuff is in that you didn’t need to explicitly import in Rules DSL.

2020-01-01 16:40:22.905 [ERROR] [on.Weihnachtsbeleuchtung einschalten] - Traceback (most recent call last):
  File "/etc/openhab2/automation/lib/python/core/log.py", line 51, in wrapper
    return fn(*args, **kwargs)
  File "<script>", line 23, in Weihnachtsbeleuchtung_An
TypeError: sendCommand(): 1st arg can't be coerced to String, org.eclipse.smarthome.core.items.Item

2020-01-01 16:40:22.938 [WARN ] [e.automation.internal.RuleEngineImpl] - Fail to execute action: 1
org.python.core.PyException: null
        at org.python.core.Py.AttributeError(Py.java:207) ~[?:?]
        at org.python.core.PyObject.noAttributeError(PyObject.java:1032) ~[?:?]
1 Like

Well, these posts are not and never were intended as documentation. There are just what it says in the title, my journey. They show my experiences and struggles and successes. As I was writing these posts, I had the “How do I” page open at the same time next to my VSCode.

By default, in the Python Rules there is only the sendCommand Action. And as with Rules DSL, the sendCommand Action only accepts to Strings as arguments. Unlike Roles DSL, Python doesn’t do the half assed only right some of the time autoconversion of types (e.g. from OnOffType ON to String “ON”).

The Helper Library core.utils has a sendCommand function you can call that works more like what you are used to when calling MyItem.sendCommand() in Rules DSL (i.e. it accepts an Item it the name of an Item as the first argument and a String or Type such as ON as the second argument. It then does all the conversions for you.

When I wore theses posts, I didn’t really understand that aspect so I neither mentioned it nor used the core.util.sendCommand function.

Hopefully the above explanation makes this clear. events.sendCommand is like calling sendCommand(“MyItem”, “ON”) in Rules DSL. Consequently both arguments must be Strings. And Python won’t try to guess and convert them for you. It works with the core.utils versions because those functions are written in such a way that they accept both Types and Strings.

I know that Scott is working to make the Helper Libraries just be available when you install the Rules Engine but I don’t know if core.utils is planned on being automatically imported into the context so you don’t have to import them. @5iver, any comments?

The real challenge is in Rules DSL the tires are implicit. In Python you at l have to be explicit. So a call that you used to be able to get away with in Rules DSL like sendCommand(“MyItem”, ON) you can’t get away with in Python because Python won’t automatically convert the ON to “ON”. That’s why the core.utils functions were written.

They are all documented in the Helper Library Docs here.

Because it is using an Item rather than a String name… https://github.com/openhab-scripters/openhab-helper-libraries/blob/master/Core/automation/lib/python/core/utils.py#L130.

Without core.utils…

events.sendCommand(itemRegistry.getItem("Terrasse_Bewegung_Timer"), ON)

I’m not clear on what you are referring to. Do you mean these?

https://openhab-scripters.github.io/openhab-helper-libraries/Guides/Event%20Object%20Attributes.html

It’s important to understand these too… https://www.openhab.org/docs/configuration/jsr223.html#events-operations.

Everything you need should be included in the default script scope or one of the other presets. Let me know what you are missing and I can add them.

Yes… I definitely plan to include some utility functions in the Scripting API

1 Like

Sure I got that. But I think now that others embark on the same journey it’ll help them if you revisit and enhance them a little so they can shortcut those struggles, no? Please fix the typo in the ‘is it cloudy ?’ code (“from core.utils …”)

As Rich mentioned, too, as a newbie you have some rules DSL code like the sendCommand() line in my example and are looking for the Python equivalent. I was thinking of something like the inversion of https://openhab-scripters.github.io/openhab-helper-libraries/Python/Core.html, i.e. have a table/register that for my example would have an entry for sendCommand() point back to “core.utils” so I know I need to import that and prioritize/select that if there’s multiple of the same name.
But I guess it is also sufficient to just give that link and to recommend browsing these tables before looking elsewhere.

Here is something else that is easy to miss… the helper library docs have a search tool at the top left…

https://openhab-scripters.github.io/openhab-helper-libraries/search.html?q=sendCommand&check_keywords=yes&area=default

core.utils.sendCommand was grandfathered in when lucid was migrated back into the main repo to maintain backwards compatibility for people that had been using lucid. I think it has caused more trouble than it solved. Just use events.sendCommand.

:+1: that was what I was looking for and yes I, too, missed that until now.

2 Likes

I’m not sure how to do that without completely transforming them into a straight up tutorial which will require a complete rewrite. If I’m going to do that I may as well just write the official docs. But they’re is too much changing right now to really get started with that too (confectarian got a good start but had to back off as well).

It’s not clear is yet with the effort to get started on such a guide given significant portions of it will look significantly different from what it does today. For example, we are one pr merge away from a wholly new set of instructions for installing Python.

All of these are good things that need to be included in the docs when they get written, but it’s not clear yet what issues we now face will still be there next week, next month, and beyond.

I’m getting a 500 error when I try to edit the op. I’ll have to make the fix later.

Lately I have been getting those 500 errors whenever I try & tag a thread too. I think the forum server has issues.

Hello to all,

I posted this here because it has to do with using a library function for sending info and unicode.
I am using the jython helpers library with the jython-standalone-2.7.2.jar and I trying to use a simplified util.py example from @rlkoshak:

from core.jsr223 import scope
from core.actions import NotificationAction
from configuration import admin_email

def send_info(message, logger):
    logger.info("[INFO ALERT] {}".format(message))

but when calling send_info in my test rule file specifying that the string has unicode with u"string":

from core.rules import rule
from core.triggers import when
import personal.util
reload(personal.util)
from personal.util import send_info

@rule("JythonInfoTest", description="Jython Info Test", tags=["info"])
@when("Item SwitchJythonInfoTest changed")
def jython_info_test_rule(event):
    if items.SwitchJythonInfoTest == ON:
        send_info(u"Máquina Lavar Roupa - Começou!", jython_info_test_rule.log)
    else:
        send_info(u"Máquina Lavar Roupa - Terminou!", jython_info_test_rule.log)

I have an error:

2020-07-31 10:01:11.090 [ERROR] [jsr223.jython.JythonInfoTest        ] - Traceback (most recent call last):
  File "/etc/openhab2/automation/lib/python/core/log.py", line 51, in wrapper
    return fn(*args, **kwargs)
  File "<script>", line 25, in jython_info_test_rule
  File "/etc/openhab2/automation/lib/python/personal/util.py", line 6, in send_info
    out = str(message)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 1: ordinal not in range(128)

2020-07-31 10:01:11.101 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule '458332f8-34da-4007-9ec7-9d1921b7a08e': Fail to execute action: 1

If I call it like this it works:

jython_test_rule.log.info(u"Máquina Lavar Roupa - Começou!")
jython_test_rule.log.info(u"Máquina Lavar Roupa - Terminou!")

but using the library function send_info it does not. I know this should be something simple for you guys but I did not manage to get it working.

Could you please give me hand on this one.

Thanks for your help.

@rjduraocosta, please post your issue in a new topic and I will help you there.

Hello @5iver,

Done.

Thanks again.

2 Likes