Page 1 of 2
How to update a virtual 'Instant+counter' sensor with Lua
Posted: Tuesday 02 February 2016 19:41
by Westcott
I'm getting the data from my SAJ solar inverter directly into Lua, and updating a virtual 'Instant+counter' sensor.
In particular, it's instantaneous 'now' in watts, and total for 'today' in Kw
commandArray[1] = {['UpdateDevice'] = "195|0|"..now..";".. today*1000}
The device appears as -

- Clipboard01.png (13.91 KiB) Viewed 10163 times
Is there a better way to update the device with Lua?
To get the data I parse the file returned by -
local cmd = 'curl
http://172.xx.xxx.xx/real_time_data.xml'
local data = assert(io.popen(cmd))
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Wednesday 09 March 2016 17:39
by henr
Can you please give me the lua script that you use or tell me how to make this work?
I also have a SAJ Inverter but i'm an absolute beginner with Domoticz.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Wednesday 09 March 2016 18:56
by Westcott
Display is now correct. It was as simple as using 'total' rather than 'today'.
Henr, at last, a fellow SAJer! - here's my Lua code.
If you don't use PVoutput, delete that bit.
You also need to create 2 virtual devices, an 'Electric (instant+counter), and a 'temperature'
However, if you can hang on a bit, I'm going to rewrite the XML parser.
Code: Select all
commandArray = {}
lineNo = 0
now = 0
temp = 0
today = 0
total = 0
v1 = 0
v2 = 0
i1 = 0
i2 = 0
ip = 'yourInverterIP'
i = 1
function UpdateDevice(device, data)
idx = otherdevices_idx[device]
if (idx == nil) then
print('** Unknown device '..device)
else
commandArray[i] = {['UpdateDevice'] = idx..'|0|'..data}
i = i+1
end
end
--Get the XML data from the inverter
local url = 'curl http://'..ip..'/real_time_data.xml'
local data = assert(io.popen(url))
for line in data:lines() do
if (lineNo == 0 and string.find(line,'Normal') ~= nil) then
lineNo = 1
elseif (lineNo > 0) then
if (lineNo == 4) then now = string.match(line, "%d+")
elseif (lineNo == 5) then temp = string.match(line, "%d+%.%d+")
elseif (lineNo == 6) then today = string.match(line, "%d+%.%d+")
elseif (lineNo == 8) then total = string.match(line, "%d+%.%d+")
end
lineNo = lineNo + 1
end
end
data:close()
if (lineNo >= 14) then
-- Update the Domoticz GUI
ep = v1*i1
wp = v2*i2
UpdateDevice('Solar', now..";".. total*1000)
UpdateDevice('Itemp', temp)
-- Upload the data to PVoutput every 10 mins
date = os.date("*t")
if (date.min % 10 == 0) then
baseURL="http://pvoutput.org/service/r2/addstatus.jsp?"
API="yourAPIkey"
PVO_URL= baseURL .. "sid=36263&key=" .. API .. "&d=" .. os.date("%Y%m%d") .. "&t=" .. os.date("%H:%M")
PVO_URL = PVO_URL .. "&v1=" .. (today*1000) .. "&v2=" .. now
commandArray['OpenURL'] = PVO_URL
end
end
return commandArray
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Thursday 10 March 2016 20:50
by henr
Thank you very much.
I will try it this weekend
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Saturday 12 March 2016 11:43
by henr
It's working in Watts but Kwh today and total is not counting.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Saturday 12 March 2016 12:04
by Westcott
Hi Henr,
Can you make a screenshot of your sensor?
Also can you put your
http://172.xx.xxx.xx/real_time_data.xml directly into a web browser and get a screenshot?
Thanks.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Saturday 12 March 2016 12:23
by henr
Normal 226.4 5.24 50.02 1270 29.7 5.3 4.1 9405.5 9377.28 12680.2 221.3 3.35 179.2 V 3.02 A 357.7
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Saturday 12 March 2016 12:49
by Westcott
Do you have a Sununo-TL4KA twin-tracker, and 2 sets of panels?
Your posted output is just like mine, but you have generated twice as much in total.
I think that an 'Instant+counter' sensor is not correct on the first day of use, since the 'previous' day's total will be zero.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Saturday 12 March 2016 12:55
by henr
Hi Westcott
Thanks for your reply
I have a Sununo TL3KA and 14 solar panels 240Wp
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Friday 13 May 2016 15:49
by nautronix
Hi,
Here another user of Domoticz with an SAJ Solar inverter.
Thanks for the script, I created an dummy hardware named SolarInverter, with two dummy devices: Solar and Itemp
Copyed script (& changed IP in the script) into lua folder, seems to be running, but the log is saying unknown device:
2016-05-13 15:48:43.684 LUA: ** Unknown device Solar
2016-05-13 15:48:43.684 LUA: ** Unknown device Itemp
Am I doing something wrong? Not sure if I created device the right way.
Thanks in advance.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Friday 13 May 2016 16:05
by Westcott
Hi Nautronix,
Sometimes a restart of Domoticz is needed for the event system to see new devices.
If that doesn't fix it, can you post your code and a screenshot of your devices?
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Tuesday 17 May 2016 20:47
by nautronix
Sorry for late response, but indeed, a reboot of Domoticz I didn't try.. Now it's working

- Domoticz-Solar-Inverter.png (48.66 KiB) Viewed 9781 times
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Thursday 09 March 2017 10:14
by annegerben
Westcott wrote:Display is now correct. It was as simple as using 'total' rather than 'today'.
Henr, at last, a fellow SAJer! - here's my Lua code.
If you don't use PVoutput, delete that bit.
You also need to create 2 virtual devices, an 'Electric (instant+counter), and a 'temperature'
However, if you can hang on a bit, I'm going to rewrite the XML parser.
- Spoiler: show
Code: Select all
commandArray = {}
lineNo = 0
now = 0
temp = 0
today = 0
total = 0
v1 = 0
v2 = 0
i1 = 0
i2 = 0
ip = 'yourInverterIP'
i = 1
function UpdateDevice(device, data)
idx = otherdevices_idx[device]
if (idx == nil) then
print('** Unknown device '..device)
else
commandArray[i] = {['UpdateDevice'] = idx..'|0|'..data}
i = i+1
end
end
--Get the XML data from the inverter
local url = 'curl http://'..ip..'/real_time_data.xml'
local data = assert(io.popen(url))
for line in data:lines() do
if (lineNo == 0 and string.find(line,'Normal') ~= nil) then
lineNo = 1
elseif (lineNo > 0) then
if (lineNo == 4) then now = string.match(line, "%d+")
elseif (lineNo == 5) then temp = string.match(line, "%d+%.%d+")
elseif (lineNo == 6) then today = string.match(line, "%d+%.%d+")
elseif (lineNo == 8) then total = string.match(line, "%d+%.%d+")
end
lineNo = lineNo + 1
end
end
data:close()
if (lineNo >= 14) then
-- Update the Domoticz GUI
ep = v1*i1
wp = v2*i2
UpdateDevice('Solar', now..";".. total*1000)
UpdateDevice('Itemp', temp)
-- Upload the data to PVoutput every 10 mins
date = os.date("*t")
if (date.min % 10 == 0) then
baseURL="http://pvoutput.org/service/r2/addstatus.jsp?"
API="yourAPIkey"
PVO_URL= baseURL .. "sid=36263&key=" .. API .. "&d=" .. os.date("%Y%m%d") .. "&t=" .. os.date("%H:%M")
PVO_URL = PVO_URL .. "&v1=" .. (today*1000) .. "&v2=" .. now
commandArray['OpenURL'] = PVO_URL
end
end
return commandArray
Thanks for your code!
I've been using it quite a while, but recently I've added a ping check so the script doesn't have to run completely when the inverter is offline.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Tuesday 21 March 2017 22:13
by 7h1nk
Hi there
I hope you don't mind me hijacking your thread with a quick question, I've been speaking to a friend about Domoticz and HA and he's interested in collating data on both what his panels generate, and how much power he is using but without the use of a Smart Meter.
Looking at your sensors, are you collating not only what your panels are generating, but also how much power you've used and the excess which is put into the grid? If so, what hardware are you using and are you using a Smart Meter?
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Wednesday 22 March 2017 9:19
by annegerben
7h1nk wrote:Hi there
I hope you don't mind me hijacking your thread with a quick question, I've been speaking to a friend about Domoticz and HA and he's interested in collating data on both what his panels generate, and how much power he is using but without the use of a Smart Meter.
Looking at your sensors, are you collating not only what your panels are generating, but also how much power you've used and the excess which is put into the grid? If so, what hardware are you using and are you using a Smart Meter?
the "energie" widget is not coming from this script, only temp and solar.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Sunday 30 July 2017 11:04
by gsmink
Hi Annegerben,
Can you share the code with the ping option
annegerben wrote:
Thanks for your code!
I've been using it quite a while, but recently I've added a ping check so the script doesn't have to run completely when the inverter is offline.
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Wednesday 20 September 2017 11:29
by edwinz
Hello, I do'nt even get the rea_time_data.xml out of my saj-solar-inverter wifi web server. Can anybody help me to "get" the input for the LUA script from the converter?
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Sunday 08 October 2017 10:48
by darkogorgievski
Apparently the above script is for single phase SAJ inverter, I had to play a bit wit the array so here is the code that can be used for 3 phase SAJ inverter:
Code: Select all
-- data from the SAJ inverter
commandArray = {}
lineNo = 0
now = 0
temp = 0
today = 0
total = 0
ip = '192.168.1.221'
i = 1
function UpdateDevice(device, data)
idx = otherdevices_idx[device]
if (idx == nil) then
print('** Unknown device '..device)
else
commandArray[i] = {['UpdateDevice'] = idx..'|0|'..data}
i = i+1
end
end
--Get the XML data from the inverter
local url = 'curl http://'..ip..'/real_time_data.xml'
local data = assert(io.popen(url))
for line in data:lines() do
if (lineNo == 0 and string.find(line,'Normal') ~= nil) then
lineNo = 1
elseif (lineNo > 0) then
if (lineNo == 13) then now = string.match(line, "%d+")
elseif (lineNo ==14) then temp = string.match(line, "%d+%.%d+")
elseif (lineNo == 15) then today = string.match(line, "%d+%.%d+")
elseif (lineNo == 17)then total = string.match(line, "%d+%.%d+")
end
lineNo = lineNo + 1
end
end
data:close()
if (lineNo >= 17) then
-- Update the Domoticz GUI
UpdateDevice('Energy production', now..";".. total*1000)
UpdateDevice('Inverter Temperature', temp)
end
return commandArray
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Monday 20 November 2017 13:00
by nood
edwinz wrote: ↑Wednesday 20 September 2017 11:29
Hello, I do'nt even get the rea_time_data.xml out of my saj-solar-inverter wifi web server. Can anybody help me to "get" the input for the LUA script from the converter?
I have the same problem. I guess we have another type of web server. This is the page I get when I browse to my local IP:
http://1xx.xxx.x.136/
Is this something we can use in a script?
Re: How to update a virtual 'Instant+counter' sensor with Lua
Posted: Sunday 01 April 2018 13:20
by Hieron
nood wrote: ↑Monday 20 November 2017 13:00
I have the same problem. I guess we have another type of web server. This is the page I get when I browse to my local IP:
http://1xx.xxx.x.136/
...
Is this something we can use in a script?
I've managed to get Westcott's script working for the type of webserver we have.
You can check the status of your inverter via http://<LOGIN_INVERTER>:<PASSWORD_INVERTER>@<IP_INVERTER>/status/status.php
if you visit this address in your browser it will output something like this:
Code: Select all
1,100928,27965,9,29,2305,65535,0,65535,65535,65535,60,5002,2305,39,65535,65535,65535,65535,3598,233,7922,2
Just visit the web interface at http://<IP_INVERTER>/ to figure out which value is which.
Code: Select all
commandArray = {}
lineNo = 0
xlineNo = 0
now = 0
temp = 0
today = 0
total = 0
ip = '192.168.xxx.xxx' --ip of your SAJ wifi module
usern = 'admin' --username of your wifi module
passw = 'admin' --password of yoru wifi module
i = 1
function UpdateDevice(device, data)
idx = otherdevices_idx[device]
if (idx == nil) then
print('** Unknown device '..device)
else
commandArray[i] = {['UpdateDevice'] = idx..'|0|'..data}
i = i+1
end
end
function split(myStr, delimiter)
result = {};
for match in (myStr..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
--Get the PHP data from the inverter
local url = 'curl http://'..usern..':'..passw..'@'..ip..'/status/status.php'
local data = assert(io.popen(url))
local dline = data:read('*all')
-- unmask the next 3 lines to see the collected data in your log for debugging purpose
--print "Data collected: ~~~~~~~~~~~~~~~~"
--print(dline)
--print "~~~~~~~~~~~~~~END"
s = split(dline, ",")
for lineNo, line in pairs(s) do
--print(lineNo..' is '..line) -- unmask for debugging purposes
if (lineNo == 1 and string.find(line,'Normal') ~= nil) then
xlineNo = 1
elseif (lineNo > 1) then
if (lineNo == 2) then total = line*10
elseif (lineNo == 4) then today = line*10
elseif (lineNo == 12) then now = line
elseif (lineNo == 21) then temp = line/10
end
xlineNo = xlineNo + 1
end
end
data:close()
--print ("*****************value for 'total' is "..total) -- unmask for debugging purposes
--print ("*****************value for 'today' is "..today) -- unmask for debugging purposes
--print ("*****************value for 'now' is "..now) -- unmask for debugging purposes
--print ("*****************value for 'temp' is "..temp) -- unmask for debugging purposes
if (xlineNo >= 21) then
-- Update the Domoticz GUI
UpdateDevice('Solar Output', now..";"..today)
UpdateDevice('Inverter temp', temp)
end
return commandArray
In my case I've added 2 dummy sensors:
Code: Select all
- 'Solar Output' Sensor type 'Electric (Instant+Counter)
- 'Inverter temp' Sensor type 'Temperature'