Page 1 of 1

getAtTime('0:20:00')

Posted: Wednesday 28 February 2018 8:35
by MartinF
Hi, I am a total newbie trying to get the historical temperature from a DS9490r 1-wire device. I've been fooling around with getAtTime('0:20:00') but no matter how I do it, I always arrive at errors with regard to nil values. I guess it's both a matter of syntax and variable scope. Some relevant sample code would be highly appreciated!

Re: getAtTime('0:20:00')

Posted: Wednesday 28 February 2018 9:48
by dannybloe
Well, for starters, post your code and the errors you get.

Re: getAtTime('0:20:00')

Posted: Wednesday 28 February 2018 17:21
by MartinF
Ok, here is my last try, which resulted in "attempt to index global 'vedpanna_20' (a nil value)"

Code: Select all

return {

    on = {
        timer = { 'every minute' }
        },

	data = {
    vedpanna = { history = true, maxItems = 25, maxMinutes = 25 }
},
	execute = function(domoticz, device)
	    
        vedpanna = domoticz.devices('Vedpanna')
        vedpanna_20 = domoticz.data.vedpanna.getAtTime('0:20:00')
 
        domoticz.log('vedpanna_temp: ' .. vedpanna.temperature)
        domoticz.log('vedpanna_20_temp: ' .. vedpanna_20.temperature)

	end
}

Re: getAtTime('0:20:00')

Posted: Thursday 01 March 2018 8:40
by dannybloe
Ok, first of all, if you create a new variable always define it as local: local vedpanna = ... as you are polluting the global scope which may affect other scripts.

So, regarding your problem. As soon as you define the (historical) variable vedpanna its initial data is empty. So, when you do this for the first time

Code: Select all

vedpanna_20 = domoticz.data.vedpanna.getAtTime('0:20:00')
it will return nill. So vedpanna_20 is nill and when you try to do vedpanna_20.temperature Lua will tell you: "attempt to index global 'vedpanna_20' (a nil value)".
So, you will have to check if domoticz.data.vedpanna is empty (or .getAtTime() returns nil)) before you start doing something with it. In other words: fill it first before taking something out:

Code: Select all

return {
	on = {
		timer = { 'every minute' }
	},
	data = {
		vedpanna = { history = true, maxMinutes = 25 }
	},
	execute = function(domoticz, device)
		local currentTemp = domoticz.devices('Vedpanna').temperature
		
		-- add temperature to the history
		domoticz.data.vedpanna.add(currentTemp)
		
		local tempMinus20 = domoticz.data.vedpanna.getAtTime('0:20:00') -- returns the temperature
		
		domoticz.log('current temperature: ' .. currentTemp)
		domoticz.log('temperature 20mins ago: ' .. tempMinus20)
	end
}
Note that I put the temperature in the history and not the entire device. That's way too much data to put in there. Just put in there what you need.
Also, note that getAtTime() only becomes relevant if there is enough data collected. So the first 20 minutes of logging will not give you the temperature at 20 minutes ago.

Re: getAtTime('0:20:00')

Posted: Thursday 01 March 2018 18:30
by MartinF
Thanks!
What I didn't grasp was that I would have to log the data myself, it makes no sense that you can't access the historical data in the Domoticz database.
However, your suggested script has been running for way over 20 minutes now and all I get is currentTemp and "attempt to concatenate local 'tempMinus20' (a nil value)".

Re: getAtTime('0:20:00')

Posted: Friday 02 March 2018 7:20
by waaren
MartinF wrote: Thursday 01 March 2018 18:30 Thanks!
What I didn't grasp was that I would have to log the data myself, it makes no sense that you can't access the historical data in the Domoticz database.
However, your suggested script has been running for way over 20 minutes now and all I get is currentTemp and "attempt to concatenate local 'tempMinus20' (a nil value)".
@MartinF, could you try this ?

Code: Select all

--[[ 
Temptest
 ]]--

