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.
How-to: launch action after a certain time [SOLVED]
Moderator: leecollings
-
- Posts: 621
- 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: 108
- 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: 621
- 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: 108
- 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: 108
- 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: 621
- 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().
Who is online
Users browsing this forum: No registered users and 1 guest