Page 1 of 1
Sensor update triggers script
Posted: Monday 09 March 2020 18:25
by jkimmel
I'm running scripts to control my heating system.
My scripts start with
Code: Select all
return {
on = {
['timer'] = {
'every 10 minutes',
},
devices = {
TEMPERATURE_SENSOR,
SETPOINT_DEVICE
}
},
So every time the sensor is updated the script will be triggered.
How to trigger the script only when the value of the sensor has changed?
Re: Sensor update triggers script
Posted: Monday 09 March 2020 20:35
by freijn
@Waaren H E L P me
I am getting close but can't get to the working one.....
Code: Select all
return {
on = {
devices = { 'TEMPERATURE_SENSOR',
},
},
data = {
TEMPERATURE_level = { initial = 0 }
},
logging = {
level = domoticz.LOG_DEBUG,
marker = "Temp Value"
},
execute = function(dz, item)
if item.name == 'TEMPERATURE_SENSOR' and item.value ~= dz.data.TEMPERATURE_level then
dz.notify('Temp level changed','Temp changed!')
dz.data.TEMPERATURE_level = item.value
end
end
}
Re: Sensor update triggers script
Posted: Monday 09 March 2020 21:23
by waaren
jkimmel wrote: Monday 09 March 2020 18:25
I'm running scripts to control my heating system.
How to trigger the script only when the value of the sensor has changed?
You will need to do some administration of the device-state in the script.
Code: Select all
local TEMPERATURE_SENSOR = 130
local SETPOINT_DEVICE = 131
return
{
on =
{
devices =
{
TEMPERATURE_SENSOR,
SETPOINT_DEVICE,
},
},
logging =
{
level = domoticz.LOG_DEBUG, -- set to LOG_ERROR when tested and OK
marker = 'setSetpoint',
},
data =
{
myHistory =
{
initial = {},
},
},
execute = function(dz, item)
if dz.data.myHistory[item.name] ~= nil and dz.data.myHistory[item.name].nValue == item.nValue and dz.data.myHistory[item.name].sValue == item.sValue then
dz.log('no action required',dz.LOG_DEBUG)
return
end
dz.data.myHistory[item.name] = {}
dz.data.myHistory[item.name].nValue = item.nValue
dz.data.myHistory[item.name].sValue = item.sValue
-- Rest of script
dz.log('Action required',dz.LOG_DEBUG)
end
}
Re: Sensor update triggers script
Posted: Tuesday 10 March 2020 11:14
by jkimmel
I'm using dannybloe's script for heating control, merely by copy and paste and not always understanding how it may work.
Now thinking of reducing triggering the scripts and getting your response I looked again into my script.
Here is the sector which I think should already run the script to its end only if sensor value or setpoint changes.
It is about reducing writes on the sdcard.
Code: Select all
if (triggerInfo.type == domoticz.EVENT_TYPE_DEVICE) then
if (sensor.changed) then
-- sensor just reported a new reading
-- add it to the readings table
if (current ~= 0 and current ~= nil) then
temperatureReadings.add(current)
else
-- no need to be here, weird state detected
domoticz.log('Strange sensor reading.. skiping', domoticz.LOG_ERROR)
return
end
elseif (domoticz.devices(SETPOINT_DEVICE).changed) then
-- a new setpoint was set
if LOGGING then domoticz.log('Setpoint was set to ' .. device.state) end
else
-- no business here, bail out...
return
end
Do I miss something?
Re: Sensor update triggers script
Posted: Tuesday 10 March 2020 12:23
by waaren
jkimmel wrote: Tuesday 10 March 2020 11:14
I'm using dannybloe's script for heating control, merely by copy and paste and not always understanding how it may work.
Now thinking of reducing triggering the scripts and getting your response I looked again into my script.
Do I miss something?
The script you are using is from the early days of dzVents. If you share the complete script I can have a go of merging it with the example.
Also have a look at the wiki and search for changed. You will read under Device attributes:
changed: Boolean. True if the device was updated. Note: This does not necessarily means the device state or value changed.
Re: Sensor update triggers script
Posted: Tuesday 10 March 2020 15:50
by jkimmel
Thank you for your fast response. Here my complete script:
- Spoiler: show
Code: Select all
-- assumptions:
-- the setpoint is set by a selector dummy device where the values are numeric temperatures
-- but you can easily change it to a setpoint device
local BOILER_DEVICE = 'FB 21 Heizkreis Salon' -- switch device
local SETPOINT_DEVICE = 'Solltemperatur Salon' -- selector dummy device
local TEMPERATURE_SENSOR = 'Salon Temperatur'
local CHANGE_DEVICE = 'Modus Waermepumpe' -- selector dummy device
local HYSTERESIS = 0.5 -- temp has to drop this value below setpoint before boiler is on again
local HEATPUMP_RETURN = 'WP Ruecklauf' -- controls dewpoint of walls
local SMOOTH_FACTOR = 3
local LOGGING = true
return {
on = {
['timer'] = {
'every 10 minutes',
},
devices = {
TEMPERATURE_SENSOR,
SETPOINT_DEVICE
}
},
data = {
temperatureReadings = { history = true, maxItems = SMOOTH_FACTOR }
},
active = true,
execute = function(domoticz, device, triggerInfo)
local avgTemp
local temperatureReadings = domoticz.data.temperatureReadings
local sensor = domoticz.devices(TEMPERATURE_SENSOR)
local current = sensor.temperature
local boiler = domoticz.devices(BOILER_DEVICE)
local setpoint = domoticz.devices(SETPOINT_DEVICE)
-- first check if the sensor got a new reading or the setpoint was changed:
if (triggerInfo.type == domoticz.EVENT_TYPE_DEVICE) then
if (sensor.changed) then
-- sensor just reported a new reading
-- add it to the readings table
if (current ~= 0 and current ~= nil) then
temperatureReadings.add(current)
else
-- no need to be here, weird state detected
domoticz.log('Strange sensor reading.. skiping', domoticz.LOG_ERROR)
return
end
elseif (domoticz.devices(SETPOINT_DEVICE).changed) then
-- a new setpoint was set
if LOGGING then domoticz.log('Setpoint was set to ' .. device.state) end
else
-- no business here, bail out...
return
end
end
-- now determine what to do
if (setpoint.state == nil or setpoint.state == 'Off') then
boiler.switchOff()
return -- we're done here
end
local setpointValue = tonumber(setpoint.state)
-- determine at which temperature the boiler should be
-- switched on
local switchOnTemp = setpointValue - HYSTERESIS
-- don't use the current reading but average it out over
-- the past <SMOOTH_FACTOR> readings (data smoothing) to get rid of noise, wrong readings etc
local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR, current) -- fallback to current when history is empty
if LOGGING then
domoticz.log('Average: ' .. avgTemp, domoticz.LOG_INFO)
domoticz.log('Setpoint: ' .. setpointValue, domoticz.LOG_INFO)
domoticz.log('Current boiler state: ' .. boiler.state, domoticz.LOG_INFO)
domoticz.log('Switch-on temperature: ' .. switchOnTemp, domoticz.LOG_INFO)
end
if (avgTemp >= setpointValue and boiler.state == 'On') then
if LOGGING then domoticz.log('Target temperature reached, boiler off') end
boiler.switchOff()
end
if (avgTemp < setpointValue and boiler.state == 'Off') then
if (avgTemp < switchOnTemp) then
if LOGGING then domoticz.log('Heating is required, boiler switched on') end
boiler.switchOn()
else
if LOGGING then domoticz.log('Average temperature below setpoint but within hysteresis range, waiting for temperature to drop to ' .. switchOnTemp) end
end
end
end
}
Re: Sensor update triggers script [Solved]
Posted: Tuesday 10 March 2020 17:15
by waaren
jkimmel wrote: Tuesday 10 March 2020 15:50
Thank you for your fast response. Here my complete script:
This script relies on the new readings even if they are equal to the previous one. It does not make sense to ignore these reading. The smoothing and hysteresis will not work as designed if you do that.