On-the-fly sleep timer

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
User avatar
Denny64
Posts: 53
Joined: Friday 03 February 2017 11:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.1
Location: Italy
Contact:

On-the-fly sleep timer

Post by Denny64 »

A very useful function that I could not find in Domoticz is the "sleep" timer. I needed to switch off some controlled devices after a period (first of all the TVs) but I couldn't find anything that was simple and immediate to use in Domoticz and so, not being a programmer, I asked ChatGPT to create a script for this need.

The script works with more than one device and totally independently; it is possible to turn on a device by setting, for example, a 30-minute timer and turn on others by setting different times.

For use it, you must first create a virtual selector (I called it "TV Timer") in which we will give each level a numerical value (Ex. 30; 60; 90; 120) and will be the sleep minutes.

Then, in the script we will enter the names of the devices we want to control and the name of the selector just created (which will be the same for all devices).

Once the script has been installed in Domoticz, to use it just select a timing level and then turn on a device among those we have inserted in the script; the selector will return to off automatically and the device will turn off after the set time.

Code: Select all

local devicesToControl = {
    {
        name = 'TV kitchen',           -- First device name
        timer = 'Timer TV'  -- Unique timer selector name for all devices
    },
    {
        name = 'TV living',                -- Second device name
        timer = 'Timer TV'  -- Unique timer selector name for all devices
    },
{
        name = 'TV attic',           -- Third device name
        timer = 'Timer TV'  -- Unique timer selector name for all devices
    },
{
        name = 'TV bedroom',           -- Fourth device name
        timer = 'Timer TV'  -- Unique timer selector name for all devices
    },
    -- You can add more devices with the unique timer selector
}

return {
    on = {
        devices = {
            -- Add the names of the devices to monitor the status
            'TV kitchen',
            'TV living',
            'TV attic',
            'TV bedroom',  -- Add more devices if needed
            'Timer TV', -- Add unique timer selector name
        }
    },
    execute = function(domoticz, device)
        -- Function to set independent sleep timer for specified device
        local function setTimerToSwitchOff(deviceName, timerValue)
            local selectedDevice = domoticz.devices(deviceName)
            selectedDevice.switchOff().afterMin(timerValue)
            domoticz.log('Device ' .. deviceName .. ' will turn off after ' .. timerValue .. ' minutes.')
            domoticz.notify('Scheduled turn off', 'Device ' .. deviceName .. ' will turn off after ' .. timerValue .. ' minutes.', domoticz.PRIORITY_LOW)
              --Reset the selector after power on
              --domoticz.devices('Timer TV').switchOff().afterSec(10)
              domoticz.devices('Timer TV').switchOff()
          
        
         end

        -- Check if the device belongs to the list of monitored devices and if it has been turned on
        local deviceToSwitchOff = nil
        for _, deviceInfo in ipairs(devicesToControl) do
            if deviceInfo.name == device.name and device.state == 'On' then
                deviceToSwitchOff = deviceInfo
                break
            end
        end

        -- If the device belongs to the list of monitored devices and is turned on, set the sleep timer
        if deviceToSwitchOff then
            local timerValue = tonumber(domoticz.devices(deviceToSwitchOff.timer).state)
            if timerValue and timerValue > 0 then
                setTimerToSwitchOff(deviceToSwitchOff.name, timerValue)

            else
        --domoticz.log('Invalid timer selector value for device ' .. deviceToSwitchOff.name)
        --domoticz.notify('Invalid time', 'The selected time is not valid for the device ' .. deviceToSwitchOff.name .. '. Make sure you select a number greater than 0.', domoticz.PRIORITY_HIGH)
            end
        end
    end
}
I don't know if the code written by ChatGPT can be improved (I made some small changes), but it works perfectly. And this is
User avatar
boum
Posts: 135
Joined: Friday 18 January 2019 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10717
Location: France
Contact:

Re: On-the-fly sleep timer

Post by boum »

The code is overcomplicated (it could be written in half the lines and logic would be clearer) and would be a hell to debug. But as long as it works…
User avatar
Denny64
Posts: 53
Joined: Friday 03 February 2017 11:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.1
Location: Italy
Contact:

Re: On-the-fly sleep timer

Post by Denny64 »

The initial idea was to have a button only to activate sleep on a device, and I succeeded with Blockly but it wasn't elegant. Then I asked ChatGPT and she gave me that code.

The starting point of a sleep button I think is interesting, and suggestions for "cleaning up" the code are still welcome.
User avatar
boum
Posts: 135
Joined: Friday 18 January 2019 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10717
Location: France
Contact:

Re: On-the-fly sleep timer

Post by boum »

just on top of my head (i won't even try to see if syntax is correct or if the script is working)

Code: Select all

local devicesToControl = {
    -- table where key is the device names to put to sleep, value is the device name of the selector switch sleep timer
    ['TV kitchen'] = 'Timer TV',
    ['TV living'] = 'Timer TV',
    ['TV attic'] = 'Timer TV',
    ['TV bedroom'] = 'Timer TV',
}

return {
    on = {
        devices = {
            -- Add the names of the devices to monitor the status
            'TV kitchen',
            'TV living',
            'TV attic',
            'TV bedroom',  -- Add more devices if needed
        }
    },
    execute = function(domoticz, device)
        -- early return
        if not device.active then
            domoticz.log('Device ' .. device.name .. ' off, timer script not needed.', domoticz.LOG_DEBUG)
            return
        end
        
        -- Check if the device belongs to the list of monitored devices and if it has been turned on
        local timerForDevice = devicesToControl[device.name]

        -- If the device belongs to the list of monitored devices and is turned on, set the sleep timer
        if timerForDevice then
            local timerDevice = domoticz.devices(timerForDevice)
            local timerValue = tonumber(timerDevice.state)
            if timerValue and timerValue > 0 then
                device.switchOff().afterMin(timerValue)
                domoticz.log('Device ' .. device.name .. ' will turn off after ' .. timerValue .. ' minutes.')
                domoticz.notify('Scheduled turn off', 'Device ' .. device.name .. ' will turn off after ' .. timerValue .. ' minutes.', domoticz.PRIORITY_LOW)
                --Reset the selector after power on
                timerDevice.switchOff()
            else
        --domoticz.log('Invalid timer selector value for device ' .. device.name)
        --domoticz.notify('Invalid time', 'The selected time is not valid for the device ' .. device.name .. '. Make sure you select a number greater than 0.', domoticz.PRIORITY_HIGH)
            end
        end
    end
}
User avatar
Denny64
Posts: 53
Joined: Friday 03 February 2017 11:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.1
Location: Italy
Contact:

Re: On-the-fly sleep timer

Post by Denny64 »

Well done, thanks for your interest boum.

I asked ChatGPT to clean up and reduce the code and this is one of the possible solutions...

Code: Select all

local devicesToControl = {
    { name = 'TV kitchen', timer = 'Timer TV' },
    { name = 'TV living', timer = 'Timer TV' },
    { name = 'TV attic', timer = 'Timer TV' },
    { name = 'TV bedroom', timer = 'Timer TV' },
    -- table where key is the device names to put to sleep, value is the device name of the selector switch sleep timer
}

return {
    -- Add the names of the devices to monitor the status
    on = { devices = { 'TV kitchen', 'TV living', 'TV attic', 'TV bedroom', 'Timer TV' } },
    execute = function(domoticz, device)
        local function setTimerToSwitchOff(deviceName, timerValue)
            domoticz.devices(deviceName).switchOff().afterMin(timerValue)
            domoticz.log('Device ' .. device.name .. ' will turn off after ' .. timerValue .. ' minutes.')
            domoticz.notify('Scheduled turn off', 'Device ' .. device.name .. ' will turn off after ' .. timerValue .. ' minutes.', domoticz.PRIORITY_LOW)
            
        end

        for _, deviceInfo in ipairs(devicesToControl) do
            if deviceInfo.name == device.name and device.state == 'On' then
                local timerValue = tonumber(domoticz.devices(deviceInfo.timer).state)
                if timerValue and timerValue > 0 then
                setTimerToSwitchOff(deviceInfo.name, timerValue)
                else
        --domoticz.log('Invalid timer selector value for device ' .. device.name)
        --domoticz.notify('Invalid time', 'The selected time is not valid for the device ' .. device.name .. '. Make sure you select a number greater than 0.', domoticz.PRIORITY_HIGH)
            end

                domoticz.devices(deviceInfo.timer).setState('Off').silent()
                break
            end
        end
    end
}
And this also works.
User avatar
boum
Posts: 135
Joined: Friday 18 January 2019 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10717
Location: France
Contact:

Re: On-the-fly sleep timer

Post by boum »

wow. such smart. changing whitespace to reduce code. awesome.

Still the timer selector on the device triggers. Still a useless for loop.
And now a non existing setState function call.
Yeah, great. My job is safe.
User avatar
Denny64
Posts: 53
Joined: Friday 03 February 2017 11:34
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.1
Location: Italy
Contact:

Re: On-the-fly sleep timer

Post by Denny64 »

I will use your code for sure.

Thanks again boum.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest