Generic auto-off

Post Reply
rrozema
Posts: 124
Joined: Thursday 26 October 2017 13:37
Target OS: Raspberry Pi
Domoticz version: beta
Location: Delft
Contact:

Generic auto-off

Post by rrozema » Monday 04 June 2018 14:33

In my house I have multiple switches that are either manually or automatically by some mechanism switched on and that I want to switch off after some time. Initially I had a separate script for each such device. But the amount of scripts kept on growing and it was not very clear anymore which script controlled what switch and when I wanted to change a setting change or a add switch I had to go into the scripts and alter them. Rather tedious and error prone. So came up with a generic solution to specify per device if it was to switched off automatically and if so, after how much time. Once I had this working I added the possibility to delay switching the light off for as long as someone is still in the room, as detected by a motion detector (a PIR). I wanted my switches to be easy configurable, and I don't think having to go into a script and add, update or remove devices names or even index values is very easy. So I wrote a single script that is executed once a minute and checks all devices to see if it needs to be switched off. This script reads for each device a setting, stored in the devices' description field, to see what to do for this device. If a device's description does not contain the values, that device is not switched off automatically. If it contains only an "auto_off_minutes" value, the device will be switched off if its state = 'On' and its LastUpdate is older than the number of minutes specified in the value. If it contains also a value for "auto_off_motion_device" and the switch is on for at least the "auto_off_minutes" value, the motion device by the name specified is interrogated to see if is currently off and its last update is more than the amount in auto_off_minutes old. If the motion is indeed off with lastupdate being old, the switch is switched off. If the motion device is On or lastUpdate is less than auto_off_minutes old, there must still be someone in the room and the switch is not switched off.

Here's an example of what to put in a device's description field to make it switch off automatically after two minutes:

Code: Select all

{
"auto_off_minutes": 2
}
And here's an example of how to make a switch go off 1 minute after the last person has left the room:

Code: Select all

{
"auto_off_minutes": 1,
"auto_off_motion_device": "Overloop 1: Motion"
}
device.JPG
device.JPG (73.36 KiB) Viewed 592 times
If I want to make a new switch go off automatically, I don't need to go into my scripts any more, I simply enter the proper values in the device's description field and it will use the new settings.

Here's the script I wrote for this. It is not completely correct yet. I haven't been able to make the error catching work correctly. So as long as you have no invalid values in your devices' description fields it will work for you too. If however there is a device with a description that is not in json format, the script will break. If anyone can tell me how to properly use pcall() to catch the error, I will be very thankful.

Code: Select all

-- This script will run every minute and can automatically send an 'Off' command to turn off any device after
-- it has been on for some specified time. Each device can be individually configured by putting json coded 
-- settings into the device's description field. The settings currently supported are:
-- - "auto_off_minutes" : <time in minutes>
-- - "auto_off_motion_device" : "<name of a motion detection device>"
-- If "auto_off_minutes" is not set, the device will never be turned off by this script. If 
-- "auto_off_minutes" is set and <time in minutes> is a valid number, the device will be turned off when it 
-- is found to be on plus the device's lastUpdate is at least <time in minutes> minutes old. This behavior 
-- can be further modified by specifying a valid device name after "auto_off_motion_device". When a motion 
-- device is specified and the device's lastUpdate is at least <time in minutes> old, the device will not 
-- be turned off until the motion device is off and it's lastUpdate is also <time in minutes> old. 
-- Specifying "auto_off_motion_device" without specifying "auto_off_minutes" does nothing.
--
-- Example 1: turn off the device after 2 minutes:
-- {
-- "auto_off_minutes": 2
-- }
--
-- Example 2: turn off the device when it has been on for 5 minutes and no motion has been detected for 
-- at least 5 minutes:
-- {
-- "auto_off_minutes": 5,
-- "auto_off_motion_device": "Overloop: Motion"
-- }

return {
	on = {

		-- timer triggers
		timer = {
			'every minute'
		}
	},

	execute = function(domoticz, triggeredItem, info)

		domoticz.devices().forEach(
	        function(device)
	            if device.state ~= 'Off' then
	                --domoticz.log( 'device is on ' .. device.name .. '.', domoticz.LOG_INFO)
    	            local description = device.description
    	            if description ~= nil and description ~= '' then
    	                --domoticz.log( 'description = ' .. description .. '.', domoticz.LOG_INFO)
    	                local ok, settings = pcall( domoticz.utils.fromJSON, description)
    	                if ok then
    	                    if settings ~= nil and settings.auto_off_minutes ~= nil and device.lastUpdate.minutesAgo >= settings.auto_off_minutes then
	                            if settings.auto_off_motion_device == nil then
            		                domoticz.log(device.name .. ' is switched off because it has been on for ' .. settings.auto_off_minutes .. ' minutes.', domoticz.LOG_INFO)
	                                device.switchOff()
	                            else
                                    local motion_device = domoticz.devices(settings.auto_off_motion_device)
                                    if motion_device.state == 'Off' and motion_device.lastUpdate.minutesAgo >= settings.auto_off_minutes then
                		                domoticz.log(device.name .. ' is switched off because no one was in the room for ' .. settings.auto_off_minutes .. ' minutes.', domoticz.LOG_INFO)
    	                                device.switchOff()
                                    end
	                            end
                            end 
                        else
                            domoticz.log( 'Device description for '.. device.name ..' is not in json format. Ignoring this device.', domoticz.LOG_ERROR)
                        end
                    end
                end
            end
        )
    end
}

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest