Show two separate strings from python script in sitemap


(Ruben s) #1

Hi there,

I made a pythonscript that establishes a serial connection with a device and receives every minute a string from that device. There are only two important substrings that I need: pH and redoxvalue.

This is my python script:

Blockquotecat /home/openhab/scripts/readserial.py
#!/bin/env python
import time
import serial
import re

ser = serial.Serial(
port=’/dev/ttyAMA0’,
baudrate = 2400,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout= None)

while True:
line = ser.readline()

print(line)

    if 'mV' in line:
     line_split = line.replace(' ','').replace('pH', ',').replace('mV', ',')                                                                                                                                                             .split(',')
     var_ph = float(line_split[0])
     var_redox = float(line_split[1])
     print 'PH:', var_ph
     print 'Redoxpotentiaal:',var_redox,'mV'

Blockquote

Is there a possibility - by using the excec command for example - to display and UPTDATE! the values in the sitemap?


(Kees Van Gelder) #2

not entirely sure what is calling the script, but other than including MQTT, you could just do a REST API call from yr script to update 2 items, provided they are on the same network. Only takes 2 lines

requests.put('http://192.168.xxx.yyy:8080/rest/items/<YOUR PH_ITEM>/state',PHvalue)
requests.put('http://192.168.xxx.yyy:8080/rest/items/<YOUR REDOX_ITEM>/state',Redoxvalue)

need to convert your floats to string though which I think is done with:
PHvalue=str(var_ph)
But maybe I am far off and don’t fully grasp what you want


(Josar) #3

Yes you could use the exec binding. But you could also use the serial binding. Which would be the better solution, IMHO.

https://docs.openhab.org/addons/bindings/serial1/readme.html


(Vincent Regaud) #4

Or your could get your python script to output a json string:
for example:
"{ "PH": 7.1, "Redoxpotentiaal": 0.414}"

Script:

    if 'mV' in line:
     line_split = line.replace(' ','').replace('pH', ',').replace('mV', ',').split(',')
     var_ph = float(line_split[0])
     var_redox = float(line_split[1])
     var jsonString = '{ "PH:"' + var_ph + ', "redoxPotential:"' + var_redox + '}'
     print jsonString

Then the JSONPATH transform will be able to get the two values easily:

Items:

Number WaterPH "Water PH: [%.1f PH]"
Number WaterRedox "Redox Potential: [%.3f mV]"

Rule:

rule "Get water data"
when
    Time cron "0 0/5 * * * ? *" //Every 5 minutes change that as you wish
then
    val waterJson = executeCommandLine("python /home/openhab/scripts/readserial.py", 5000) //5 seconds time out for script to execute
    WaterPH.postUpdate(transform("JSONPATH", "$.PH", waterJson))
    WaterRedox.postUpdate(transform("JSONPATH", "$.redoxPotential", waterJson))
end

(Rich Koshak) #5

I agree with Josar, this sort of thing is what the Serial Binding is made for. Failing that, it is probably better to have your script report to OH rather than have OH polling the script by executing it over and over like Kees recommends.

Finally, as Vincent demonstrates, it is very possible to have OH call the script (note there is a missing open quote in the rule trigger Time "cron 0 0/5 * * * ? *"). However, you will have to take the while True part out of the script and have the script exit once one line has been read from the device.

It would also be possible to use the Exec binding for this, but since the script returns two values on one line you will need a Rule like this one anyway so it doesn’t buy you much.

Note: How to use code fences


(Vincent Regaud) #6

Thank you corrected


(Ruben s) #8

I tried the json solution of vzorgclub and I got this error while executing the python script: > Traceback (most recent call last):

File “/home/openhab/scripts/readserial.py”, line 22, in
jsonString = ‘{ “PH:”’ + var_ph + ‘, “redoxPotential:”’ + var_redox + ‘}’
TypeError: cannot concatenate ‘str’ and ‘float’ objects


(Vincent Regaud) #9

You need to convert the floats to strings.
I haven’t coded python in a while.
Try str(var_ph)


(Ruben s) #10

Okay but don’t I need to use String instead of Number in the .items file?


(Ruben s) #11

This is the result of the script when I run it manually (by using str(var_ph)):

{ "PH:"8.2, "redoxPotential:"775.0}


(Vincent Regaud) #12
jsonString = '{ "PH:"' + str(var_ph) + ', "redoxPotential":' + str(var_redox) + '}'

Then you can use the JSONPATH transform to extract your values


(Ruben s) #13

That’s what I already did, but it didn’t work for me.

This is my basicui:

Water PH: - PH


(Vincent Regaud) #14

I am sorry I keep making typos… :sob:

jsonString = '{ "PH":' + str(var_ph) + ', "redoxPotential":' + str(var_redox) + ' }'

This now generates a valid json:
{ "PH":8.2, "redoxPotential":775.0 }


(Ruben s) #15

It still doesn’t work for me. Maybe we can use a String item instead of Number item, but maybe the jsonpath and the rulesfile will look different?


(Vincent Regaud) #16

No, it should work, I think
There is obviously an error somewhere

Change the rule to:
Every 1 minute just for debugging

rule "Get water data"
when
    Time cron "0 0/1 * * * ? *" //Every 5 minutes change that as you wish
then
    val waterJson = executeCommandLine("python /home/openhab/scripts/readserial.py", 5000) //5 seconds time out for script to execute
    logInfo("WATER", waterJson)
    WaterPH.postUpdate(transform("JSONPATH", "$.PH", waterJson))
    WaterRedox.postUpdate(transform("JSONPATH", "$.redoxPotential", waterJson))
end

Can you show me the log file, please?


(Vincent Regaud) #17

@OpenHabian2
Was your problem solved?