Is the washing machine done?

Moderator: leecollings

User avatar
felix63
Posts: 244
Joined: Monday 07 December 2015 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.1
Location: Gouda
Contact:

Re: Is the washing machine done?

Post by felix63 »

I see my Raspberry is running 5 - 10% CPU load with peak unto 17%. But I don't know if that is due to this script.

I have include an optimalisation to the script adding a counter for keeping track of the number of active devices so to be able to skip the timer bit of the code if there are no active devices. Not thorough testing done yet 8-)
Spoiler: show

Code: Select all

 -- create a lookup table that matches a usage
 -- device to the accompanying switch
 local USAGE_DEVICES = {
 	['SC-Wasdroger verbruik'] = 'Wasdroger',	-- You need to have a inline wall plug that measures energy,
 	['SC-Wasmachine verbruik'] = 'Wasmachine',  -- here you make the link between the energy device and the wall plug.
 }

 local USAGE_SwitchTimeOutMinutes = {
 	['Wasdroger'] = 6,							-- Here you define how long no power is used per device.
 	['Wasmachine'] = 6,							-- The period is in minutes. Adjust to your needs. Between every add a ",".
 }

 local USAGE_MaxWatt = {
 	['Wasdroger'] = 3,							-- Here you define the maximum amount of power a device uses when it is in standby.
 	['Wasmachine'] = 3,							-- Some devices uses a little amount of power. Test it and a slightly higher usage.
 }

 local USAGE_Notify = {
 	['Wasdroger'] = 'Yes',						-- In some cases you want to be notified when a device is turned on and off.
 	['Wasmachine'] = 'Yes',						-- Adjust to your needs. Between every line you need to add a ",".
 }

 return {
 	logging = {
-- 		level = domoticz.LOG_INFO, 				-- Uncomment to override the dzVents global logging setting
-- 		marker = 'POW'
 	},

 	on = {
		timer = { 'every 5 minutes' },
 		devices = {								-- Make sure that the devices are the same as above
 			'SC-Wasdroger verbruik',
 			'SC-Wasmachine verbruik',
 		},
 	},
 	data = { 									-- use exact device names to match USAGE_DEVICES
        ['CountDevices'] = {initial=0},
 		['SC-Wasdroger verbruik'] = { history = true, maxMinutes = 10 },
 		['SC-Wasmachine verbruik'] = { history = true, maxMinutes = 10 }
 	},

 	execute = function(domoticz, device)
         if (device.isTimer) then
		 	if domoticz.data['CountDevices'] > 0) then
 			-- we need to check for expiration of grace period
 			domoticz.log("timer trigger")
 			for i, machine in pairs(USAGE_DEVICES) do
				local usage = "SC-" .. machine.. " verbruik"
 				domoticz.log("device = " .. machine)
 				local actual = domoticz.devices(usage).WhActual
 				local average = domoticz.data[usage].avg()
                domoticz.data[usage].add(actual)
 				domoticz.log("actual = " .. actual)
				domoticz.log("average = " .. tostring(average))
				if actual == 0 then
					domoticz.log(machine .. " gebruikt geen energie, dus is uit")
					domoticz.devices(machine).switchOff().checkFirst()
				elseif actual < USAGE_MaxWatt[machine] then
					domoticz.log(machine .. " gebruikt weinig energie, is de machine klaar?")
					local timeout = USAGE_SwitchTimeOutMinutes[machine]
					domoticz.log(machine .. " gebruikte gemiddeld: " .. tostring(domoticz.data[usage].avg))
					if (average <= USAGE_MaxWatt[machine]) then
						domoticz.log(machine .. " lijkt standby te staan, we nemen aan klaar.")
						domoticz.devices(machine).switchOff().checkFirst()
					    domoticz.data[usage].reset()
					else
						domoticz.log(machine .. " maar nog te kort om klaar te zijn.")
						domoticz.devices(machine).switchOn().checkFirst()
					end
				else 
					domoticz.log(machine .. " gebruikt energie, dus is (nog) bezig.")
					domoticz.devices(machine).switchOn().checkFirst()
				end
 			end
			end
 		elseif (USAGE_DEVICES[device.name] ~= nil) then
 			-- we have a usage sensor here
 			domoticz.log("usage trigger")
 			local switch = domoticz.devices(USAGE_DEVICES[device.name])
 			local timeout = USAGE_SwitchTimeOutMinutes[USAGE_DEVICES[device.name]]
 			local watt = USAGE_MaxWatt[USAGE_DEVICES[device.name]]
 			domoticz.data[device.name].add(device.WhActual)
 			local history = domoticz.data[device.name]
 			domoticz.log("device = " .. device.name)
 			if (switch.active) then
				domoticz.log("Switch is active, check average use and last update")
				domoticz.log("usage last update: " .. tostring(switch.lastUpdate.minutesAgo))
  			    domoticz.log("usage = " .. tostring(device.WhActual))
				domoticz.log("average = " .. tostring(history.avg()))
				if (history.avg() <= watt and device.WhActual <= watt and switch.lastUpdate.minutesAgo >= timeout) then
    			 	switch.switchOff().checkFirst()
					domoticz.log("Turn switch off")
    			    if domoticz.data['CountDevices'] > 0 then
						domoticz.data['CountDevices'] = domoticz.data['CountDevices'] - 1
					end
					domoticz.data[device.name].reset()
     			end
             else
				domoticz.log("Switch not on")
                 if (device.WhActual > watt) then
					domoticz.log("but power use is over treshold, turn switch on")
    			    domoticz.data['CountDevices'] = domoticz.data['CountDevices'] + 1
 	                switch.switchOn().checkFirst()
 	            end
 		    end
 		end
 	end
 }
akamming
Posts: 337
Joined: Friday 17 August 2018 14:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by akamming »

Thank you very much for this script.

i added some features for my situation, so posting my changed version back to this forum is my way of saying thank you to the original authors!

My additional needs were :
- The energy consumption of the Miele washing machine during the program is very low, it almost matches the pattern which is present after the finishing of some other washing programs (like 'kreukherstellend', sorry i do not know the english translation). this lead to wrong conclusions in the script and/or too notifications (resulting in an unhappy wife :oops: ) depending on how i set the paramets, but i could not get it to work. So i decided in my case the only generic way to detect if a the machine was finished its program is by checking the average. Since this also works for the other appliances, i removed the other detection method in the code
- i do not like to have too many virtual devices, so i wanted to user persistent vars instead.
- for tweaking the parameters to detect if a device is ready, i needed a logline which can be imported in Excel.

So i adapted the script to these needs, and now it works like a charm also in my situation (without the need of creating extra virtual devices in domoticz)

many thanks to the original authors of the code and keep up the good work!

Code: Select all

 
 -- create a lookup table that matches a usage
 -- device to the accompanying switch persistent variable
 local USAGE_DEVICES = {
 	['SC-Wasdroger verbruik'] = 'Wasdroger',		-- You need to have a inline wall plug that measures energy,
    ['SC-Wasmachine verbruik'] = 'Wasmachine',  	-- here you make the link between the energy device and the wall plug.
 	['SC-Vloerverwarming verbruik'] = 'Vloerverwarming',
 }

 local USAGE_SwitchTimeOutMinutes = {
 	['Wasdroger'] = 5,						-- Timeout after switching to prevent a lot of notifications when the situation is a little bit grey.
 	['Wasmachine'] = 5,	                    --
 	['Vloerverwarming'] = 1,
 }

 local USAGE_MaxWatt = {
 	['Wasdroger'] = 75,						-- Here you define the maximum amount of power a device uses when it is in standby.
 	['Wasmachine'] = 20,						-- Some devices uses a little amount of power. Test it and a slightly higher usage.
 	['Vloerverwarming'] = 5,
 }
 
  local USAGE_Notify = {
 	['Wasdroger'] = true,						-- In some cases you want to be notified when a device is turned on and off.
 	['Wasmachine'] = true,					-- Adjust to your needs. Between every line you need to add a ",".
 	['Vloerverwarming'] = true,
 }

 return {
 	logging = {
 		level = domoticz.LOG_DEBUG, 			-- Adjust to your needs
 		marker = 'AppliancesNotification-3'
 	},

 	on = {
		timer = { 'every minute' },
 		devices = { 
 		    'SC-Wasdroger verbruik', 
 		    'SC-Wasmachine verbruik'
 		} 
 	},
 	data = { 								-- use exact device names to match USAGE_DEVICES
 		['SC-Wasdroger verbruik'] = { history = true, maxMinutes = 3 },   -- persistent vars to record device history
 		['SC-Wasmachine verbruik'] = { history = true, maxMinutes = 5, maxItems = 300 }, -- choose maxMinutes as the time the average should be above maxwatt to indicate a running  appliance
 		['SC-Vloerverwarming verbruik'] = { history = true, maxMinutes = 1 },

 		['Wasdroger'] = { initial = false },    -- persistent var to store virtual switch
 		['Wasmachine'] = { initial = false },    -- use exact names to match USAGE_DEVICES
 		['Vloerverwarming'] = { initial = false },    

 		['Wasdroger LastUpdate'] = { initial = "2018-09-01 09:35:05" },    -- persistent var to store last update of virtual switch
 		['Wasmachine LastUpdate'] = { initial = "2018-09-01 09:35:05" },    -- use exact names to match USAGE_DEVICES, with " LastUpdate" added to the varname
 		['Vloerverwarming LastUpdate'] = { initial = "2018-09-01 09:35:05" },     -- timestamp should just be any timestamp in the past
 	},

 	execute = function(domoticz, item)
         -- Create Time Object
         local Time = require('Time')
         
         -- function to retrieve timestamp of lastupdate
         function GetLastUpdate(device)
             Timestring=domoticz.data[USAGE_DEVICES[device.name].." LastUpdate"]
             return Time(Timestring)  
         end
         
         -- flip the switch
         function SetSwitch(device,value)
            -- Set Switch value
         	domoticz.data[USAGE_DEVICES[device.name]]=value

         	-- Set Switch Timestamp
         	domoticz.data[USAGE_DEVICES[device.name].." LastUpdate"]=Time().raw
         	
         	-- for debuggin purposes
          	domoticz.log("Switch "..USAGE_DEVICES[device.name].." was put to "..tostring(domoticz.data[USAGE_DEVICES[device.name]]).." on "..GetLastUpdate(device).raw)
          	
          	-- Check if we have to notify
          	if (USAGE_Notify[USAGE_DEVICES[device.name]]) then
          	    if (value) then
          	        NotificatonMessage='De '..USAGE_DEVICES[device.name].." is aan"
      	        else
          	        NotificatonMessage='De '..USAGE_DEVICES[device.name].." is klaar"
  	            end
          	    domoticz.notify(USAGE_DEVICES[device.name],NotificatonMessage,domoticz.PRIORITY_HIGH)
          	    domoticz.log("Notification sent: "..NotificatonMessage)
      	    end
         end

 	    
 	    -- check values of 1 device and act on it if needed
 	     function CheckAppliance(device)
 			domoticz.log("Checking device " .. device.name)

 	        -- retrieve the needed data
			local timeout = USAGE_SwitchTimeOutMinutes[USAGE_DEVICES[device.name]]
 			local watt = USAGE_MaxWatt[USAGE_DEVICES[device.name]]
 			domoticz.data[device.name].add(device.WhActual)
 			local history = domoticz.data[device.name]
 			local UpdateTime = GetLastUpdate(device)
 			
			-- for debugging purposes
			domoticz.log("switch last update in minutes: " .. tostring(UpdateTime.minutesAgo))
  		    domoticz.log("usage = " .. tostring(device.WhActual))
			domoticz.log("average = " .. tostring(history.avg()))
			domoticz.log("timeout = "..timeout)
			domoticz.log("MaxWatt = "..watt)
			
			-- for analysing the log to finetune the parameters of the appliances: Log a line which can be imported in excel
			domoticz.log("Import:"..device.name..";"..tostring(UpdateTime.minutesAgo)..";"..tostring(device.WhActual)..";"..tostring(history.avg())..";"..timeout..";"..watt)

            -- analyse the values and perform actions if needed
    		if (domoticz.data[USAGE_DEVICES[device.name]]) then
				if (history.avg() <= watt and device.WhActual <= watt and UpdateTime.minutesAgo >= timeout) then
					domoticz.log("average power use is under treshold, turning switch off")
					SetSwitch(device,false)
				else 
				    domoticz.log("actual or average power use is above treshold or timeout still active, leave switch on")
     			end
             else
                 if (history.avg() >watt and device.WhActual >watt and UpdateTime.minutesAgo >= timeout) then
					domoticz.log("average power use is above treshold, turning switch on")
					SetSwitch(device,true)
                 else
                    domoticz.log("actual or average power use is under treshold or timeout still active, leave switch off")
 	            end
 		    end
 	    end
 	
 	    -- it the trigger was the timer, all devices should be triggered
 	    if (item.isTimer) then
 			domoticz.log("timer trigger, Check all devices")
     	    -- loop through appliances 
     	    for i, machine in pairs(USAGE_DEVICES) do
     			CheckAppliance(domoticz.devices(i))
     			domoticz.log("---------------------------------------------------------------------")
            end
        end
    
        -- it the triggered was a device: Check this device
 	    if (item.isDevice) then
 			domoticz.log("device trigger, Check updated device")
 	        CheckAppliance(item)
        end
 	end
 }
