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
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
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/
Image

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'