Monitoring Thing Status

Until OH can move to a more recent version of Java where Graal VM will be available, these are the only three languages that are available. I believe the target is to move to Java 11, but there are some upstream libraries around the Xtext libraries IIRC (upon which all the text config files OH loads like .items, .rules, .sitemaps, etc) that cannot run on Java 11 or later yet.

The hope is once we have Graal VM, we can support pretty much any language you can think of. I wouldn’t mind playing around with Clojure or some other functional language. Until that happens though, probably OH 3, we are stuck with Jython. If you really want to get started with Python 3 (honestly, for the purposes of Rules writing, I see little practical difference between Python2 and Python3 so even if you get started with Jython now, when Python 3 becomes available it should be minimal effort to move your rules over).

And if you really want to jump in using Python 3 from the start, there is GitHub - spacemanspiff2007/HABApp: Easy home automation with MQTT and/or openHAB. Though because this runs as a separate application it is limited to only doing actions that can be done through the REST API.

Thanks, I saw that . I may look at Jython when I have a chance.
Thank you for your patient explanations & advice.

If you use a snapshot (and soon to be included in 2.5M2), all installed JSR223 supported script engines will be included in the Script Type dropdown for scripted Actions and Conditions. I added this right after 2.5M1 was released.

Unfortunately, all current bindings implementing Actions have used the AnnotatedThingActionModuleTypeProvider, which was not originally implemented for allowing the Actions to be used within a UI, so they will not work. Enhancing this class is being discussed. There is no visual que that Actions and Conditions are coming from a binding or core, so usage can be a little tricky ATM. Binding Actions do work in scripts though.

Conditions are available, but I haven’t implemented them in the helper libraries. They are really only useful in the UI, since they are essentially ‘if’ statements. Eventually, they will be expanded to ‘if/then/else’, which will be a milestone for UI rules, since the rules will no longer be linear paths with a single set of possible Actions. Too soon yet to dive into a discussion about this, and will required integration into the new UI (OH3).

The NGRE is also experimental because the APIs are not locked down and changes to them could break rules. I don’t foresee any major changes being needed ATM though, and development of the NGRE has settled down significantly after the business(es) using ESH stopped contributing. I hope to get a major changes implemented before OH3 though.

There are only some experimental (and TMK abandoned) Jython builds using Python3. When/if GraalVM is integrated, which is the logical evolution of OH scripted automation, you’ll be able to use newer version of Python. I see Rich has mentioned this, and I agree that there is very little you will miss using Python2 for scripting.

There are many other languages compatible with javax.script (JSR223). That repo is a fork from the java.net scripting project, which is no longer available from Oracle. Jython, JS and Groovy are just the most popular for use with OH.

Hmmmm. I’m on Build 1639 and all I have in the list is ECMA Script (i.e. JavaScript).

image

I’m upgrading to 1640 as I type this (to get the fix for the REST API Docs) and will post back if that changes. I thought I remember you mentioning that this was fixed in PaperUI but doubted my memory when I tried it recently and it didn’t work. Maybe it’s a recent regression? Clearly something changed because prior to 2.5 M1 it said JavaScript instead of ECMAScript.

But it’s possible as evidenced by the “publish MQTT” Action which was my main point.

Which is why I wasn’t surprised to see them listed. But if we want to ever get to a point where users can export their JSON Rules to Python (for example) there will need to be some sort of concept in the Helper Libraries I suspect.

:+1:

Available doesn’t necessarily mean that they work. There was some significant work a couple years ago to try and get JRuby to work as a suitable JSR223 language. There was some fundamentally technical hurdle that they could not overcome. I’m sure many others on that list can work, but there is at least one that will not. Perhaps jRuby or openHAB has changed since then to the point where it would work.

It’d be fun to write Rules in Scheme though. I have an intuition that the functional paradigm would work quite well for Rules. I just don’t have the time right now to try it out and see if it works.

The list is built from the available ScriptEngines. When you setup Jython or Groovy, you’ll see them in the list.

Binding ThingActions are currently visible in the UI, but they will likely soon be hidden until this is fixed. However, you’ll find that you can’t configure a topic for the MQTT Action, or add an email address, subject, or message body in a Mail Action, etc.

The helper libraries are a filler for interacting directly with OH classes and interfaces until a Scripting API is put in place. There will still be some use for them though (utility functions, experimental functionality not yet implemented in the API, custom ModuleTypes and handlers, etc.). I expect the Scripting API will be around long before someone looks into migrating JSON rules to scripted automation. It would also be easy to migrate a Condition too, since they are just a simple ‘if’ statement.

Adding Conditions is on the list though!

They should all work. However, a language specific ScriptEngineFactory may be needed for special handling of the default script scope. I haven’t tried jRuby, but I believe the issues early on were with the OH1 implementation.

But I do have Jython set up. All I have is a “hello world” script set up but I do have it available. I don’t have the latest helper library, is that required?

Funny – just a couple of days ago I needed to trigger a JSR223/Jython rule based on the online/offline status of an MQTT/Homie device.

I came up with this on my own:

@rule("ServerRoomLightsChanged", description="", tags=["utility"])
@when("Thing \"mqtt:homie300:srvrm-lightsense\" changed")
def ServerRoomLightsHomie(event):

	status=event.getStatusInfo().getStatus().toString()
	
	if status=="ONLINE":
		global hTimer
		if hTimer:
			hTimer.stop()
			hTimer=0
		

	if status=="OFFLINE":
		events.sendCommand(ir.getItem(strItem),OFF)