return {
	on = {  timer = { 'every minute' } }, 
	data = { vedpanna = { history = true, maxMinutes = 25 } }, 
	
	execute = function(domoticz, _)
		local currentTemp  = domoticz.devices('Vedpanna').temperature or 'fail'
		local historyTemp   = domoticz.data.vedpanna
		local historyOldest  = historyTemp.getOldest().time.minutesAgo or 0  
		local tempMinus2    = "Not in history yet"
		local tempMinus20  = "Not in history yet"
		
		if currentTemp ~= 'fail' then 
			-- add temperature to the history
			historyTemp.add(currentTemp)
		
			if historyOldest > 2 then
				tempMinus2 = historyTemp.getAtTime('0:02:00').data -- returns the temperature
				if historyOldest > 21 then
					tempMinus20 = historyTemp.getAtTime('0:20:00').data -- returns the temperature
				end  
			end  
			
			print ( 'Current temperature: ' .. currentTemp)
			print ( 'Temperature 2 minutes ago: ' .. tempMinus2)
			print ( 'Temperature 20 minutes ago: ' .. tempMinus20)
			
			print ( 'Average temperature: ' ..  historyTemp.avg())
			print ( 'Oldest temperature in history: ' ..  historyTemp.getOldest().data)
			print ( 'Oldest time stamp in history: ' ..  historyTemp.getOldest().time.getISO())
			print ( 'Minutes of data in history: ' .. historyOldest)
			print ( 'Last added temperature in history: ' ..  historyTemp.getLatest().data)
			print ( 'Number of entries in History: ' ..  historyTemp.size)
			
		else
			print ( 'Skipped adding temperature to history (Wrong temperature reading) ' )
		end
	end
}

Re: getAtTime('0:20:00')

Posted: Friday 02 March 2018 8:32
by MartinF
Thank you Waaren, works like a clock!
I now understand that the errors were not handled, script aborted and no data stored. And that getAtTime is a table with data in the .data variable.

I actually made a workaround without getAtTime. It notifies me when it's time to put more firewood in the boiler and how much it'l take without boiling:

Code: Select all

local Time = require('Time')
local lastTime = Time('2017-12-31 00:00:01')
return {
	on = {
		timer = { 'every 5 minutes' }
	},
	data = {
		vedpanna = { history = true, maxMinutes = 25 }
	},
	execute = function(domoticz, device)
		local currentTemp = domoticz.devices('Vedpanna').temperature
        local availableStorage = tonumber(domoticz.devices('Utrymme i tankarna').rawData[1])
        local Ready=1
        local now = Time()
		local tempMinus5, index = domoticz.data.vedpanna.get(1)
		local tempMinus20, index = domoticz.data.vedpanna.get(4)
		local number, index = domoticz.data.vedpanna.size
		
		-- add temperature to the history
		domoticz.data.vedpanna.add(currentTemp)
		
		domoticz.log('Last time: ' .. lastTime.hoursAgo..' hours ago' )
		domoticz.log('Number: ' .. number)
		
		domoticz.log('')
		domoticz.log('Current temperature: ' .. currentTemp)
		
		if tempMinus5 ~= nil then
		    domoticz.log('Temperature idx=1: '..tempMinus5.time.minutesAgo.. ' minutes ago: ' .. tempMinus5.data)
		else
		    Ready=0
		end 
		
		if tempMinus20 ~= nil then
		    domoticz.log('Temperature idx=4: '..tempMinus20.time.minutesAgo.. ' minutes ago: ' .. tempMinus20.data)
		else
		    Ready=0
		end 

		domoticz.log('Available storage '..availableStorage)

		if (Ready==1) then 
		    if (    currentTemp < tempMinus20.data 
		        and tempMinus20.data > tempMinus5.data 
		        and currentTemp < tempMinus5.data 
		        and currentTemp > 70 
		        and currentTemp < 80 
		        and availableStorage > 0.5) 
		        and lastTime.hoursAgo >= 2 then
		    domoticz.notify('Fyll ' .. availableStorage ..' pannor med ved!')
		    lastTime=now
	        end
	    end
		
		domoticz.log('')
	end
}

Re: getAtTime('0:20:00')

Posted: Friday 02 March 2018 8:51
by dannybloe
Yeah I forgot the .data attribute.. my bad :roll: Created it myself.. how could I forget...

Re: getAtTime('0:20:00')

Posted: Friday 02 March 2018 9:57
by MartinF
:-) Thanks!