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?
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
}
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
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.
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
}
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
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
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.
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
}
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.
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
}