Sorry if this isn’t the appropriate place, but no other category seems to be applicable....
I’ve been unable to find a function that operates as a sleep timer, so I wrote the following function (again, I really should convert this to a node) and am sharing it here.
It’s a sleep timer that I’m using for my TV.
topic “start”, optional payload of time in minutes for the timeout (default in function)
topic “stop”, stops the timer
topic “increment”, optional payload of time to increment current timeout by (default in function)
topic “decrement”, as above but decrement
topic “remaining”, outputs the time remaining on output 3.
sending start starts the timer running, sending start again will restart the timer with the timeout provided or the default
sending stop stops the timer...obvious really.
sending increment increments the current timeout count by the given minutes if provided, if not provided increments by a default set in the function
decrement does the same, but opposite. Decrementing to zero or below zero stops the timer.
Output 1:
payload is “started” if the timer was not active and the timer was started, “stopped” if the timer is stopped, and “timeout” if the timer expires.
Output 2:
the current number of seconds remaining, triggers every second. I use this catch 60, 30 and 10 seconds to display warnings on the TV.
Output 3:
when the timeout value is changed by a start, increment or decrement, this payload contains the number of seconds of the new timer. (I use this to display a message on the TV showing the new sleep timer time remaining). When the remaining command is send, then this outputs the number of seconds remaining on the timer.
Not much to it. Seems to work for me, couldn’t find a timer in the library which had this exact functionality, so implemented it myself. Might be of use to some folks.
(there’s probably better ways of doing stuff, but I’ve only had node-red installed for a day or so)
const defaultTimeout = 60
const defaultAdjust = 15
timerObject = context.get('timerObject')||null
isRunning = context.get('isRunning')||false
switch(msg.topic) {
case "start":
if ((!isNaN(msg.payload)) && (msg.payload!==undefined) && (msg.payload>0)) {
context.set('timeout', (msg.payload*60))
} else {
context.set('timeout', (defaultTimeout*60))
}
if (!isRunning) {
msg.topic = ''
msg.payload = 'started'
node.send([msg, null, null])
}
context.set('isRunning', true)
msg.topic = ''
msg.payload = context.get('timeout')
node.send([null, null, msg])
break;
case "stop":
if (!isRunning) {
return
}
context.set('isRunning', false)
context.set('timeout', undefined)
msg.topic = ''
msg.payload = 'stopped'
node.send([msg, null, null])
break
case "increment":
if ((isNaN(msg.payload))||(msg.payload===undefined)||(msg.payload<=0)) {
value = defaultAdjust*60
} else {
value = msg.payload*60
}
if (isRunning) {
context.set('timeout', (context.get('timeout')||defaultTimeout)+value)
} else {
context.set('timeout', context.get('timeout')||value)
}
context.set('isRunning', true)
msg.topic = ''
msg.payload = context.get('timeout')
node.send([null, null, msg])
break
case "remaining":
value = context.get('timeout')||0
if (value>0) {
msg.topic = ''
msg.payload = value
node.send([null, null, msg])
}
return
case "decrement":
if ((isNaN(msg.payload))||(msg.payload===undefined)||(msg.payload<=0)) {
value = defaultAdjust*60
} else {
value = msg.payload*60
}
if (!isRunning) {
return
}
val = (context.get('timeout')||defaultTimeout)-value
if (val<0) {
context.set('isRunning', false)
context.set('timeout', undefined)
msg.topic = ''
msg.payload = 'stopped'
node.send([msg, null, null])
} else {
context.set('timeout', val)
context.set('isRunning', true)
msg.topic = ''
msg.payload = context.get('timeout')
node.send([null, null, msg])
}
break
}
if (!timerObject) {
timerObject = setInterval(function() {
isRunning = context.get('isRunning')||false
if (isRunning) {
timeout = context.get('timeout')
if (timeout<=0) {
context.set('isRunning', false)
msg.topic = ''
msg.payload = "timeout"
node.send([msg, null, null])
} else {
timeout = timeout-1
}
msg.topic = ''
msg.payload = timeout
node.send([null, msg, null])
context.set('timeout', timeout)
}
}, 1000);
context.set('timerObject', timerObject)
}