incremental timer for device

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

Moderator: leecollings

Post Reply
zuputrus
Posts: 9
Joined: Saturday 23 January 2021 16:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Madrid. Spain
Contact:

incremental timer for device

Post by zuputrus »

Hi, I'm trying to program a script to control a smart plug, so that if over the course of the day between several off and on totaling more than 3 hours of use automatically turn off the plug and not turn on until the next day. I have the following code, but it doesn't work. Could someone give me a hand and tell me what I'm doing wrong?

Thank you very much.

Code: Select all

return {
    on = {
        devices = {
            'WII'
        }
    },
    data = {
        startTime = { initial = 0 },
        totalUsage = { initial = 0 }
    },
    execute = function(domoticz, device)
                           domoticz.log('Tiempo acumulado encendido: ' .. domoticz.data.totalUsage .. ' segundos')
        if device.name == 'WII' then
            if device.state == 'On' then
                -- Si el enchufe se enciende, almacenar la hora de inicio
                domoticz.data.startTime = os.time()
                  if domoticz.data.totalUsage >= 10800 then
                    -- Apagar el enchufe inteligente
                    domoticz.log('Tiempo acumulado encendido: ' .. domoticz.data.totalUsage .. ' segundos')
                    domoticz.devices('WII').switchOff().afterSec(5).checkFirst()
            elseif device.state == 'Off' then
                -- Si el enchufe se apaga, calcular el tiempo de uso y reiniciar el contador
                local endTime = os.time()
                local usageTime = endTime - domoticz.data.startTime
                domoticz.data.totalUsage = domoticz.data.totalUsage + usageTime
                domoticz.log('Tiempo acumulado de uso: ' .. domoticz.data.totalUsage .. ' segundos')

                -- Verificar si se ha alcanzado el límite de 3 horas
                if domoticz.data.totalUsage >= 10800 then
                    -- Apagar el enchufe inteligente
                    domoticz.devices('WII').switchOff().afterSec(20).checkFirst()
                    domoticz.log('El enchufe inteligente se ha apagado automáticamente debido a 3 horas de uso.')
                end

                -- Reiniciar los valores para el nuevo día
                -- domoticz.data.startTime = 0
                -- domoticz.data.totalUsage = 0
                if os.date('%d', endTime) ~= os.date('%d', domoticz.data.lastStateChangeTime) then
                domoticz.data.lastStateChangeTime = endTime
                domoticz.data.startTime = 0
                domoticz.data.totalUsage = 0
                 domoticz.log('Comenzó un nuevo día. Reiniciando el conteo de tiempo.')
                end
                end
            end
        end
    end
}
User avatar
waltervl
Posts: 5149
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: incremental timer for device

Post by waltervl »

A lot of the logic is when the device is off (elseif device.state == 'Off' then..) and that seems unlogic. Se perhaps you are misplaced an "end" here,

Also the script is triggered only when the device is switched on/off and I suppose you need to trigger it also every x minutes to update the calculation.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
zuputrus
Posts: 9
Joined: Saturday 23 January 2021 16:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Madrid. Spain
Contact:

Re: incremental timer for device

Post by zuputrus »

waltervl wrote: Monday 14 August 2023 16:52 A lot of the logic is when the device is off (elseif device.state == 'Off' then..) and that seems unlogic. Se perhaps you are misplaced an "end" here,

Also the script is triggered only when the device is switched on/off and I suppose you need to trigger it also every x minutes to update the calculation.

thanks a lot for your help @waltervl.

I tried to include your comments and got to the sript below, but I still can't get it to work. Apparently the time counting does not work the same when turning the device on and off and when taking every minute data. I don't quite get the concept of the timer.

Code: Select all

return {
    active = true,
    on = {
        devices = {'WII'},
        timer = { 'every minute' }
    },
    data = {
        startTime = { initial = 0 },
        totalUsage = { initial = 0 },
        lastStateChangeTime = { initial = 0 }
    },
    execute = function(domoticz, item)
        domoticz.log('Tiempo acumulado encendido: ' .. domoticz.data.totalUsage .. ' segundos')
        local device = domoticz.devices('WII')
        
        if item.isTimer then
            if domoticz.data.totalUsage >= 14370 then
                device.switchOff().afterSec(5).checkFirst()
                domoticz.log('El enchufe inteligente apagado por tiempo.')
                end
            -- Lógica a implementar en caso de ser un temporizador
        elseif item.isDevice then --and item.active then
            if domoticz.data.totalUsage >= 14370 then
                device.switchOff().afterSec(5).checkFirst()
                domoticz.log('El enchufe inteligente apagado por 3 horas de tiempo de uso.')
            else
                if device.state == 'On' then
                    -- Si el enchufe se enciende, almacenar la hora de inicio
                    domoticz.data.startTime = os.time()
                    domoticz.log('Tiempo acumulado de uso: encendido ' .. domoticz.data.totalUsage .. ' segundos')
                elseif device.state == 'Off' then
                    -- Si el enchufe se apaga, calcular el tiempo de uso y reiniciar el contador
                    local endTime = os.time()
                    local usageTime = endTime - domoticz.data.startTime
                    domoticz.data.totalUsage = domoticz.data.totalUsage + usageTime
                    domoticz.log('Tiempo acumulado de uso: apagado ' .. domoticz.data.totalUsage .. ' segundos')

                    -- Verificar si se ha alcanzado el límite de 3 horas
                    if domoticz.data.totalUsage >= 14370 then
                        -- Apagar el enchufe inteligente después de 10 segundos
                        device.switchOff().afterSec(10).checkFirst()
                        domoticz.log('El enchufe inteligente se ha apagado automáticamente debido a 3 horas de tiempo de uso.')
                    end

                    -- Reiniciar los valores para el nuevo día
                    if os.date('%d', endTime) ~= os.date('%d', domoticz.data.lastStateChangeTime) then
                        domoticz.data.lastStateChangeTime = endTime
                        domoticz.data.startTime = os.time()
                        domoticz.data.totalUsage = 0
                        domoticz.log('Comenzó un nuevo día. Reiniciando el conteo de tiempo.')
                    end
                end
            end
        end
    end
}
User avatar
waltervl
Posts: 5149
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: incremental timer for device

Post by waltervl »

I am struggling with the logic to keep the max 180 minutes per day.
For 1 sesssion it is easy:
if device.state == 'On' and device.lastUpdate.minutesAgo > 180 then switch off

But if for example 3x 60 minutes session you have to calculate the total usage and that makes thing a little bit more complex.

Note: This would suggest that the device is only switched on/off by the smart plug and not by switching it by the device switch itself.
Else you have to measure if there is a power usage on the smart plug (if possible). That would make things easier because 3 hours usage would resemble a certain number Wh (say for example 300 Wh). Then you can just ask the usage of today of that powerplug (dz.devices('powerplug').counterToday). if > 300 then shutdown.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
User avatar
waltervl
Posts: 5149
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: incremental timer for device

Post by waltervl »

Addition, check this script, it uses a counter device to calculate the usage of the switch then you can check the counterToday value to switch off after 3 hours.
viewtopic.php?t=27776
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
zuputrus
Posts: 9
Joined: Saturday 23 January 2021 16:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Madrid. Spain
Contact:

Re: incremental timer for device

Post by zuputrus »

waltervl wrote: Wednesday 16 August 2023 15:10 Addition, check this script, it uses a counter device to calculate the usage of the switch then you can check the counterToday value to switch off after 3 hours.
viewtopic.php?t=27776

I think I have it. Thanks again @waltervl for your help. It's been very useful¡¡

I leave here the code in case someone can use it or improve it.

What a great forum¡¡
return {
active = true,
on = {
devices = {'WII'},
timer = { 'every minute' }
},
data = {
startTime = { initial = 0 },
totalUsage = { initial = 0 },
lastStateChangeTime = { initial = 0 }
},
execute = function(domoticz, item)
local device = domoticz.devices('WII')

if item.isTimer then
if device.state == 'On' then
domoticz.data.tiempototal = domoticz.data.totalUsage + os.time() - domoticz.data.startTime
domoticz.log('Tiempo encendido desde timer ' .. domoticz.data.tiempototal .. ' segundos') end
if device.state == 'On' and domoticz.data.tiempototal >= 10800 then
device.switchOff().afterSec(5).checkFirst()
domoticz.log('El enchufe inteligente apagado por tiempo.')
end

elseif item.isDevice then --and item.active then
if domoticz.data.totalUsage >= 10800 then
device.switchOff().afterSec(5).checkFirst()
domoticz.log('El enchufe inteligente apagado por 3 horas de tiempo de uso.')
else
if device.state == 'On' then
-- Si el enchufe se enciende, almacenar la hora de inicio
domoticz.data.startTime = os.time()
domoticz.log('Tiempo acumulado de uso: encendido ' .. domoticz.data.totalUsage .. ' segundos')
elseif device.state == 'Off' then
-- Si el enchufe se apaga, calcular el tiempo de uso y reiniciar el contador
local endTime = os.time()
local usageTime = endTime - domoticz.data.startTime
domoticz.data.totalUsage = domoticz.data.totalUsage + usageTime
domoticz.log('Tiempo acumulado de uso: apagado ' .. domoticz.data.totalUsage .. ' segundos')

-- Verificar si se ha alcanzado el límite de 3 horas
if domoticz.data.totalUsage >= 10800 then
-- Apagar el enchufe inteligente después de 10 segundos
device.switchOff().afterSec(10).checkFirst()
domoticz.log('El enchufe inteligente se ha apagado automáticamente debido a 3 horas de tiempo de uso.')
end

-- Reiniciar los valores para el nuevo día
if os.date('%d', endTime) ~= os.date('%d', domoticz.data.lastStateChangeTime) then
domoticz.data.lastStateChangeTime = endTime
domoticz.data.startTime = os.time()
domoticz.data.totalUsage = 0
domoticz.log('Comenzó un nuevo día. Reiniciando el conteo de tiempo.')
end
end
end
end
end
}
zuputrus
Posts: 9
Joined: Saturday 23 January 2021 16:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Madrid. Spain
Contact:

