Journey to JSR223 Python 1 of 9

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

Hello, is this tutorial still valid with OH 3.0?

I’m using version 3.1.0M4 and apparently something must be modified, because for example even the simple line:

from core.jsr223 import scope

causes an error:

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'myscript' failed: ImportError: No module named core in <script> at line number 5

@Frank_Pepperyellow you should be able to use the code in this series with only minimal changes. The Python/Jython part of these tutorials did not change from OH2 to OH3, but parts for OH did so you may need to change things that interact with OH yo work in 3. Largely the only thing you need to change will be DateTime related. OH2 had Joda DateTime installed and it was encouraged to use that, OH3 does not have Joda so you must use Java’s ZonedDateTime instead (which is also available in OH2).

In regards to the error you saw:

```
Use code fences like this when posting logs or code. 
Enclosing the log or code in 3 ticks, like you see
above and below here, will make it look like this
block
```

And I’m guessing you have installed the original Helper Libraries and not my update version that supports OH3. You can find it here:

2 Likes

@CrazyIvan359 Thank you very much, following your instructions I was able to run my first Python script!

Actually, after my first Hello World example working fine, I’m experiencing some problems.

First of all, I’m writing my scripts in ‘Scripts’ page, is this the correct way to proceed? When I write a script there, I can see it there but it is also in some way replicated in ‘Rules’ page, where it says that the rule cannot be modified because it is has been provisioned from a file.

The problem is that I’m starting having a list of ‘zombie’ rules appearing in Rules page and I cannot remove them because I cannot find in which file they have been put (I wrote them in Scripts page). Each time I modify the original script it seems that it creates a new rule and these rules are never deleted.

What am I doing wrong? Thank you again for your help…

You should open a new thread if you have a question unrelated to the content of this thread.

Though to answer your question, you want to using rules not scripts.

Just to elaborate a little bit on this. If by “Scripts” page @Frank_Pepperyellow means in MainUI, those have nothing to do with this series of posts. In fact this series of posts cannot be implemented in MainUI. You must use text based rules to use these as written (even after the updates for OH 3 already mentioned).

In UI created rules much of the rule is defined outside the code. There is no @rule and there is no @when. In fact there isn’t even a def functionname(event):. All of that is handled for you. The only code you enter is in a Script Action or a Script Condition (which is a concept that only exits in UI rules).
In the UI there are three types of rules:

  1. Rules: regular old run-of-the-mill rules
  2. Schedule: a regular rule that has a time based trigger or condition (“But only if…”) and tagged with “Schedule”
  3. Script: a regular old rule that only consists of a Script Action and tagged with “Script”. That means no triggers and no conditions.

You cannot copy the above code into the UI and have it work. Anything that is outside the body of the function that makes up the body of the rule is invalid in a UI rule.

@rlkoshak thank you, your post has been very helpful in clarifying all these aspects of rules and script (in relation to Main UI) that I was not aware of before.

I’m trying to write a simple rule for sending emails using a python script, but with no success so far. This works fine:

from core.actions import NotificationAction

but if I try to import also Mail modifying the previous this with this:

from core.actions import NotificationAction, Mail

I get the following error:

2021-05-24 13:39:43.830 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'XYZ' failed: ImportError: cannot import name Mail in <script> at line number 2

Of course, I installed and configured Mail add-on and followed all the steps described by @CrazyIvan359 in his post of 7 days ago. Can you help me in understanding what I’m doing wrong? I’m using OH 3.1.0M4… Thanks!

Importing an Action like that is for OH 1.x style add-ons and are no longer valid for OH 2/3 add-ons. You need to do it just like the examples shown in the binding docs. The only difference is in the Python code you need to reference the actions object.

mailActions = actions.getActions("mail","mail:smtp:samplesmtp")
success = mailActions.sendMail("mail@example.com", "Test subject", "This is the mail content.")
success = mailActions.sendMail("mail1@example.com, mail2@example.com", "Test subject", "This is the mail content sent to multiple recipients.")

Still having problems… Here is the complete code of my (very simple) rule, which I wrote in the Rules page of the MainUI and is triggered by an Item that I switch on and off:

from core import actions
from core.actions import NotificationAction

msg = 'Hello!'

NotificationAction.sendBroadcastNotification(msg)
mailActions = actions.getActions("mail", "mail:smtp:EmailSMTPServer")
success = mailActions.sendMail("some_email@example.com", "openHAB Info", msg)

The notification is correctly sent and received by my mobile app, but the email is not sent and I see this in the log:

2021-05-24 19:17:43.801 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'XYZ' failed: AttributeError: 'module' object has no attribute 'getActions' in <script> at line number 7

So, it seems I’m still missing something… :frowning:

My mistake. It’s actions.get("mail", ...