mcmikev
Posts: 146
Joined: Tuesday 26 May 2015 8:11
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: right here
Contact:

Re: Is the washing machine done?

Post by mcmikev »

Thanks for your updated script.

I too have/had false "Vaatwasser klaar, of wasmachine klaar" notifications. So I want to try this version.

Can you tell me what vars you need and what type those are ? (String, Integer, date or time?)

Hope you are willing to explain!!
akamming
Posts: 337
Joined: Friday 17 August 2018 14:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by akamming »

mcmikev wrote: Saturday 08 September 2018 12:25 Thanks for your updated script.

I too have/had false "Vaatwasser klaar, of wasmachine klaar" notifications. So I want to try this version.

Can you tell me what vars you need and what type those are ? (String, Integer, date or time?)

Hope you are willing to explain!!

I don't fully understand your question. The persistent vars are declared in the "date = { } " section. So you have to put your 'vaatwasser' and 'wasmachine' there as well. you do not have to specify the type. if you have a bit of scripting skills (like me, i am not an experienced programmer) and follow the comments you should be able to make it work.
User avatar
felix63
Posts: 244
Joined: Monday 07 December 2015 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.1
Location: Gouda
Contact:

Re: Is the washing machine done?

Post by felix63 »

akamming wrote: Saturday 08 September 2018 11:47 - i do not like to have too many virtual devices, so i wanted to user persistent vars instead.
The reason I created virtual devices in this instance was because I like to attach notifications to a switch using the Domoticz standard notifications. This way the notifications are separate from the scripting and more easily maintainable. I know it's a a quirk...
akamming
Posts: 337
Joined: Friday 17 August 2018 14:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by akamming »

