[Function] Sleep Timer

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)
}
1 Like

This topic was automatically closed after 60 days. New replies are no longer allowed.