Sensor update triggers script  [Solved]

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

Moderator: leecollings

Post Reply
jkimmel
Posts: 129
Joined: Monday 25 November 2013 17:51
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Mallorca
Contact:

Sensor update triggers script

Post 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?
Rfxcom
Raspi 4
freijn
Posts: 536
Joined: Friday 23 December 2016 16:40
Target OS: Raspberry Pi / ODroid
Domoticz version: Stable
Location: Netherlands Purmerend
Contact:

Re: Sensor update triggers script

Post 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
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Sensor update triggers script

Post 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
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
jkimmel
Posts: 129
Joined: Monday 25 November 2013 17:51
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Mallorca
Contact:

Re: Sensor update triggers script

Post 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?
Rfxcom
Raspi 4
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Sensor update triggers script

Post 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.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
jkimmel
Posts: 129
Joined: Monday 25 November 2013 17:51
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Mallorca
Contact:

Re: Sensor update triggers script

Post 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
}
Rfxcom
Raspi 4
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Sensor update triggers script  [Solved]

Post 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.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest