Page 1 of 1
Countdown timer
Posted: Monday 02 November 2020 22:27
by Patricen
Hello,
Is there a way using a dummy device to make a countdown timer that I can set the duration with GUI ?
The idea would be to be able setting the heating setpoints to 16° while I'm out for a weekend for example (1 day, 2 days, 1 week) and change the timerplan back to comfort mode.
Any idea is warmly welcome!
Patrice
Re: Countdown timer
Posted: Tuesday 03 November 2020 1:59
by waaren
Patricen wrote: Monday 02 November 2020 22:27
Is there a way using a dummy device to make a countdown timer that I can set the duration with GUI ?
The method to set an Alarm time as posted
here could be modified without much effort to create such a countdown.
Re: Countdown timer
Posted: Tuesday 03 November 2020 6:58
by Patricen
Thanks a lot waaren,
I'll try this, it could be interesting having this kind of object native in Domoticz!
Patrice
Re: Countdown timer
Posted: Tuesday 03 November 2020 15:00
by waaren
Patricen wrote: Tuesday 03 November 2020 6:58
Thanks a lot waaren,
I'll try this, it could be interesting having this kind of object native in Domoticz!
Patrice
Can you try this proof of concept?
Code: Select all
--[[
dzvents script to use a selector type switch to set and start a countdown
selector levels must be set and named to:
0 Off
10 add 1 week
20 add 3 days
30 add 1 day
40 add 4 hours
50 add 1 hour
60 add 10 minutes
70 add 1 minute
80 reset to now
90 start Countdown
100 set idle
110 Choose
Off level must be set to "hided" and for lay-out purposes best to set Selector Style to "select Menu"
The name of the selector switch should initially be set to: "Countdown"
History:
20201102 Start coding
20201103 first proof of concept
todo:
-- Allow multiple Countdown selectors
]]
local scriptVar = 'Countdown'
return
{
on =
{
devices =
{
700, -- id of your selector type switch with initial name "Countdown"
},
system =
{
'start', -- Needed in case domoticz was restarted (the customEvent need to be emitted again)
},
customEvents =
{
scriptVar, -- This will come back once the countdown "reaches zero"
}
},
logging =
{
level = domoticz.LOG_DEBUG, -- set to domotiocz.LOG_ERROR when all OK
marker = scriptVar,
},
data =
{
countdown =
{
initial = 0,
},
},
execute = function(dz, item)
local datePattern = '(%d%d%d%d)-(%d%d)-(%d%d)%s(%d+):(%d%d+)' -- this will catch "yyyy-mm-dd hh:mm"
local minutesTable =
{
["add 1 week"] = 10080,
["add 3 days"] = 4320,
["add 1 day"] = 1440,
["add 4 hours"] = 240,
["add 1 hour"] = 60,
["add 10 minutes"] = 10,
["add 1 minute"] = 1,
["reset to now"] = 0,
["start Countdown"] = 0,
["set idle"] = 0,
["Choose"] = 0,
}
local function date2Timestamp(str)-- Assuming a date pattern like: yyyy-mm-dd hh:mm
dz.log(str)
local year, month, day, hour, minute = str:match(datePattern)
return os.time({year = year, month = month, day = day, hour = hour, min = minute})
end
local function timeStamp2dateString(timestamp)
return os.date('%Y-%m-%d %H:%M',( timestamp or os.time() ) )
end
local function resetLevel()
if item.isDevice then
item.switchSelector('Choose').afterSec(1).silent() -- force display of new name
end
end
local function closeEnough()
return os.time() > dz.data.countdown - 5 and os.time() < dz.data.countdown + 5
end
local function emitCountdown()
if dz.data.countdown > os.time() then
dz.emitEvent(scriptVar).afterSec(dz.data.countdown - os.time())
dz.log('Countdown set for ' .. ( dz.data.countdown - os.time() ) .. ' seconds.' .. '('.. timeStamp2dateString(dz.data.countdown) ..')', dz.LOG_DEBUG)
else
dz.log('Countdown target is not in the future', dz.LOG_DEBUG)
end
resetLevel()
end
local function setName(timestamp)
dz.data.countdown = 0
if item.levelName == 'reset to now' then
item.rename('Countdown: ' .. timeStamp2dateString())
elseif item.levelName == 'set idle' then
item.rename('Countdown off')
else
item.rename('Countdown: ' .. timeStamp2dateString(timestamp))
dz.data.countdown = timestamp
end
resetLevel()
end
-- main code
if item.isDevice and item.levelName == 'set idle' then
dz.data.countdown = 0
setName(0)
elseif item.isDevice and item.levelName == 'start Countdown' then
emitCountdown()
elseif item.isDevice and item.levelName ~='Choose' then
-- get Multiplier
local multiplier = minutesTable[item.levelName] or 0
-- current timestamp
local currentTimestamp = os.time()
local startStr, endStr = item.name:find(datePattern)
if startStr then
currentTimestamp = date2Timestamp(item.name:sub(startStr, endStr))
if currentTimestamp < os.time() then currentTimestamp = os.time() end
end
local newTimestamp = currentTimestamp + multiplier * 60
setName(newTimestamp)
elseif item.isCustomEvent then
if closeEnough() then
dz.log('Put your required actions for countdown ended here', dz.LOG_DEBUG)
dz.data.countdown = 0
else
dz.log('This is not the customEvent we are looking for', dz.LOG_DEBUG)
end
elseif item.isSystemEvent and dz.data.countdown ~= 0 then
if dz.data.countdown > os.time() then
dz.log('domoticz was restarted ==>> rescheduling the countdown', dz.LOG_DEBUG)
emitCountdown()
else
dz.log('Countdown time already passed. Check if rescheduling is needed', dz.LOG_FORCE)
end
end
end
}
Re: Countdown timer
Posted: Saturday 14 November 2020 9:25
by Patricen
Tried, Working pretty well!