[Solved] OH3.1.0 python script - string to number conversion

thank you

Oh, I forgot - two strings for that
postUpdate("invttot", data1)

Nope, still same warning. Is there any other way to convert string to number?

In a rule I’ll use below

 mode = int(str(event.itemState))

thanks, can you share full example? I am not sure how can I apply this to my rule.

Only thing I can think of, you’ve got some invisible control characters in your strings.
Try
postUpdate("invttot", "3.142")
to prove stuff works.
Try
logInfo("test", "Chars " + data1.length)
for character count.

Sure, it’s called ‘parsing’.

To clarify, are you using RulesDSL or Jython/Python?

Below works without errors

postUpdate("invttot", "3.142")

Length of data1 is

2021-12-10 05:17:01.126 [INFO ] [org.openhab.core.model.script.test  ] - Chars 8

String is separated by line breaks

logInfo("test", invtstring.state.toString())

returns

2021-12-10 09:15:30.704 [INFO ] [org.openhab.core.model.script.test  ] - 12509.0
2.10
2534

how do I check?

You must be using the Rules DSL - if you configured python you would know.

Ok, in that case I cannot test your suggestion?

And that is this string with 7 visible characters, yes?

Guess you have output separate NL/CR characters from your script.

    logInfo("results", data1)
	logInfo("test", "Chars " + data1.length)
	logInfo("results", data2)
	logInfo("test", "Chars " + data2.length)
	logInfo("results", data3)
	logInfo("test", "Chars " + data3.length)

returns

2021-12-10 05:35:01.616 [INFO ] [rg.openhab.core.model.script.results] - 12509.8
2021-12-10 05:35:01.618 [INFO ] [org.openhab.core.model.script.test  ] - Chars 8
2021-12-10 05:35:01.619 [INFO ] [rg.openhab.core.model.script.results] - 2.98
2021-12-10 05:35:01.634 [INFO ] [org.openhab.core.model.script.test  ] - Chars 5
2021-12-10 05:35:01.636 [INFO ] [rg.openhab.core.model.script.results] - 2957
2021-12-10 05:35:01.637 [INFO ] [org.openhab.core.model.script.test  ] - Chars 5

No, @rossko has the right stuff to get you going :slight_smile:

I tried by using “parsing” and it seems to be working so far. Below is the code

rule "solar inverter"
when
    //Time cron "0 0/5 * 1/1 * ? *"  
then
    if(solarman.state == ON) {
	var String invdata = executeCommandLine(Duration.ofSeconds(10),"/usr/bin/python", "/var/lib/openhab/INVT-inverter/getPVData.py")
	invtstring.postUpdate(invdata)
	val data1 = invtstring.state.toString.split("\n").get(0)
	invttot.postUpdate(Float::parseFloat(data1))
	val data2 = invtstring.state.toString.split("\n").get(1)
    invtday.postUpdate(Float::parseFloat(data2))
	val data3 = invtstring.state.toString.split("\n").get(2)
    invtcurrent.postUpdate(Float::parseFloat(data3))
	}
end

How can I convert invttot.postUpdate sentences to below format while still using parsing? Or is it not necessary?

postUpdate("invttot", data1)

Hi @niccodemi, could you please tell me what script/method you use in your python code to retrieve the data from the INVT inverter ? Thanks

Hi, below is modified python script which I am using. It’s based on the one I found on following link

#!/usr/bin/python

import urllib, urllib2, hashlib, re, requests
from xml.etree import ElementTree as ET
from requests.auth import HTTPBasicAuth

#config
username          = 'USERNAME' #your inverter webpage username
password          = 'PASSWORD' #your inverter webpage password
inverterIP        = 'XXX.XXX.XXX.XXX' #inverter ip address


# Process html response
def processResponse(resp, strToken, strNextToken):
        #parse response and get values
        strTokenLen = len(strToken)
        valueIndexToken = resp.find(strToken)
        valueIndexNextToken = resp.find(strNextToken)
        value = re.sub('[ =";]', '', resp[valueIndexToken+strTokenLen:valueIndexNextToken-5])
        #print retreved values
        return value

#fetch site from url
url     = 'http://' + inverterIP + '/status.html'

try:
        res = requests.get(url,auth=HTTPBasicAuth(username, password))
        res.raise_for_status()
except requests.exceptions.HTTPError as err:
        print err
        sys.exit(1)


#gather values
inverter = processResponse(res.content, 'webdata_pv_type', 'webdata_rate_p')
totalToday = processResponse(res.content, 'webdata_today_e', 'webdata_total_e')
totalOveral = processResponse(res.content, 'webdata_total_e', 'webdata_alarm')
now = processResponse(res.content, 'webdata_now_p', 'webdata_today_e')
multiply='1000.0'
etotal1000 = float(totalOveral) * float(multiply)
strTotalOveral=str(etotal1000)

#print to console
print totalOveral
print totalToday
print now

This is the rule which gets the data from python script (via Wifi dongle connected to inverter)

rule "solar inverter"
when
    //Time cron "0 0/5 * 1/1 * ? *"      //normal 
	Time cron "0/30 0/1 * 1/1 * ? *"   //(every 30 seconds - for testing)
	//Time cron "0 44 13 ? * *"          //https://github.com/jankeesder/getPVData/blob/master/getPVData.py
then
    if(solarman.state == ON) {
	var String invdata = executeCommandLine(Duration.ofSeconds(10),"/usr/bin/python", "/var/lib/openhab/INVT-inverter/getPVData.py")
	invtstring.postUpdate(invdata)
//	logInfo("results", invdata)
	val data1 = invtstring.state.toString.split("\n").get(0)
//	invttot.postUpdate(Float::parseFloat(String::format("%s",data1).replace(',','.')))
	invttot.postUpdate(Float::parseFloat(data1))
//	invttot.postUpdate(data1)    //worked with OH 3.0
//  postUpdate("invttot", "3.142")
	val data2 = invtstring.state.toString.split("\n").get(1)
//	invtday.postUpdate(data2)
    invtday.postUpdate(Float::parseFloat(data2))
//	invtday.postUpdate(Float::parseFloat(String::format("%s",data2).replace(',','.')))
	val data3 = invtstring.state.toString.split("\n").get(2)
//	invtcurrent.postUpdate(data3)
//  postUpdate("invtcurrent", data3)
    invtcurrent.postUpdate(Float::parseFloat(data3))
//	invtcurrent.postUpdate(Float::parseFloat(String::format("%s",data3).replace(',','.')))
//	logInfo("results", data1)  // had //
//	logInfo("test", invtstring.state.toString())
//  logInfo("results", data1)
//	logInfo("test", "Chars " + data1.length)
//	logInfo("results", data2)
//	logInfo("test", "Chars " + data2.length)
//	logInfo("results", data3)
//	logInfo("test", "Chars " + data3.length)
	}
end

items

Switch solarman “solarman” { channel=“network:pingdevice:solarman:online”}
String invtstring “inverter string data”
Number invttot “inverter total [%.1f]” (gCharts)
Number invtday “inverter daily [%.1f]”
Number invtcurrent “inverter current power [%.1f]”

And thing

network:pingdevice:solarman [ hostname=“xxx.xxx.xxx.xxx”, retry=1, timeout=4000, refreshInterval=180000 ]

Great! Thanks. So if I understand I’ll have this “status.html” on my future INVT inverter where I can get the info from.

I don’t know about status.html and it’s future implementation.