My first steps with OpenHab

I decided to try making a binding for the Awair air quality sensor. I downloaded the addons package and found the Foobot binding, which is really similar to the Awair in every respect. I modified it for the Awair and now I need to test it. I’ve spent hours fiddling around with Eclipse and setting up the dependencies, but to no avail so far. I tried following a couple of how-tos on the OpenHab site, but also without success. I’ll carry on next week.

I eventually worked out how to set up the Eclipse environment and eliminated all the reported errors. After more than a month I’ve come back to it with the objective of generating a .jar for testing. After a couple of attempts I managed to get the jar generated by executing this command:

mvn clean install -DskipChecks

on the addon directory (org.openhab.binding.awair). Before doing that you need to clean up the code formatting with:

mvn spotless:apply

Now I have some errors to deal with from the automatic tests.

Fixed the test errors. Now I’m ready to test the addon on my system.

1 Like

Ahh, not quite. I got the 3.00 addon fixed, but not the 2.5x addon, and it’s still giving me problems with dependencies. I’ve just noticed that it’s asking for JRE 1.8, which I don’t have.

I got the 2.5.x version built. First, you don’t need the core from github (for which only the 3.0.0 branch is needed). But that wasn’t my problem. As explained here:

https://community.openhab.org/t/eclipse-setup-for-developing-2-5-x-addon

the imports change in 3.0.0. I had the imports right for 3.0.0, not for 2.5.x. I changed:

org.openhab.core

to

org.eclipse.smarthome.core

and also had to change the unit test imports and add a few more imports that seem to be needed in 2.5.x (I copied what I found in the 2.5.x version of the foobot binding).

Also, at the end of the Maven build I got a ton of errors starting with this:

 Feature resolution failed for [openhab-binding-awair/2.5.11.SNAPSHOT]
[ERROR] Message: Unable to resolve root: missing requirement [root] osgi.identity; 

Hunting around on the forum, I found this post:

And changed the following in feature.xml in my binding:

<bundle start-level="80">

to

<bundle dependency="true">

I have absolutely no idea what it does, but it got rid of the errors.

I can now test the binding on my OH system.

1 Like

I tested the Awair binding and got to the point where it appears in Bindings in Paper UI… and that’s it. Oh well, it’s a start. No entries appear in the main logs, although I tried to set up logging for the binding as described here on the forums. To be investigated.

I decided to press ahead with creating the building blocks of my rules. I said I was going to go down the Jython route, but the flesh is weak, so I’m going to use Javascript.

I read here that you couldn’t put non-rule utility function .js files in the rules folder, but I found the opposite to be the case. If I put them in another parallel folder, they are found by the rules engine, but attempts to call the functions seem to fail. If I put them in the “personal” folder, they work. I include them in the same way as the rules.js file:

load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/jsr223/javascript/personal/WeekdaysAndHolidays.js');

One thing I’ve noticed is that changes are only applied on restart.

Lots of progress today. First, I realised I needed to add the Awair bridge manually (duh). As soon as I did that, I was able to (try) to add a device and saw entries in the log. The device didn’t add because of a stupid typo in the binding. I’ll try the corrected version now.

I also saw a post that cleared up the confusion about the WeatherUnderground Personal Weather Station binding. If you have a PWS, the WeatherUnderground binding does not work, you need the Weather Forecast Company one.

A bit more progress. The Awair binding shows the right things and items, and it connects to the account, but discovery doesn’t work, and something goes wrong with reading the values when a device is added manually.

Awair binding now fully working. I need to get the 3.0 version compiling and work out how to get it included in future builds.

I spoke a bit too soon. I can’t get the item units to appear in PaperUI.

I’ve migrated quite a few rules from the Zipabox.

Trying to work out how to access the last position that Somfy RTS blinds and awnings were set to.

Added an items file to create groups and items for last update time stamps for various sensors and stuff, as described here:

