Formatting sensor value received from exec-binding

Dear all,

After having read the official tutorials, I’m now tackling my first project: reading the temperature from a DHT-11 sensor that is connected to my Raspberry Pi and displaying the value via the Basic UI. After hours of research, trial and error, it is now working in a rudimentary way, but I want to learn how to make it more pretty.

Based on this thread I’ve stored a python script in /etc/openhab2/scripts:

import sys
import Adafruit_DHT

sensor = Adafruit_DHT.DHT11
pin = 17 ## GPIO

humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)

if humidity is not None and temperature is not None:
     print('{0:0.2f}'.format(temperature))
else:
     print('Failed to get reading. Try again!')
     sys.exit(1)

Then I created a thing, an item and a sitemap entry. The relevant lines are as follows.

exec.things

Thing exec:command:read_temperature [
	command="/usr/bin/python /etc/openhab2/scripts/myDHT11.py",
	transform="REGEX([0-9]+\.[0-9]{1})",
	interval=30,
	autorun=true]

sensors.items

String Current_Temperature <temperature> { channel="exec:command:read_temperature:output" }

default.sitemap

Text item=Current_Temperature label="Temperature [%s °C]"

Now, this gives me a reading, e.g. “19.00 °C” in the web browser. However, I’d like it to read “19.0 °C” (the sensor’s accuracy and resolution are not that high) and I’d also want to be able to display humidity in a later step. So far, I thought of the following ways to achieve this.

  1. Use a regular expression in the thing to transform the script output value to the desired one. I think, this would be the most flexible solution, and also, I could easily add the humidity in the sitemap according to the tutorial linked above. However, the regex in the thing shown above doesn’t work as expected. I tested it in regex101 where the expression works flawlessly. Do you have any idea, why it doesn’t work in OpenHAB?
  2. Perhaps it is possible to display a Number item in the sitemap? In that case, I could use a format string like label="Temperature [%.1f °C]".
  3. Use a rule to convert the string item to a number item as shown in this tutorial. However, this appears to me like some not really necessary hassle for this simple use case.
  4. I could, of course, change the Python script to give me exactly the output, that I want and write a second one to output humidity, but I don’t like this solution as it is not very flexible and might not work for other projects.
  5. I could make use of the REST API as suggested in this tutorial. While this is an interesting approach that I might try later, I still want to be more comfortable with other ways to solve the problem. This allows me to find more creative solutions in other projects later. It might not always be possible to change the source script to use the REST API.
  6. Another approach that I came across is using MQTT to send the sensor readings to OpenHAB. While I want to try this later and MQTT will surely help me in many of my later projects, basically the same thoughts as for the REST API apply. It might not always be possible or the best way to send values over MQTT.

I hope, you guys can answer some of my questions. I’m especially interested in getting the first or second approach to work to enhance my OpenHAB “magic drawer”. :wink:

Thank you in advance! :slight_smile:

Hemanti

Change the python script print line from {0:0.2f} to {0:0.1f}. I think that’s how I did it before.:thinking: I’ve since stopped using the exec binding and have most everything using mqtt. Gotta love those little ESP8266 devices.:grinning:

Have your script report the temperature as only a number and use a number item in openHAB and let openHAB do the formatting.

"Temperature [%0.1f C]"

That folder really isn’t intended to store Python scripts like this. You may run into trouble if you ever run openhab-cli fix-permissions or during an upgrade. More appropriate locations would be ~openhab/scripts or /etc/openhab2/shell.

The scripts folder are intended to hold openHAB Rules DSL Scripts which are a rarely used feature of OH that let’s you put a bit of reusable code in a .script file and call it from Rules. But they have significant limitations which makes them rarely used.

I’m not sure the REGEX is doing anything for you. I suppose it will prevent the “Failed to get reading. Try again!” message from reaching OH and generating an error in the logs.

2 and 3 are the most appropriate solutions. Unfortunately you cannot link the Exec output channel to a Number Item so you need a rule to copy the result to a Number Item. Then you can use the %.1f. You will want to do this anyway as you will almost certainly want to do math with this reading at some point and possible put it into a database where it can be charted.

6 is another approach that will let you expand this more easily in the future to more sensors. If you use MQTT then later you can build little sensors based on an ESP8266 using Tasmota or ESPEasy. And when you do, it will be integrated exactly the same way as this sensor. And you don’t even need to write the script if you don’t want to. See https://github.com/rkoshak/sensorReporter for some ready made code you can use.

Unfortunately you cannot link the output Channel from the Exec binding to a Number Item, only to String Items.

1 Like

I was not aware of that limitation.

Great! Thanks a lot everyone! :slight_smile:

I will then move the python script and try approaches 3, 5, and 6 to gain more experience with OpenHAB. Right now, I think, that in the end, approach 6 will be the one I stick with, but it’s always good to know more. :wink:

Is the rule that I linked for approach 3 a good example?

Can you give me an example as to what REGEX is actually doing? According to this post and the following two replies, I could apparently use it to split a script output value to two items with exec-binding (v1). Now, what does REGEX do in version 2 of the binding?

That link looks reasonable as a Rule approach for 3.

See

For the docs for the transformation service and REGEX transformation in specific.

The REGEX transform, like any other transformation performs some sort of manipulation of the text received from the script (in this case) and passes that transformed data to the Item as it’s state. In the case of REGEX, it extracts a portion of the result.

In that post what is being explained is that you have two Items. Both Items independently execute the script. One Item needs a REGEX to select the first number. The second Item needs a REGEX to select the second number. You can do the same thing with Exec2. You just need to create two Things and use the different REGEX expressions on the two Things.

The REGEX transformation does the same thing in ALL versions of ALL bindings.

The REGEX in the OP will select

  • [0-9]+: one or more numbers
  • \.: decimal point
  • [0-9]{1}: exactly one number

If the script returns anything that doesn’t match that pattern, including stuff like trailing white space, will cause the REGEX transform to return null. Note, if the script decides not to print out a decimal point or adds another decimal place, this REGEX will reject that reading.

If the script returns two sets of numbers, one Thing would use a REGEX along the lines of ([\d]+\.\d) .* and the other would be along the lines of .* ([\d]+\.\d).

1 Like

Thank you for you comprehensive reply!

Ah, two independent script calls. That’s the detail I wasn’t getting. :smiley:

That’s actually what I thought based on my readings and trials with regex101. However, I was confused, why I still got “19.00 °C” instead of “19.0 °C”. So I rebooted and now I just saw “- °C”. So I commented and uncommented again the regex transformation line in my thing. Now “19.00 °C” was back. I rebooted again and found the following error in the logs:

Configuration model ‘exec.things’ has errors, therefore ignoring it: [3,12]: mismatched character ‘.’ expecting set null
[3,27]: no viable alternative at input ‘[’
[3,28]: extraneous input ‘0-9’ expecting ‘]’
[3,33]: extraneous input ‘1’ expecting ‘}’
[3,36]: mismatched character ‘’ expecting ‘"’

That would explain that the regex has no impact. Any ideas to whether my regex could be malformed? Or could it be the nano editor saving the file in some false format? I’ll try with another editor tomorrow.

Thanks again for your support! :slight_smile:

What you see in the sitemap can have little to nothing to do with what the Item’s actual state is. Just as you can apply a transformation to the data coming in, you can format and transform the data as it is displayed in the label on the sitemap (i.e. the stuff between the [] in the label).

You need to look at the logs, events.log in particular, to see what the Item is actually being set to.

- means the Item’s state is NULL or UNDEF. Items are initialized to NULL when OH first starts or a .items file is reloaded.

I don’t know if your REGEX is malformed but there is something malformed about your .things file. I don’t use .things files, and don’t recommend their use frankly, so can’t be of much help there. I do strongly recommend using VSCode with the openHAB extension for editing any OH config files. It will do the syntax checking as you type.