felix63 wrote: Saturday 08 September 2018 15:42 The reason I created virtual devices in this instance was because I like to attach notifications to a switch using the Domoticz standard notifications. This way the notifications are separate from the scripting and more easily maintainable. I know it's a a quirk...
I understand your point. My problem is that using virtual switch in the ui i get a device which i can switch on or off which should not be possible and therefore is confusing.

On the other hand i am very new to this scripting and domoticz, so maybe i miss something. Would it be possible to create a switch (or even better: a status indicator) which does display the state of the appliance, but cannot be overruled in the user interface of domoticz...
User avatar
felix63
Posts: 244
Joined: Monday 07 December 2015 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.1
Location: Gouda
Contact:

Re: Is the washing machine done?

Post by felix63 »

That's very simple. You can 'protect' switches. Meaning that the value can not be changed by either the user or by json calls. When you go to the tab with the device and click on the gear icon to edit the properties you can click 'protect'. Then you can no longer 'accidentally' change it because you are asked for a password.
akamming
Posts: 337
Joined: Friday 17 August 2018 14:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by akamming »

Nice... i will try it. Currently not in a hurry.. i have a working script now :)
madvisionz
Posts: 12
Joined: Tuesday 25 September 2018 12:38
Target OS: NAS (Synology & others)
Domoticz version: 4.10327
Contact:

Re: Is the washing machine done?

Post by madvisionz »

Added this script into my Domoticz and shortly after that I received two telegram notifications that both washingmachine and dryer are turned on.
My wife confirmed that see did turned on both devices indeed. :D Nice!

Another question.. Is it possible to add a second person to receive notifications on certain events? This was not needed until this moment. ;)
My wife wants to see the washing and dryer notifications as well (duh).
User avatar
felix63
Posts: 244
Joined: Monday 07 December 2015 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.1
Location: Gouda
Contact:

Re: Is the washing machine done?

Post by felix63 »

You can if you use Telegram for notifications. In Telegram you can create groups that multiple people can subscribe to.

Cheers,
Lex
renerene
Posts: 316
Joined: Wednesday 03 August 2016 11:36
Target OS: -
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by renerene »

I don't like the idea of buying a powersocket, just for notification purposes. I am thinking about writing a simular script which monitors typical powerpeeks in total house usage of P1 meter. Less accurate offcourse, but we'll see if that works.
Anybody experience with this?
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Is the washing machine done?

Post by emme »

I did....
then I spend some money to grab a socket plug with power metering function :lol: :lol:

Spikes in total usage cannot be referred to any device....
I have a 5.5kW contract so I can handle washing machine and dishwashing machine at the same time....
OR... induction hob and washing machine...

seeing the total consumption how could you determinate when I've finish cooking rather then washing? :P :P
The most dangerous phrase in any language is:
"We always done this way"
madvisionz
Posts: 12
Joined: Tuesday 25 September 2018 12:38
Target OS: NAS (Synology & others)
Domoticz version: 4.10327
Contact:

Re: Is the washing machine done?

Post by madvisionz »

felix63 wrote: Wednesday 09 January 2019 19:24 You can if you use Telegram for notifications. In Telegram you can create groups that multiple people can subscribe to.

Cheers,
Lex
Sounds good, but I use Telegram notifications for several things and want to add a second person for only your script notifications for now.
I don't want to bother my wife with the other notifications which are not relevant for her.. ;)
If it's possible to add more accounts and configure notifications for each account then I will try that.
User avatar
felix63
Posts: 244
Joined: Monday 07 December 2015 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.1
Location: Gouda
Contact:

Re: Is the washing machine done?

Post by felix63 »

In my setup I use two separate Telegram accounts. One is a Group account with messages for all the family members. The other account is used for 'service messages' intended for system maintenance. This second account is used not via Domoticz notification but directly by using curl or alternatively using the custom notification option.
renerene
Posts: 316
Joined: Wednesday 03 August 2016 11:36
Target OS: -
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by renerene »

seeing the total consumption how could you determinate when I've finish cooking rather then washing? :P :P
I am gonna give it a go anyway. See if can recognise duration and power increase. If too many devices switch on at the same time it will be hard to analyse, you are right.
But hey, doesn't need to be 100% correct. Just for fun.
billie77
Posts: 1
Joined: Sunday 11 March 2018 17:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by billie77 »

