Can you try this one? It' s not a complete solution but should point you in the right direction.
Thank you very much waaren, you give the timeStamp for each state log, that was the tricky point.
I understand the behavior of the script, in spite of everything, I will have to look more closely.
So, I have decided to continue the script with the code I show bellow and it seems to work. The most complicated thing has been to manage the various Log scenarios:
- Case 1: we have a log with successives 'On' and 'Off'. (easy)
- Case 2: we have a log with two consecutive 'Off' states.
- Case 3: we have a log with two consecutive 'On' states.
- Case 4: we have a log with an 'Off' status at the beginning.
- Case 5: we run the script with the switch in the 'On' state.
I think I have managed to solve the situations 1,2,3,4 and I still have the 5 under study. But I think I will need the current time to finish it as I think.
Code: Select all
local activeDevice = 592
local scriptVar = 'Compute total minutes'
return
{
on =
{
timer =
{
'every 1 minutes', -- for DEBUG
},
httpResponses =
{
scriptVar .. '*',
},
},
logging =
{
level = domoticz.LOG_DEBUG ,
marker = scriptVar,
},
data = --persistent data?
{
state =
{
initial = {},
},
},
execute = function(dz, item)
if not(dz.devices(activeDevice).active) then return end
local AC_room = dz.devices(13)
local counter = 0
local lastTimeStamp = 0
local function makeTimeStamp(dateString, pattern)
local pattern = pattern or "(%d+)%-(%d+)%-(%d+)%s(%d+):(%d+):(%d+)" -- must be this format!! "2016-12-12 07:35:00"
local year, month, day, hour, minute, seconds= dateString:match(pattern)
return os.time({year = year, month = month, day = day, hour = hour, min = minute, sec = seconds})
end
local function triggerJSON(id, delay)
url = dz.settings['Domoticz url'] .. '/json.htm?type=lightlog&idx=' .. id
dz.openURL({ url = url, callback = scriptVar .. '_' .. id}).afterSec(delay or 0)
end
-- main
if item.isTimer or item.isDevice then
if dz.data.state[dz.time.rawDate] == nil then
dz.data.state[dz.time.rawDate] = AC_room.state -- keep state at first run of the day, will be something like: 2016-12-12T20:00:00Z
end
triggerJSON(AC_room.id)
return
end
if item.isJSON then
rt = item.json.result
local leng = 0
for k, v in pairs(rt) do
leng = leng+1
end
dz.log('Lenght ' ..leng,dz.LOG_DEBUG)
for _, record in ipairs(rt) do
dz.log('action ' .. record.Status .. ', at ' .. record.Date .. ' =>> timeStamp: ' .. makeTimeStamp(record.Date),dz.LOG_DEBUG)
if _>=2 and item.json.result[_].Data == item.json.result[_-1].Data and record.Status == "Off" then --Ok!, avoid bug for 2 successives 'Off' in Log
counter = counter - lastTimeStamp + makeTimeStamp(record.Date)
elseif _>=2 and item.json.result[_].Data == item.json.result[_-1].Data and record.Status == "On" then --Don´t have tested yet, avoid bug for 2 successives 'On' in Log
counter = counter
elseif _ == leng and record.Status == "Off" then --Ok!, avoid bug if you have an 'Off' as first state in Log (older state, not last state)
counter = counter
elseif _ == leng and record.Status == "On" then --Dont work, may be it needed to call to actual timeStamp. Need to resolve bug if srcipt runs at same time switch has 'On' state
counter = counter
elseif record.Status == "Off" then
counter = counter + makeTimeStamp(record.Date)
elseif record.Status == "On" then
counter = counter - makeTimeStamp(record.Date)
end
lastTimeStamp = makeTimeStamp(record.Date)
end
minutes= counter/60
seconds= counter%60
if seconds < 10 then
dz.log('Number of minutes ' ..math.floor(minutes)..':0'..seconds..'s',dz.LOG_DEBUG)
else
dz.log('Number of minutes ' ..math.floor(minutes)..':'..seconds..'s',dz.LOG_DEBUG)
end
dz.log('Counter ' .. dz.utils.round(counter,2),dz.LOG_DEBUG)
else
dz.log('Problem retrieving data..',dz.LOG_ERROR)
dz.log(item,dz.LOG_DEBUG)
end
end
}