The groups and items were no problem (I hadn’t noticed that items have a “parent groups” configuration". The tricky bit was working out how to implement the rule in Javascript. After a lot of fiddling I came up with a helper function to extract the name of the item updated from the “input” parameter:

// Adapted from https://gitlab.com/RNTs_3/openhab-jsr223-javascript-helper/tree/master
function GetTriggerItemForEvent(input) 
{
  var ev = input.get("event")+"";
        
  // Splits into: 'gRecordLastUpdate,changed,from,7.96612745098039237,to,7.95362745098039237,through,BalconyAeotec_SensorTemperature' 
  var evArr = ev.split("'").join("").split("Item ").join("").split(" ");

  return evArr[7];
}

It seems that evArr[0] contains the group name, not the item name, when you’re capturing changes to all members of a group.

The rule looks like this, in case it helps somebody. I stuck three different triggers in there because I wasn’t sure which I needed. The last bit of the puzzle was working out that the date sent to sendCommand needed to be in ISO format (.toISOString).

JSRule
(
  {
    name: "Rule_LastUpdate",
    description: "Store last update stamps for all items that require them",
    triggers: 
    [ 
      UpdatedEventTrigger("gRecordLastUpdate"), // Any Member of gRecordLastUpdate received update, even if the value didn't change
      ChangedEventTrigger("gRecordLastUpdate"),
      ItemStateChangeTrigger("gRecordLastUpdate")
    ],
    execute: function( module, input)
    {
      // LastUpdate item has same name as item update, plus _LastUpdate
      var itemLastUpdate; // Item containing last update date

      // Get current date
      var dateNow = new Date();

      var sTriggerItemName = GetTriggerItemForEvent(input);

      // LastUpdate item has same name as item update, plus _LastUpdate
      itemLastUpdate = getItem(sTriggerItemName + "_LastUpdate");      

      sendCommand(itemLastUpdate, dateNow.toISOString());    
    }
  }
);

After learning that I could access all items via the cloud through the REST API, I set up a myopenhab.org account, installed the REST API docs (in PaperUI: Add-ons -> User interfaces -> REST documentation) and looked up the methods for reading and setting an item state (look under https://home.myopenhab.org/doc/index.html).

I stumbled a bit when I decided to test the calls in the Advanced REST client tool. I’d read that the URL should take the form:

https://<myopenhab email>:<myopenhab password>@myopenhab.org:443/rest/items/<item name>/state

with the @ symbol of the email encoded as %40. I did this, but always got “unauthorized” back. After beating my head against the wall for an hour, I realised that there is a specific section for inputting the basic authorisation user name and password :man_facepalming:. In the app I use on my phone to transmit certain information back to the controller (Llama Automate, sort of like Tasker), the HTTP Request blocks work in exactly the same way. So I’m now updating my first item over the cloud.

Next stop: persistence.

1 Like

I’ve built a large part of my rules but there’s still quite a long way to go. I’m having trouble with exposed items at the moment. Despite apparently exposing them in PaperUI, the values seem hardly ever to arrive, or only very erratically. The UI for selecting items to expose is horrible, so I’m going to look at using the config file instead. At least then it will be clear what’s being exposed.

you dont need to have rule for it, it can be easily done by profile, for example I’m using this approach

Number:Temperature      Water_Temperature               "Water [%.1f°]"                 <temperature>   (gStore10, gGarden, gWeather, Graph_Water, Graph_Temperatures, Graph_InOutWater, gMinMaxDaily, gMinMaxAlltime, gMinMaxLastYear, Graph_Weather) ["Measurement","Temperature"] { channel = "mqtt:topic:garden_control:water" }
DateTime                Water_Temperature_LastUpdate    "Last change [%1$tR]"           <time>          { channel="mqtt:topic:garden_control:water"[profile="timestamp-update"] }

How does that work? I’m not familiar with profiles. How are the two items linked? (Also: is this an OH3 feature?)

Does this work when a value is updated but not changed?

whenever main item receives and update, this item is updated on timestamp as well.
They are linked by the channel, in this example via MQTT

mainitem  -> { channel="mqtt:topic:garden_control:water" }
timestamp -> { channel="mqtt:topic:garden_control:water"[profile="timestamp-update"] }

OK got it, they’re linked by the channel. Any update to the channel causes the time stamp to update.

What about items without things (and therefore without channels)? Can you just make up a channel to associate with the items?

I have items that receive data from external sources via the cloud and associated time stamps with them via a rule. There’s no thing, and currently no channel either.