Page 1 of 2

Average outside temperature with Lua

Posted: Friday 16 November 2018 19:12
by Knibor
Hi,

I want to measure the average temperature from my outside temperature sensor, this is a sensor that measure, temperature and humidity.
I'm not familiar with the Lua scripts.
But I found an example on the the internet

My IDX from the temperature/humidity sensor is IDX 37 (Buiten Temp)
The dummy temperature has the IDX 247 (Gemiddelde buiten temperatuur)

I have no output to IDX 247. , it gives me the number "0"

Can someone help me with this?

In the Log I get this information

EventSystem: in Script #1: [string "local function DeviceUpdate(idx, value1)..."]:16: attempt to index global 'otherdevices_247' (a nil value)

Here is the script:

local function DeviceUpdate(idx, value1)
local cmd = string.format("%d|0|%.2f", idx, value1)
--print(cmd)
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

Debug = "YES" -- Debugging aanzetten ("YES") of uitzetten ("NO")

commandArray = {}

local m = os.date('%M')
if (m % 5 == 0) then -- script loopt iedere 5 minuten

-- Variabelen instellen
local temperature_name = 'Gemiddelde Temp buiten'
local temperature_idx = otherdevices_idx[temperature_name]

local uitlees_name = 'Temperature'
local uitlees_idx = otherdevices_idx[uitlees_name]

--Temperaturen van afgelopen 24 uur opvragen
local sQuery = 'curl "http://192.168.1.37:8080/json.htm?type= ... &range=day"'
local handle=assert(io.popen(sQuery))
local raw = handle:read('*all')
handle:close()

--Ontvangen waarden verwerken
json = assert(loadfile '/home/pi/domoticz/scripts/lua/JSON.lua')()
local jsonData = json:decode(raw)

if Debug=='YES' then
print (jsonData.title)
print (jsonData.status)
print (jsonData.result[1].d)
print (jsonData.result[1].te)
end

--Gemiddelde temperatuur van afgelopen 24 uur bepalen
local sum = 0
local ave = 0
local elements = #jsonData.result

for i = 1, elements do
sum = sum + jsonData.result.te
end

ave = sum / elements

if Debug=='YES' then
print('Gemiddeld: '..tostring(ave))
end

--Gemiddelde temperatuur opslaan in virtuele temperatuur sensor
DeviceUpdate(temperature_idx,ave)

end
return commandArray

Re: Average outside temperature with Lua

Posted: Friday 16 November 2018 23:21
by aleph0
I don't know exactly what you want to do, but it looks a bit overkill to calculate an average value. Why wouldn't you use a low band filter for that :
avg_value=((n-1)*avg_value+instant_value)/n will give you the running average value over n measures

Envoyé de mon Hi9Air en utilisant Tapatalk


Re: Average outside temperature with Lua

Posted: Saturday 17 November 2018 17:11
by Knibor
Hi, thanks for the info.

In want to measure the exact average outside temperature in 24 hour.
This because I want to know how much gas I use in my house in 24 hour with the average temperature of that day.
So I can calculate the cost of the gas I used with that given average temperature in that day.

Where do I put the average calculation? In Lua or somewhere else.

Re: Average outside temperature with Lua

Posted: Saturday 17 November 2018 17:36
by jvdz
Shouldn't this line:

Code: Select all

sum = sum + jsonData.result.te
be changed to:

Code: Select all

sum = sum + jsonData.result[i].te
I tested this script and works fine for me.:

Code: Select all

local function DeviceUpdate(idx, value1)
    local cmd = string.format("%d|0|%.2f", idx, value1)
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

Debug = "YES" -- Debugging aanzetten ("YES") of uitzetten ("NO")

commandArray = {}

local m = os.date('%M')
if (m % 5 == 0) then -- script loopt iedere 5 minuten

    -- Variabelen instellen
    local temperature_name	= 'Gemiddelde Temp buiten'
    local temperature_idx	= otherdevices_idx[temperature_name]

    local uitlees_name	= 'Temperature'
    local uitlees_idx	= otherdevices_idx[uitlees_name]

    --Temperaturen van afgelopen 24 uur opvragen
    local sQuery	= 'curl "http://192.168.0.30:8080/json.htm?type=graph&sensor=temp&idx='..tostring(uitlees_idx)..'&range=day"'
    local handle=assert(io.popen(sQuery))
    local raw = handle:read('*all')
    handle:close()

    --Ontvangen waarden verwerken
--~ 	print(raw)
    json = assert(loadfile 'JSON.lua')()
    local jsonData = json:decode(raw)

    if Debug=='YES' then
        print (jsonData.title)
        print (jsonData.status)
        print (jsonData.result[1].d)
        print (jsonData.result[1].te)
    end

    --Gemiddelde temperatuur van afgelopen 24 uur bepalen
    local sum = 0
    local ave = 0
    local elements = #jsonData.result

    for i = 1, elements do
        sum = sum + jsonData.result[i].te
        -- print(i,sum)
    end

    ave = sum / (elements)

    if Debug=='YES' then
        print('sum: '..tostring(sum))
        print('elements: '..tostring(elements))
        print('Gemiddeld: '..tostring(ave))
    end

    --Gemiddelde temperatuur opslaan in virtuele temperatuur sensor
    DeviceUpdate(temperature_idx,ave)

end
return commandArray


Jos

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 18:50
by Knibor
Hi,

I copied your code in Lua (Time) and only changed the Ip adres to 192.168.1.28:8080 (My Domoticz IP address)

Now I get the error "2018-11-18 18:45:00.292 Error: EventSystem: in Script #1: [string "local function DeviceUpdate(idx, value1)..."]:28: cannot open JSON.lua: No such file or directory"

What do I wrong?
This is what I use now.


local function DeviceUpdate(idx, value1)
local cmd = string.format("%d|0|%.2f", idx, value1)
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

Debug = "YES" -- Debugging aanzetten ("YES") of uitzetten ("NO")

commandArray = {}

local m = os.date('%M')
if (m % 5 == 0) then -- script loopt iedere 5 minuten

-- Variabelen instellen
local temperature_name = 'Gemiddelde Temp buiten'
local temperature_idx = otherdevices_idx[temperature_name]

local uitlees_name = 'Temperature'
local uitlees_idx = otherdevices_idx[uitlees_name]

--Temperaturen van afgelopen 24 uur opvragen
local sQuery = 'curl "http://192.168.1.28:8080/json.htm?type= ... &range=day"'
local handle=assert(io.popen(sQuery))
local raw = handle:read('*all')
handle:close()

--Ontvangen waarden verwerken
--~ print(raw)
json = assert(loadfile 'JSON.lua')()
local jsonData = json:decode(raw)

if Debug=='YES' then
print (jsonData.title)
print (jsonData.status)
print (jsonData.result[1].d)
print (jsonData.result[1].te)
end

--Gemiddelde temperatuur van afgelopen 24 uur bepalen
local sum = 0
local ave = 0
local elements = #jsonData.result

for i = 1, elements do
sum = sum + jsonData.result.te
-- print(i,sum)
end

ave = sum / (elements)

if Debug=='YES' then
print('sum: '..tostring(sum))
print('elements: '..tostring(elements))
print('Gemiddeld: '..tostring(ave))
end

--Gemiddelde temperatuur opslaan in virtuele temperatuur sensor
DeviceUpdate(temperature_idx,ave)

end
return commandArray

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 18:54
by jvdz
Change the JSON.lua line to the one you had as I am testing on a different setup. :roll:
Jos

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 19:03
by Knibor
i actually don't understand exactly what you mean?
What exactly should I change in this line.

ok, I think I understand? My Domoticz IP address was changed due a modem update to local address 192.168.1.28
it is not anymore 192.168.1.37

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 19:06
by Joep123
If you use a Pi...

Code: Select all

json = assert(loadfile 'JSON.lua')()
shoud be:

Code: Select all

json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 19:10
by Knibor
Ok, thanks I will try.
Indeed I use Rasp pi3B Beta

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 19:17
by Knibor
Now I get this Error

2018-11-18 19:15:00.897 Error: EventSystem: in Script #1: /home/pi/domoticz/scripts/lua/JSON.lua:660: html passed to JSON:decode(): <html><head><title>Unauthorized</title></head><body><h1>401 Unauthorized</h1></body></html>

i change that line to

Code: Select all

json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()/code]

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 21:29
by jvdz
That line should be without "/code]"at the end, but that is not the error you see.
I assume you are using user&password to access your domoticz systems and you aren't prvoding the userid&password on the url?
The easy way out would be to change the ip asdress to 127.0.0.1 when you run the script on the domoticz pi and add that to the system settings for local ipaddress, which means that it won't need an userd&password to access the system.

Jos

Re: Average outside temperature with Lua

Posted: Sunday 18 November 2018 23:33
by Knibor
ok thanks,
where can I find the system settings, and where to add, I'm newbie to linux and Domoticz.

Re: Average outside temperature with Lua

Posted: Monday 19 November 2018 7:19
by Joep123
Setup > Settings > Local Networks (no username/password):

Re: Average outside temperature with Lua

Posted: Monday 19 November 2018 20:25
by Knibor
I changed the IP address in " Setup > Settings > Local Networks (no username/password)" to 127.0.0.1 and now I get the error

2018-11-19 20:20:01.142 Error: EventSystem: in Script #1: [string "local function DeviceUpdate(idx, value1)..."]:32: attempt to index local 'jsonData' (a nil value)

code is now

Code: Select all

local function DeviceUpdate(idx, value1)
    local cmd = string.format("%d|0|%.2f", idx, value1)
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

Debug = "YES" -- Debugging aanzetten ("YES") of uitzetten ("NO")

commandArray = {}

local m = os.date('%M')
if (m % 5 == 0) then -- script loopt iedere 5 minuten

    -- Variabelen instellen
    local temperature_name	= 'Gemiddelde Temp buiten'
    local temperature_idx	= otherdevices_idx[temperature_name]

    local uitlees_name	= 'Temperature'
    local uitlees_idx	= otherdevices_idx[uitlees_name]

    --Temperaturen van afgelopen 24 uur opvragen
    local sQuery	= 'curl "http://127.0.0.1/json.htm?type=graph&sensor=temp&idx='..tostring(uitlees_idx)..'&range=day"'
    local handle=assert(io.popen(sQuery))
    local raw = handle:read('*all')
    handle:close()

    --Ontvangen waarden verwerken
--~ 	print(raw)
    json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
    local jsonData = json:decode(raw)

    if Debug=='YES' then
        print (jsonData.title)
        print (jsonData.status)
        print (jsonData.result[1].d)
        print (jsonData.result[1].te)
    end

    --Gemiddelde temperatuur van afgelopen 24 uur bepalen
    local sum = 0
    local ave = 0
    local elements = #jsonData.result

    for i = 1, elements do
        sum = sum + jsonData.result[i].te
        -- print(i,sum)
    end

    ave = sum / (elements)

    if Debug=='YES' then
        print('sum: '..tostring(sum))
        print('elements: '..tostring(elements))
        print('Gemiddeld: '..tostring(ave))
    end

    --Gemiddelde temperatuur opslaan in virtuele temperatuur sensor
    DeviceUpdate(temperature_idx,ave)

end
return commandArray

Re: Average outside temperature with Lua

Posted: Monday 19 November 2018 22:33
by jvdz
What does the rest of the log messages show as this is the very last part stating it didn't set the value for the variable?
Are you sure about the devicename for temperature_name being "Gemiddelde Temp buiten" (check upper/lower case as well)?

Jos

Re: Average outside temperature with Lua

Posted: Tuesday 20 November 2018 9:09
by mvzut
I tried your script, and it works when I add the Domoticz port number (in my case 8080) to the curl command, so http://127.0.0.1:8080.
In a previous version of your code, I noticed that you did use the port number (also 8080), so this will probably solve your problem.

By the way, a few remarks which might be relevant for your application:
  • It calculates the average over the time configured in Domoticz under Settings > Log History > Short Log Sensors. I have this at 2 days, so in my case it calculates the average over 2 days! May be important to realize if others are going to use your code for inspiration. This can be solved by the way, by not adding all values but only from the last 24h.
  • You may already have thought of this, but in case you didn't: It calculates a so-called "running average" over the last 24h, so not for an exact day (0:00 - 23:59). This means you have to retrieve the value at 0:00h every night and use that for your gas calculations.

Re: Average outside temperature with Lua

Posted: Tuesday 20 November 2018 18:13
by Knibor
Hi, it works now, I was struggling with Setup > Settings > Local Networks (no username/password) and indeed make a little mistake with the device name.
Thanks for the info "calculates the average" now I understand how it works.

I have only one little problem when I use the device "Temperature" it only has the temperature in degree C.
This was only my test temperature device not the outside temperature.

Now I want to use the the real outside temperature measurement, but this one is from the type degree C and Humidity %
How do I separate the degree C from Humidity %, so that I only measure the degree C.
Schermafbeelding 2018-11-20 om 18.12.39.png
Schermafbeelding 2018-11-20 om 18.12.39.png (77.72 KiB) Viewed 4403 times

Re: Average outside temperature with Lua

Posted: Tuesday 20 November 2018 19:01
by Joep123

Re: Average outside temperature with Lua

Posted: Tuesday 20 November 2018 20:19
by Knibor
Hi, now outside temperature works perfect, thanks for the info.

Now I use the script for measure the "Gasverbruik per graaddag" in conjunction with the previous script "average temperature"

The following error is in the error log "

2018-11-20 20:17:00.475 Error: EventSystem: Lua script Gasverbuik per graaddag did not return a commandArray



What do I wrong?



The script is,

Code: Select all


return {
          on   = { timer    = { "at 23:58"}},

  execute = function(domoticz)
        local Date = domoticz.time.year..domoticz.time.month..domoticz.time.day
        local meantempOutside = domoticz.devices('Gemiddelde Temp buiten').temperature
        local baseTemp = 18
        local factor = 1
        local degreesday = baseTemp - meantempOutside
        if (domoticz.time.month >= 4 and domoticz.time.month <= 9) then factor = 0.8 end
        if (domoticz.time.month >= 11 or domoticz.time.month <= 2) then factor = 1.1 end
        degreesdays = degreesday * factor
        local GasUsage = domoticz.devices('Gas').counterToday
        local GasUsageperDegreesday = domoticz.round((GasUsage / degreesdays),3)
        if (degreesday <= 0) then 
            degreesdays = 0 
            GasUsageperDegreesday = 0
        end
        domoticz.log('Gemiddelde temperatuur buiten (laatste 24u): '..meantempOutside)
        domoticz.log('Gasverbruik vandaag: '..GasUsage..' m3')
        domoticz.log('Aantal graaddagen: '..degreesdays)
        domoticz.log('Gasverbruik: '..GasUsageperDegreesday..' m3 per graaddag')
        
        domoticz.devices('Gasverbruik per graaddag').updateCustomSensor(GasUsageperDegreesday)

  end
}

Re: Average outside temperature with Lua

Posted: Tuesday 20 November 2018 20:20
by jvdz
Knibor wrote: Tuesday 20 November 2018 18:13 Now I want to use the the real outside temperature measurement, but this one is from the type degree C and Humidity %
How do I separate the degree C from Humidity %, so that I only measure the degree C.
Have you tried and didn't it work, because as far as I know the JSON result contains field TE containing the temperature and field HU for the Humidity so all should work fine.

Jos