Am I just lucky to have started in JSR223 to begin with? Would the when thing xxx changed pattern not have worked in Rules DSL? Or is it a matter of ONLINE/OFFLINE status being different for Z-Wave and Homie devices? I’ve only used this with Homie and it works perfectly there.

No, just Jython in the classpath. It’s still working for me on S1634…

I’ll go update and check to see if it might have broken. There have been some recent changes to automation, but nothing that I would have thought that could have broken this.

Thing triggers also work in the rules DSL. Actually, a ThingStatusTrigger was recently added to the NGRE too. I haven’t committed a PR to use it in the helper libraries yet, but it’s coming.

So then, how is that different from the OP question? Is it just the “from ONLINE to OFFLINE” part that doesn’t work, so the logic has to be in the rule itself?

The OP was looking for a generic rule to alert when any Thing went offline… like ‘Member of’ but for Things. In the helper libraries, you can use GenericEventTrigger (not included in the when decorator).

2 Likes

@rlkoshak, the script type dropdown is still populating for me in S1641. If you open an issue in GH, we can troubleshoot it over there.

Oh? Interesting!

Thanks :slight_smile: Fixed.

FYI the new UI will offer a better experience than PaperUI for building rules graphically (“JSON rules”), as well as a script editor that’s actually useable.
The autocompletion support is only partial (it doesn’t detect imported libraries etc.) and is only working for JavaScript - and there are no plans currently to extend it to Python and other languages because of library limitations - but we could relatively easily get at least the syntax highlighting working for other languages. Still, it will probably be enough for some users. Other installable specialized UIs for rules could embed a more sophisticated editor like Monaco to offer better support.

(this is an early mockup, the appearence and functionality are subject to change!)

3 Likes

I’m running build 1640. I’ll go through the install steps again just to make sure I’ve not messed something up. If I didn’t I’ll open the issue. No news is good news (i.e. I messed something up somewhere along the way).

I meant to include a link. Running Actions from JSON Rules was where I stopped with the documentation but I think I have enough to get someone started. The helper libraries do most of the work for you though and you just need to pull the Action from a list of discovered Actions. There is a little bit showing how to do it using Lewie’s JS library which has since been merged with the Helper Libraries and may have changed a bit. Experimental Next-Gen Rules Engine Documentation 5 of : Actions

Scroll down to the bottom the OP.

:smiley:

I am trying to hijack Yannick’s NGRE rule, as part of a fault management project.
It gets all Thing status changes, and I could filter out the ones that I’m interested in in the javascript body.

But I thought to improve efficiency by listening only for selected event topics …

The topics I want are something like smarthome/things/modbus:poller:slave22:holding22
Aha thinks me, I will use

"eventTopic": "smarthome/things/modbus:poller:*",

Everything I’ve read suggests this is possible, but I still get all things status changes. I’m well out of my depth here. Maybe it’s a side effect of importing the rule from json. Help?

More thinks - I am on standard issue OH2.4 … maybe that filter isn’t yet functional there.

Another approach maybe beneficial for your needs: Monitoring Things (Status)

1 Like

I quite like that tag-based approach.

It won’t do for my very particular case, because of the cron based rule needed.
I’m looking at Modbus which has fast (typically per-second) polling and a retry mechanism. In case of an error (device unplugged), retries pile up, and the timeout waits affect other device responses. The benefit I’m looking for comes when acting within seconds to re-arrange modbus polling. So really I need an update-as-it-happens Thing status trigger.
I would not want to run the tag-based checking rule every second over a great many Things.

It looks very useful for less time-critical health monitoring.

Hi,
I have some Things that sometimes goes offline for communication error but I just need to disable and enable again and they just go online again.
I would like to check with DSL rules the things status and if != ONLINE I would disable and enable them again.
I can read the THings status but is there any command to disable and enable a particolar thing?
Regards
Lorenzo

Example using REST API for enable (developer tools section)

    val EchoControlAccountThingStatus = getThingStatusInfo("amazonechocontrol:account:account1")
    if (EchoControlAccountThingStatus.getStatus().toString() != "ONLINE") {
        executeCommandLine(Duration.ofSeconds(10), "/etc/openhab/scripts/enable_amazonechocontrol.sh")

etc

Script

#!/bin/bash
 curl -X PUT "http://<Local openHAB server IP>:8080/rest/things/amazonechocontrol%3Aaccount%3Aaccount1/enable" -H  "accept: */*" -H  "Content-Type: text/plain" -H  "Authorization: Bearer  <API token> " -d "true"
 

API tokens are generated by openHAB admin panel.

Did we have a generic way in oh3? I have a few things they goes offline sometime.
Thanks for your help.

1 Like

You can hook into the ThingStatusInfoChanged Event.
But I think you have to write your code in javascript…

configuration: {}
triggers:
  - id: "1"
    label: When ThingStatusInfoChangedEvent is raised
    configuration:
      eventSource: ""
      eventTopic: openhab/things/*
      eventTypes: ThingStatusInfoChangedEvent
    type: core.GenericEventTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    label: execute a given script
    configuration:
      type: application/javascript
      script: >-
        //get thing name
        var thingId = event.topic.split('/')[2];
        //get Thing state
        var thingState = JSON.parse(event.payload)[0].status;
    type: script.ScriptAction