How-to: launch action after a certain time [SOLVED]
Moderator: leecollings
-
- Posts: 117
- Joined: Tuesday 06 February 2018 18:48
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta rel
- Contact:
How-to: launch action after a certain time
Hello,
I'm trying to optimize my boiler start-up sequence, but have an issue coding this.
Currently there is a flowswitch that starts heating as soon as I do open a hot water tap. As there is a 50l hot water tank, I would like to start heating after 30s of water flow.
That was for the story.
Then, I would like to start heating after 30s, only if the water is still flowing, otherwise, no need to start.
If started, as soon as the water is not flowing anymore, stop heating.
Looks easy to write it but I can't figure out how to code it with dzvents.
I'm trying to optimize my boiler start-up sequence, but have an issue coding this.
Currently there is a flowswitch that starts heating as soon as I do open a hot water tap. As there is a 50l hot water tank, I would like to start heating after 30s of water flow.
That was for the story.
Then, I would like to start heating after 30s, only if the water is still flowing, otherwise, no need to start.
If started, as soon as the water is not flowing anymore, stop heating.
Looks easy to write it but I can't figure out how to code it with dzvents.
-
- Posts: 631
- Joined: Saturday 21 September 2019 17:55
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.1
- Location: The Netherlands
- Contact:
Re: How-to: launch action after a certain time
Looking at the dzvents documentation, you probably have to use the command options to handle this. Did you have a look at that?
-
- Posts: 117
- Joined: Tuesday 06 February 2018 18:48
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta rel
- Contact:
Re: How-to: launch action after a certain time
Sure,
Found out afterSecs control, that I should combine with item.lastUpdate but within if function, item.lastupdate has a restriction. If the item is the one that triggered the event, lastUpdate time is the time before the event is triggered, then it is useless...
Then I need to find a trick.
Found out afterSecs control, that I should combine with item.lastUpdate but within if function, item.lastupdate has a restriction. If the item is the one that triggered the event, lastUpdate time is the time before the event is triggered, then it is useless...
Then I need to find a trick.
-
- Posts: 631
- Joined: Saturday 21 September 2019 17:55
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.1
- Location: The Netherlands
- Contact:
Re: How-to: launch action after a certain time
I understand, you want to trigger the flameswitch 30 seconds after the triggering of the flowswitch, but only of the flowswitch is still on. Could you use a dummy switch as intermediary?
Something like the code below ? (not tested) The script triggers itself a second time by changing the status of a dummyswitch. Not sure if this works, but easy to try out.
I think you also need to consider when you want to fill up the tank again with hot water, otherwise you will run out of hot water at some point.
Something like the code below ? (not tested) The script triggers itself a second time by changing the status of a dummyswitch. Not sure if this works, but easy to try out.
I think you also need to consider when you want to fill up the tank again with hot water, otherwise you will run out of hot water at some point.
Code: Select all
local idxFlowSwitch=XX, -- XX,YY,ZZ to be replaced by device numbers
local idxDummySwitch=YY,
local idxFlameSwitch=ZZ,
return {
on = {
devices = {
idxFlowSwitch,
idxDummySwitch
},
},
execute=function(domoticz,device)
if device==idxFlowSwitch then -- script triggered by flowswitch
domoticz.devices(idxDummySwitch).switchOff()
domoticz.devices(idxFlameSwitch).switchOff()
if device.state=='On' then -- flowswitch was switched to On
domoticz.devices(idxDummySwitch).switchOn().afterSec(30)
end
else -- script triggered by dummyswitch (30 seconds after flowswitch)
if domoticz.devices(idxFlowSwitch)=='On' then -- flow is still on
domoticz.devices(idxFlameSwitch).switchOn()
end
end
end
}
-
- Posts: 117
- Joined: Tuesday 06 February 2018 18:48
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta rel
- Contact:
Re: How-to: launch action after a certain time
Thanks, I'll check that.
Indeed, there is the dummy switch solution that I already used for another application, but I was wondering if there could be a way of coding that does not need the dummy switch.
"Appel ECS" is the water flowswitch and "Chaudière-Chauffe ECS" is the flame control
At the moment the code looks as below but is nos satisfying, as " if(Appel_ECS == 'On' and dz.devices('Appel ECS').lastUpdate.secondsAgo > 10)" does not work properly due to the limitation of item.lastUpdate.secondsAgo > 10 as the item triggered the thread.
dzVents documentation says :
and removing devices trigger, but I do have no idea about the required computing resources it takes to the RPI.
Indeed, there is the dummy switch solution that I already used for another application, but I was wondering if there could be a way of coding that does not need the dummy switch.
This switch is only intended to anticipate starting the flame before the flame starts due to temperature drop, because without the timer I want to set-up, it is very stressful for the ignition system (it is a common known failure for this type of boiler) and it unnecessarily consumes gas for short time water consumption. There is a 50l buffer tank and it looks like 60s would be the right delay time at the end. Basically, running out of hot water only happens for bathtub filling if the flowswitch is not connected to the flame control system.I think you also need to consider when you want to fill up the tank again with hot water, otherwise you will run out of hot water at some point.
"Appel ECS" is the water flowswitch and "Chaudière-Chauffe ECS" is the flame control
At the moment the code looks as below but is nos satisfying, as " if(Appel_ECS == 'On' and dz.devices('Appel ECS').lastUpdate.secondsAgo > 10)" does not work properly due to the limitation of item.lastUpdate.secondsAgo > 10 as the item triggered the thread.
dzVents documentation says :
The solution could be (but I don't find this really smart) to trigger usinglastUpdate: Time Object: Time when the device was updated. **Note: The lastUpdate for devices that triggered the script at hand is in fact the previousUpdate time. The real lastUpdate time for these “script triggering” devices is the current time.
Code: Select all
timer = {'Every 20 seconds'}
Code: Select all
return
{
on =
{
devices = {
'Appel ECS',
'Chaudière-Chauffe ECS'
},
timer = {'Every 10 minutes'}, -- just in case the flowswitch off is not detected, to avoid overheating
},
logging =
{
level = domoticz.LOG_debug, -- change to domoticz.LOG_ERROR when script is tested and OK
marker = 'Contrôle ECS',
},
execute = function(dz, item)
Appel_ECS = dz.devices('Appel ECS').state
dz.log('Appel ECS : ' .. Appel_ECS )
if(Appel_ECS == 'On' and dz.devices('Appel ECS').lastUpdate.secondsAgo > 10)
then
dz.devices('Chaudière-Chauffe ECS').switchOn().checkFirst()
dz.log('Démarrage chauffe ECS')
elseif(Appel_ECS == 'Off')
then
dz.devices('Chaudière-Chauffe ECS').switchOff().checkFirst()
dz.log('Arrêt chauffe ECS')
end
end
}
-
- Posts: 117
- Joined: Tuesday 06 February 2018 18:48
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta rel
- Contact:
Re: How-to: launch action after a certain time
Finally I found out a dummy solution without dummy switch...
-
- Posts: 631
- Joined: Saturday 21 September 2019 17:55
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.1
- Location: The Netherlands
- Contact:
Re: How-to: launch action after a certain time
You said you wanted a solution in Dzvents?
-
- Posts: 470
- Joined: Thursday 26 October 2017 13:37
- Target OS: Raspberry Pi / ODroid
- Domoticz version: beta
- Location: Delft
- Contact:
Re: How-to: launch action after a certain time [SOLVED]
Using dzvents you can trigger a custom event. In that custom event you can send a payload. So what you can do is to have a custom event sent using the timed actions 30 seconds after the tap started running, in the payload you put the last update value of the current time the tap was opened. Next when you receive this custom event, you check if the tap is still open (status of the tap switch is "On" and last update equals the time in the payload of the custom event). If the status is "Off" by the time you receive the custom event, the tap must have been open for less han 30 seconds. If the status is "On" and the last update time on the tap switch matches the time in the payload, the tap is open for at least 30 seconds. If the status is "On" but the tap's last update differs from the time in the message's payload, the tap must have been opened, closed then re-opened within your 30 second time. It was NOT on for 30 seconds. Plus, you will probably get another custom message with a new pay load somewhat later, to which you can again do the same tests. I created a test script for this method once with a lot of help of @waaren. I never got to fully implementing it, maybe you can use this as an example for your purpose:
To get an even more reliable result you could try to add the length of the period for each period the tap was "On" (i.e. the number of seconds between the "On" and the "Off" event) in a persistent data with "history = true, MaxMinutes = 1" , then when you receive the custom event retrieve the sum of the periods over all times the tap was "On" in the last minute simply by calling the statistical function domoticz.data.myVar.sum().
Code: Select all
return {
on = {
devices = {
"myTest"
},
customEvents = {
"Delayed-Auto-On*"
}
},
logging =
{
level = domoticz.LOG_ERROR,
},
execute = function(domoticz, item)
if item.isDevice then
-- if the trigger device changed to 'On' ...
if item.bState then
-- TODO: determine the delay for the device.
local delay = 20
-- ... and there is a delay > 0 seconds defined for this device...
if delay ~= nil and delay > 0 then
local Time = require('Time')
local thisUpdate = Time(os.date("%Y-%m-%d %H:%M:%S", os.time(item.lastUpdate.current)))
local name = 'Delayed-Auto-On-' .. tostring(item.idx) .. '-' .. thisUpdate.raw
local extraData = { ["idx"] = item.idx, ["bState"] = item.bState, ["thisUpdate"] = thisUpdate }
-- ... emit a customEvent after the delay.
domoticz.emitEvent(name, extraData).afterSec(delay)
else
-- No delay, activate the action right now.
-- TODO: add action here.
domoticz.log( 'Triggering action without delay', domotiz.LOG_FORCE)
end
end
elseif item.isCustomEvent then
-- If we get here, the customEvent has been triggered after the delay period. We will
-- test that:
-- 1 : bState on the device equals that which we stored in the [extra data], and
-- 2 : lastUpdate on the device equals that which we stored in [extra data].
-- If both conditions are met we know the device is still unchanged after the delay
-- and we can then start the delayed action.
if item.json == nil then
domoticz.log( 'json is missing', domoticz.LOG_ERROR)
elseif item.json.idx == nil then
domoticz.log( 'idx is missing', domoticz.LOG_ERROR)
elseif item.json.bState == nil then
domoticz.log( 'bstate is missing', domoticz.LOG_ERROR)
elseif item.json.thisUpdate == nil then
domoticz.log( 'thisUpdate is missing', domoticz.LOG_ERROR)
else
local device = domoticz.devices(item.json.idx)
if device == nil then
domoticz.log( 'device('..tostring(item.json.idx)..') not found', domoticz.LOG_ERROR)
else
local Time = require('Time')
local thisUpdate = Time(os.date("%Y-%m-%d %H:%M:%S", os.time(item.json.thisUpdate)))
if device.bState == item.json.bState and device.lastUpdate.compare(thisUpdate).compare == 0 then
-- TODO: add action here.
domoticz.log( 'Triggering action after delay', domoticz.LOG_FORCE)
end
end
end
else
domoticz.log( 'Unexpected trigger type', domoticz.LOG_ERROR)
end
end
}
To get an even more reliable result you could try to add the length of the period for each period the tap was "On" (i.e. the number of seconds between the "On" and the "Off" event) in a persistent data with "history = true, MaxMinutes = 1" , then when you receive the custom event retrieve the sum of the periods over all times the tap was "On" in the last minute simply by calling the statistical function domoticz.data.myVar.sum().
-
- Posts: 22
- Joined: Wednesday 13 January 2016 16:11
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Contact:
Re: How-to: launch action after a certain time
Why does customEvents = { … } does not support .name attribute? ALmost all other objects support .name.
It would be useful to identify it when handling multiple customEvents in one script. E.g.:
Currently the only workaround is to use the second parameter payload to indicate which one to execute, e.g.:
Is there a reason for it? Or am I missing something?
It would be useful to identify it when handling multiple customEvents in one script. E.g.:
Code: Select all
return {
on = {
devices = {'Test1', 'Test2'},
customEvents = {'delay_1_sec', 'delay_2_sec'},
},
logging = {level = domoticz.LOG_INFO, marker = 'Test',},
execute = function(domoticz, item)
if item.isDevice and item.name == 'Test1' and item.state == 'On' then
domoticz.emitEvent('delay_1_sec').afterSec(1)
elseif item.isDevice and item.name == 'Test2' and item.state == 'On' then
domoticz.emitEvent('delay_2_sec').afterSec(2)
elseif item.isDevice and item.state == 'Off' then
-- do nothing
elseif item.isCustomEvent and item.name == 'delay_1_sec' then -- item.name doesn't work!
domoticz.devices('Test1').switchOff()
elseif item.isCustomEvent and item.name == 'delay_2_sec' then -- item.name doesn't work!
domoticz.devices('Test2').switchOff()
else
-- do nothing
end
end
}
Code: Select all
return {
on = {
devices = {'Test1', 'Test2'},
customEvents = {'delay_x_sec',},
},
logging = {level = domoticz.LOG_INFO, marker = 'Test',},
execute = function(domoticz, item)
if item.isDevice and item.name == 'Test1' and item.state == 'On' then
domoticz.emitEvent('delay_x_sec', '1_sec').afterSec(1)
elseif item.isDevice and item.name == 'Test2' and item.state == 'On' then
domoticz.emitEvent('delay_x_sec', '2_sec').afterSec(2)
elseif item.isDevice and item.state == 'Off' then
-- do nothing
elseif item.isCustomEvent and item.data == '1_sec' then -- item.data does work!
domoticz.devices('Test1').switchOff()
elseif item.isCustomEvent and item.data == '2_sec' then -- item.data does work!
domoticz.devices('Test2').switchOff()
else
-- do nothing
end
end
}
Rpi4B,RFX433e,PiFace2, LCD, Hue bridge, Alexa (+TTS), HA-Bridge, Sonoff NSPanel, Sonoff RF (+IR) bridge, Nefit CV, Tasmota/MQTT, Enphase Solar, Smartmeter, Alarm I/F, H13726B Weather Station, CM180 Energy meter, Sonoff, KaKu, Tuya, Gledopto, AriLux,...
- waltervl
- Posts: 5734
- Joined: Monday 28 January 2019 18:48
- Target OS: Linux
- Domoticz version: 2024.7
- Location: NL
- Contact:
Re: How-to: launch action after a certain time
I never used custom events but looking at the wiki you have to use attribute .trigger for this
Eg
Eg
Code: Select all
if item.isCustomEvent and item.trigger == 'delay_1_sec' then
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
-
- Posts: 22
- Joined: Wednesday 13 January 2016 16:11
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Contact:
Re: How-to: launch action after a certain time
Hi Walter,
I've tested it and it works! This is exactly what I was looking for.
Thx...
I've tested it and it works! This is exactly what I was looking for.
Thx...
Rpi4B,RFX433e,PiFace2, LCD, Hue bridge, Alexa (+TTS), HA-Bridge, Sonoff NSPanel, Sonoff RF (+IR) bridge, Nefit CV, Tasmota/MQTT, Enphase Solar, Smartmeter, Alarm I/F, H13726B Weather Station, CM180 Energy meter, Sonoff, KaKu, Tuya, Gledopto, AriLux,...
-
- Posts: 748
- Joined: Saturday 27 February 2016 12:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2020.2
- Location: NL
- Contact:
Re: How-to: launch action after a certain time
What if someone opens the hot water tap for 25 seconds? And again, and again? Eventually it would leave the boiler cold!
I know it may sound unlikely, but you should code for the worst...
I know it may sound unlikely, but you should code for the worst...
Hans
-
- Posts: 22
- Joined: Wednesday 13 January 2016 16:11
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Contact:
Re: How-to: launch action after a certain time
Good point,
I found a thread about that, see viewtopic.php?t=33002
Unfortunately dz.emitEvent('myEvent').cancelQueuedCommands() doesn't work but it describes some work-around solutions.
I found a thread about that, see viewtopic.php?t=33002
Unfortunately dz.emitEvent('myEvent').cancelQueuedCommands() doesn't work but it describes some work-around solutions.
Rpi4B,RFX433e,PiFace2, LCD, Hue bridge, Alexa (+TTS), HA-Bridge, Sonoff NSPanel, Sonoff RF (+IR) bridge, Nefit CV, Tasmota/MQTT, Enphase Solar, Smartmeter, Alarm I/F, H13726B Weather Station, CM180 Energy meter, Sonoff, KaKu, Tuya, Gledopto, AriLux,...
Who is online
Users browsing this forum: No registered users and 1 guest