Script works well. Wife happy too :lol:

Thanks Felix63
Squeaken
Posts: 2
Joined: Tuesday 23 July 2019 17:10
Target OS: Linux
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by Squeaken »

Hi

I´ve tried the supplied script but I get this error in the logfile.

Error: EventSystem: Lua script script_time_washingmachine did not return a commandArray

Any ideas why?
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Is the washing machine done?

Post by waaren »

Squeaken wrote: Tuesday 23 July 2019 17:14 I get this error in the logfile. Error: EventSystem: Lua script script_time_washingmachine did not return a commandArray. Any ideas why?
Yes. You saved it as a type Lua script but you should save it as a type dzVents
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Squeaken
Posts: 2
Joined: Tuesday 23 July 2019 17:10
Target OS: Linux
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by Squeaken »

waaren wrote: Tuesday 23 July 2019 18:10
Squeaken wrote: Tuesday 23 July 2019 17:14 I get this error in the logfile. Error: EventSystem: Lua script script_time_washingmachine did not return a commandArray. Any ideas why?
Yes. You saved it as a type Lua script but you should save it as a type dzVents
I changed it to dzVents and it worked like a charm, thanks.
jaaap
Posts: 59
Joined: Sunday 28 July 2019 22:59
Target OS: NAS (Synology & others)
Domoticz version:
Contact:

Re: Is the washing machine done?

Post by jaaap »

Hi all, and first of all: thank you for this script!

I run into a little problem: it seems that some of the data is not properly imported. I get the following log:

Code: Select all

2019-09-26 19:19:11.878 Status: dzVents: Info: Handling events for: "SC-Wasmachine verbruik", value: "24.58"
2019-09-26 19:19:11.878 Status: dzVents: Info: POW: ------ Start internal script: is de was klaar 2: Device: "SC-Wasmachine verbruik (hs110)", Index: 46
2019-09-26 19:19:11.879 Status: dzVents: Info: POW: usage trigger
2019-09-26 19:19:11.880 Status: dzVents: Info: POW: device = SC-Wasmachine verbruik
2019-09-26 19:19:11.880 Status: dzVents: Info: POW: Switch is active, check average use and last update
2019-09-26 19:19:11.880 Status: dzVents: Info: POW: usage last update: 8
2019-09-26 19:19:11.880 Status: dzVents: Info: POW: usage = nil
2019-09-26 19:19:11.880 Status: dzVents: Error (2.4.19): POW: Item data is not a number type. Type is nil
2019-09-26 19:19:11.880 Status: dzVents: Error (2.4.19): POW: An error occured when calling event handler is de was klaar 2
2019-09-26 19:19:11.880 Status: dzVents: Error (2.4.19): POW: /usr/local/domoticz/dzVents/runtime/HistoricalStorage.lua:289: attempt to perform arithmetic on local 'sum' (a nil value)
2019-09-26 19:19:11.880 Status: dzVents: Info: POW: ------ Finished is de was klaar 2
I think what happens here is that the usage is not reported as a number, but as a string. I use a TPlink hs110 smart socket.

Do any of you have an idea how to fix this?


EDIT: I love it when I fix it myself :lol:

It turns out that if you use the plugin for the TP link hs110 (https://github.com/dahallgren/domoticz- ... /plugin.py), which I highly recommend, the sensor created for the power usage is not a power sensor, but some custom sensor that doesn't record Watt in a number but in a string. In order to get a proper power sensor (which reports Watt in numbers, so this scripts can actually do some calculations) you should change line 73 to:

Code: Select all

            Domoticz.Device(Name="emeter power (W)", Unit=4, Type=243, Subtype=29, Image=1, Used=1).Create()
Safe the plugin.py file, restart domoticz, add the hardware, rename devices (to SC-Wasmachine etc) and voila!

Big thank you to all who post on this forum, all of you who create these brilliant scripts, and all those who test it out and comment!!
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest