Jython - creating own library module (MQTT)

I’m pretty sure I’m just missing something simple here, but I can’t see it.

Gradually migrating my existing DSL to Jython and I’m refactoring to move a function into a library. The function takes in a MQTT topic and a message and publishes them accordingly.

When the function is in with the other rules, it works fine, but extracting it to another file results in an error:

NameError: global name 'actions' is not defined

The complete library file: /lib/python/personal/utils.py

""" Send message to MQTT Broker """
def send_message_to_broker(topic, message):
    """ Take in topic name & message and send to MQTT broker """
    actions.get("mqtt", "mqtt:broker:tower").publishMQTT(str(topic), str(message))

The calling file: /jsr223/python/personal/messaging.py (top part only)

from core.rules import rule
from core.triggers import when
from core.actions import Voice
from java.time import ZonedDateTime
import personal.utils
reload(personal.utils)
from personal.utils import send_message_to_broker

@rule("Handle Item_Notify_Message",
      description="MQTT Messaging for normal notifications",
      tags=["System", "Messages"])
@when("Item Item_Notify_Message received update")
def notify_message(event):
    """ Send normal message to MQTT Broker """
    message = str(items["Item_Notify_Message"])
    #Log it
    notify_message.log.info("***** {}".format(message))
    #Send it
    send_message_to_broker("home/messages/pushover/normal", message)
    send_message_to_broker("home/messages/slack/normal", message)

MQTT v2 is installed and running.

The Jython docs say that I don’t need an import (https://openhab-scripters.github.io/openhab-helper-libraries/Guides/Actions.html?highlight=mqtt), but I’m guessing that is what is missing from the top of the utils.py.

I tried adding:

from core.actions import MQTT

but that just threw:

ImportError: cannot import name MQTT in <script>

Can someone point out the D’oh moment to me please?

[UPDATE]
So it doesn’t throw the error on compile/load, only on execute. If I add the core.actions import to the module, that error gets thrown on compile.

try changing

to

from core.actions import Mqtt

(case-sensitive)

Same error:

 ImportError: cannot import name Mqtt 

And same with

from core.actions import mqtt

Ref. https://openhab-scripters.github.io/openhab-helper-libraries/Guides/Actions.html
Seems no import is required.

And that was what I did at first - no import, literally just the function defined in a file. But that throws the

NameError: global name 'actions' is not defined

error

Scripts run with a number of things injected into the scope. Modules start with nothing, so you need to manually import everything you need. For the MQTT action, you first need to import actions…

from core.jsr223.scope import actions

The core.jsr223 module allows you to access those things in the default script scope. I have an updated version of the docs coming soon, where I provide some more detail, but… https://openhab-scripters.github.io/openhab-helper-libraries/Python/Reference.html#custom-packages-and-modules.

2 Likes

Hi Scott,

Tried that as well early on, same error:

ImportError: cannot import name actions 

I also just imported core.jsr223 without success :grimacing:

Just for clarity, I’m also adding and deleting empty lines to the messaging.py file to force the

reload(personal.utils)

I had a similar problem, and solved it with

from core.jsr223.scope import events, items

Same error:

NameError: global name 'actions' is not defined

but adding:

from core.jsr223.scope import events, items, actions

appears to have worked

So it appears that I actually just need to add:

from core.jsr223.scope import actions

for the library module to now work.

Thanks!

core.jsr223.scope import actions

Did you have this in the script or module?

Module (utils.py)

from core.jsr223.scope import actions

""" Send message to MQTT Broker """
def send_message_to_broker(topic, message):
    """ Take in topic name & message and send to MQTT broker """
    actions.get("mqtt", "mqtt:broker:tower").publishMQTT(str(topic), str(message))

^^ The file above, stored in /lib/python/personal/utils.py now works

[UPDATE]
Not sure why it didn’t work when I tried it earlier - apologies Scott - that was your suggestion :confused:

1 Like

Glad you got it sorted out! Something I noticed though, you could run into some trouble here with special characters. Unless you really need a str, it is best practice to use unicode.

message = unicode(items["Item_Notify_Message"])
notify_message.log.info(u"***** {}".format(message))

You shouldn’t need to convert these again, but you had str in your original…

actions.get("mqtt", "mqtt:broker:tower").publishMQTT(unicode(topic), unicode(message))

Ok, thanks for that, lots of logging going on with this, so I’ll probably change it.

N

If i look into the help libraries docs there is the information that ni import is required with MQTT

https://openhab-scripters.github.io/openhab-helper-libraries/Guides/Actions.html

Correct… for a script. You will need one if trying to use actions in a module.