Re: incremental timer for device

Post by zuputrus »

Oks. Tested a couple of days the script, the main code seems to work fine.

However, the date change does not seem to be working as it should. It does not detect that a day has passed and therefore the counter is not reset (the last part of script). Can anyone give me a hint on how to fix it?
Last edited by zuputrus on Friday 18 August 2023 9:00, edited 2 times in total.
User avatar
waltervl
Posts: 5149
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: incremental timer for device

Post by waltervl »

I think the last part should be in the item.isTimer section. else it will only be run when switch is switched
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
zuputrus
Posts: 9
Joined: Saturday 23 January 2021 16:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Madrid. Spain
Contact:

Re: incremental timer for device

Post by zuputrus »

waltervl wrote: Friday 18 August 2023 8:41 I think the last part should be in the item.isTimer section. else it will only be run when switch is switched
I wrote next code. Tomorrow i'll know if it's working or not.
return {
active = true,
on = {
devices = {'WII'},
timer = { 'every 5 minutes', 'every day at 00:00' }
},
data = {
startTime = { initial = 0 },
totalUsage = { initial = 0 },
lastStateChangeTime = { initial = 0 }
},
execute = function(domoticz, item)
local device = domoticz.devices('WII')

if item.isTimer and item.trigger == 'every 5 minutes' then
if device.state == 'On' then
domoticz.data.tiempototal = domoticz.data.totalUsage + os.time() - domoticz.data.startTime
domoticz.log('Tiempo encendido desde timer ' .. domoticz.data.tiempototal .. ' segundos')
if domoticz.data.tiempototal >= 10800 then
device.switchOff().afterSec(5).checkFirst()
domoticz.log('El enchufe inteligente apagado por tiempo.')
end
end

elseif item.isTimer and item.trigger == 'every day at 00:00' then
local endTime = os.time()
domoticz.data.lastStateChangeTime = endTime
domoticz.data.startTime = endTime
domoticz.data.totalUsage = 0
domoticz.log('Comenzó un nuevo día. Reiniciando el conteo de tiempo.')

elseif item.isDevice then
if domoticz.data.totalUsage >= 10800 then
device.switchOff().afterSec(5).checkFirst()
domoticz.log('El enchufe inteligente apagado por 3 horas de tiempo de uso.')
else
if device.state == 'On' then
-- Si el enchufe se enciende, almacenar la hora de inicio
domoticz.data.startTime = os.time()
domoticz.log('Tiempo acumulado de uso: encendido ' .. domoticz.data.totalUsage .. ' segundos')
elseif device.state == 'Off' then
-- Si el enchufe se apaga, calcular el tiempo de uso y reiniciar el contador
local endTime = os.time()
local usageTime = endTime - domoticz.data.startTime
domoticz.data.totalUsage = domoticz.data.totalUsage + usageTime
domoticz.log('Tiempo acumulado de uso: apagado ' .. domoticz.data.totalUsage .. ' segundos')

-- Verificar si se ha alcanzado el límite de 3 horas
if domoticz.data.totalUsage >= 10800 then
-- Apagar el enchufe inteligente después de 10 segundos
device.switchOff().afterSec(10).checkFirst()
domoticz.log('El enchufe inteligente se ha apagado automáticamente debido a 3 horas de tiempo de uso.')
end
end
end
end
end
}
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest