Help with smart switching

Moderator: leecollings

Post Reply
TyzzyT
Posts: 32
Joined: Saturday 11 March 2017 11:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.5877
Contact:

Help with smart switching

Post by TyzzyT »

Hi all,

I currently have my lights in the dressing room being switched with Blocky, but it is somehow a little limited and not really 'smart'. I hope someone can help me writing this logic in LUA.
Setup: door open sensor, pir in room, manual switch in wall on 433 MHz, switched light, IsDark sensor, 30 minute timer after waking up. I use this last timer/switch because my curtains are closed in the dressing room while I sleep and when I wake up this timer stays on for 30 minutes so I have 30 minutes to get dressed and open the curtains.

I basically want this light to be switched ON for 1 minute when the door is open, or there is activity in the room while it is dark or 30 minutes after waking up. When there is no movement detected anymore the light can go out after 1 minute.
But I also have a manual switch placed in the wall (where the old light-switch was originally). I want this switch to toggle the light. So if the light is on because of logics I can turn it off with this switch. But if the light is off because none of the logics is true, I want to turn the light on with this switch.

I hope someone is willing to help me with this.
asjmcguire
Posts: 71
Joined: Saturday 13 July 2013 2:45
Target OS: Linux
Domoticz version: 3.5877
Location: Scotland
Contact:

Re: Help with smart switching

Post by asjmcguire »

OK so start by creating 2 virtual switches.
You want one for the on for 1 minute (1 minute off delay) and one for the on for 30 minutes (30 minutes off delay)

So this is untested psuedo code:

Code: Select all

if (devicechanged['door contact'] == "Open" or devicechanged['PIR'] == "Motion") then
 if (otherdevices['isDark'] == "On") then
    if (otherdevices['LightName1'] == "On") then commandArray['LightName1']='Off' end
    commandArray['LightName30']='On'
 else
  if (otherdevices['LightName30'] == "On") then commandArray['LightName30']='Off' end
  commandArray['LightName1']='On'
 end
elseif (devicechanged['ManualLightSwitch']) then
 if (devicechanged['ManualLightSwitch']='On') then
  if (otherdevices['LightName1'] == "On") then commandArray['LightName1']='Off' end
  if (otherdevices['LightName30'] == "On") then commandArray['LightName30']='Off' end
end

if (devicechanged['LightName1'] == "On" or devicechanged['LightName30'] == "On" or devicechanged['ManualLightSwitch'] == "On") then
 commandArray['AssociatedLights']='On'
else
 commandArray['AssociatedLights']='Off'
end
Like I say it's untested - but this is roughly the way mine works anyway, but mine is in Blockly. In my case I want the door contact, motion sensor and wall switch to switch the light on for 15 minutes - but only when it's dark.

Now as to why I don't use the "On for X" commands in either Blockly or LUA - my understanding is that these commands stop the script from running again while the timer is active, whereas adding an off timer to a switch allows the switch to be activated again multiple times, which means in my case as long as people are moving and doors opening and closing then the timer on the switch is constantly getting reset to zero so the light doesn't just come on for 15 minutes and then go off until the next activation.
AEOTEC ZStick, 11 ZWave Nodes, RFXCOMM, 50ish Byron Sockets.. HE851 (PIR), 2x HE852 (DoorContact)
WS2300, CM180, CC128, 2xTHGR122NX, 2xPiZeroW w/DS18B20, 8Ch 1W Relay Board.
8 Panasonic IP Cams, 1 16ch CCTV DVR + 15 CCTV Cams
TyzzyT
Posts: 32
Joined: Saturday 11 March 2017 11:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.5877
Contact:

Re: Help with smart switching

Post by TyzzyT »

Thank you very much for your help so far, manually switching the light with the wall-switch is working. But I manually activated the 30 min timer slapen and triggered the PIR and door-sensor, but the light doens't go on. Please find my script below.

It may is worth noticing that the script did set my virtual switch 30 min timer slapen OFF when the PIR is activated.

Code: Select all

commandArray = {}
if (devicechanged['Binnendeur kleedkamer'] == "Open" or devicechanged['PIR kleedkamer'] == "On") then
 if (otherdevices['IsDonker'] == "On") then
    if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
    commandArray['30 min timer slapen']='On'
 else
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
  commandArray['1 min timer kleedkamer']='On'
 end
elseif (devicechanged['Schakelaar kleedkamer Toggle']) then
 if (devicechanged['Schakelaar kleedkamer Toggle']=='On') then
  if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
end

if (devicechanged['1 min timer kleedkamer'] == "On" or devicechanged['30 min timer slapen'] == "On" or devicechanged['Schakelaar kleedkamer Toggle'] == "On") then
 commandArray['pLamp kleedkamer']='On'
else
 commandArray['pLamp kleedkamer']='Off'
end
end
return commandArray
asjmcguire
Posts: 71
Joined: Saturday 13 July 2013 2:45
Target OS: Linux
Domoticz version: 3.5877
Location: Scotland
Contact:

Re: Help with smart switching

Post by asjmcguire »

I may be a bit off here - but this script looks to me (presumably you have it as a device script) - like because of the end of the script:

Code: Select all

if (devicechanged['1 min timer kleedkamer'] == "On" or devicechanged['30 min timer slapen'] == "On" or devicechanged['Schakelaar kleedkamer Toggle'] == "On") then
 commandArray['pLamp kleedkamer']='On'
else
 commandArray['pLamp kleedkamer']='Off'
end
end
This would have the effect that if the device that has changed is the 1 minute switch, the 30 minute switch or the toggle switch, and the device state is ON - it will turn on pLamp. However - if they send the off command (and here is the important bit - or the device that has changed state is every single device not mentioned in this script - eg a temperature sensor updating the temperature will trigger this script, and as the device that has changed is not any of those specifically mentioned - then the else statement is execute - eg - turn off pLamp.

I would also point out - there appears to be additional "end" statement here - which doesn't appear to be linked to any IF condition (though the forum makes it more difficult to tell) - This may be ending the script before the commandArray is returned.

EDIT: Actually looking again - it seems that your final IF block is actually wrapped inside the else of the toggle check.

Code: Select all

elseif (devicechanged['Schakelaar kleedkamer Toggle']) then
 if (devicechanged['Schakelaar kleedkamer Toggle']=='On') then
  if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
end
This "end" is the end of the code block for

Code: Select all

if (devicechanged['Schakelaar kleedkamer Toggle']=='On') then
So the following block that actually tried to switch the real light on and off - is only executed if the device that has changed is 'Schakelaar kleedkamer Toggle', now I am not entirely certain how the LUA scripts get called in Domoticz, but my understanding is once per device state change - so if the device that has changed is ['Schakelaar kleedkamer Toggle'] then the following IF block

Code: Select all

if (devicechanged['1 min timer kleedkamer'] == "On" or devicechanged['30 min timer slapen'] == "On"
will never be true because this part of the script will never be executed when they change state.

Code: Select all

commandArray = {}
if (devicechanged['Binnendeur kleedkamer'] == "Open" or devicechanged['PIR kleedkamer'] == "On") then
 if (otherdevices['IsDonker'] == "On") then
    if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
    commandArray['30 min timer slapen']='On'
 else
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
  commandArray['1 min timer kleedkamer']='On'
 end
elseif (devicechanged['Schakelaar kleedkamer Toggle']) then
 if (devicechanged['Schakelaar kleedkamer Toggle']=='On') then
  if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
 end
end

if (devicechanged['1 min timer kleedkamer'] == "On" or devicechanged['30 min timer slapen'] == "On" or devicechanged['Schakelaar kleedkamer Toggle'] == "On") then
 if (otherdevices['pLamp kleedkamer'] == "Off") then commandArray['pLamp kleedkamer']='On' end
else
 if (otherdevices['pLamp kleedkamer'] == "On") then commandArray['pLamp kleedkamer']='Off' end
end
return commandArray
Try that - this should also stop sending repeat commands.
AEOTEC ZStick, 11 ZWave Nodes, RFXCOMM, 50ish Byron Sockets.. HE851 (PIR), 2x HE852 (DoorContact)
WS2300, CM180, CC128, 2xTHGR122NX, 2xPiZeroW w/DS18B20, 8Ch 1W Relay Board.
8 Panasonic IP Cams, 1 16ch CCTV DVR + 15 CCTV Cams
TyzzyT
Posts: 32
Joined: Saturday 11 March 2017 11:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.5877
Contact:

Re: Help with smart switching

Post by TyzzyT »

I did activate this script, but as soon as I open my door the light goes on and immediately off again.
It also switches off the 30 min timer slapen.

I did write the ON/OFF commands which were being send after the rows. So you know what is happening.
To me it looks like the script is turning off the 30 min timer slapen, and since that it off the light won't turn on again.

Code: Select all

2017-05-04 08:58:11.037 EventSystem: Script event triggered: Kleedkamer verlichting
2017-05-04 08:58:11.006 (RFXtrx433) Lighting 4 (Binnendeur kleedkamer) = OPEN
2017-05-04 08:58:11.073 (Dummy) Light/Switch (30 min timer slapen) = OFF
2017-05-04 08:58:11.120 EventSystem: Script event triggered: Kleedkamer verlichting
2017-05-04 08:58:11.097 (Dummy) Light/Switch (1 min timer kleedkamer) = ON
2017-05-04 08:58:11.194 EventSystem: Script event triggered: Kleedkamer verlichting
2017-05-04 08:58:11.163 (RFXtrx433) Lighting 1 (pLamp kleedkamer) = ON
2017-05-04 08:58:11.238 (RFXtrx433) Lighting 1 (pLamp kleedkamer) = OFF
Also when I manually try to activate the light with the 'pLamp kleedkamer' or 'Schakelaar kleedkamer Toggle' the light goes on and immediately off again.
asjmcguire
Posts: 71
Joined: Saturday 13 July 2013 2:45
Target OS: Linux
Domoticz version: 3.5877
Location: Scotland
Contact:

Re: Help with smart switching

Post by asjmcguire »

TyzzyT wrote:I did activate this script, but as soon as I open my door the light goes on and immediately off again.
It also switches off the 30 min timer slapen.

I did write the ON/OFF commands which were being send after the rows. So you know what is happening.
To me it looks like the script is turning off the 30 min timer slapen, and since that it off the light won't turn on again.

Code: Select all

2017-05-04 08:58:11.037 EventSystem: Script event triggered: Kleedkamer verlichting
2017-05-04 08:58:11.006 (RFXtrx433) Lighting 4 (Binnendeur kleedkamer) = OPEN
2017-05-04 08:58:11.073 (Dummy) Light/Switch (30 min timer slapen) = OFF
2017-05-04 08:58:11.120 EventSystem: Script event triggered: Kleedkamer verlichting
2017-05-04 08:58:11.097 (Dummy) Light/Switch (1 min timer kleedkamer) = ON
2017-05-04 08:58:11.194 EventSystem: Script event triggered: Kleedkamer verlichting
2017-05-04 08:58:11.163 (RFXtrx433) Lighting 1 (pLamp kleedkamer) = ON
2017-05-04 08:58:11.238 (RFXtrx433) Lighting 1 (pLamp kleedkamer) = OFF
Also when I manually try to activate the light with the 'pLamp kleedkamer' or 'Schakelaar kleedkamer Toggle' the light goes on and immediately off again.
OK post the code of your updated script and we will see if we can get this working....
AEOTEC ZStick, 11 ZWave Nodes, RFXCOMM, 50ish Byron Sockets.. HE851 (PIR), 2x HE852 (DoorContact)
WS2300, CM180, CC128, 2xTHGR122NX, 2xPiZeroW w/DS18B20, 8Ch 1W Relay Board.
8 Panasonic IP Cams, 1 16ch CCTV DVR + 15 CCTV Cams
TyzzyT
Posts: 32
Joined: Saturday 11 March 2017 11:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.5877
Contact:

Re: Help with smart switching

Post by TyzzyT »

This is the script is currently have activated:

Code: Select all

commandArray = {}
if (devicechanged['Binnendeur kleedkamer'] == "Open" or devicechanged['PIR kleedkamer'] == "On") then
 if (otherdevices['IsDonker'] == "On") then
    if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
    commandArray['30 min timer slapen']='On'
 else
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
  commandArray['1 min timer kleedkamer']='On'
 end
elseif (devicechanged['Schakelaar kleedkamer Toggle']) then
 if (devicechanged['Schakelaar kleedkamer Toggle']=='On') then
  if (otherdevices['1 min timer kleedkamer'] == "On") then commandArray['1 min timer kleedkamer']='Off' end
  if (otherdevices['30 min timer slapen'] == "On") then commandArray['30 min timer slapen']='Off' end
 end
end

if (devicechanged['1 min timer kleedkamer'] == "On" or devicechanged['30 min timer slapen'] == "On" or devicechanged['Schakelaar kleedkamer Toggle'] == "On") then
 if (otherdevices['pLamp kleedkamer'] == "Off") then commandArray['pLamp kleedkamer']='On' end
else
 if (otherdevices['pLamp kleedkamer'] == "On") then commandArray['pLamp kleedkamer']='Off' end
end
return commandArray
zicht
Posts: 272
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Re: Help with smart switching

Post by zicht »

It makes sense it turns on and off, as the next time the lua is running it sees the different status and runs the opposit command :)

I simplfied the code a bit and skipped the both timers (used an internal domoticz supported timer) assuming you have a switch and not a push button

Code: Select all

if (devicechanged['Binnendeur kleedkamer'] == "Open" or devicechanged['PIR kleedkamer'] == "On") and otherdevices['IsDonker'] == "On" and otherdevices['pLamp kleedkamer'] == "Off" then
	commandArray['pLamp kleedkamer']='On FOR 1' -- 1 minute : You can adust time to whatever you want
	-- **
end

if (devicechanged['Schakelaar kleedkamer Toggle']=='On' and otherdevices['pLamp kleedkamer'] == "Off" ) then
   commandArray['pLamp kleedkamer']='On'
elseif (devicechanged['Schakelaar kleedkamer Toggle']=='Off' and otherdevices['pLamp kleedkamer'] == "On" ) then
   commandArray['pLamp kleedkamer']='Off'
end
if you need the other time you can add next line at the -- ** mark

Code: Select all

commandArray['30 min timer slapen']='On FOR 30'  
Hope this example helps you to get where you want to be.
This can be made from very simple to very complex by adding more conditions.

some explanation can be found here : https://www.domoticz.com/wiki/Events and https://www.domoticz.com/wiki/LUA_commands
commandArray['MyOtherDeviceName4']='On FOR 10' -- minutes
commandArray['MyOtherDeviceName5']='Off RANDOM 30' -- random within x minutes
commandArray['Scene:MyScene']='On'
commandArray['Group:MyGroup']='Off AFTER 30' -- seconds
* Notice the capital FOR and AFTER & Notice the FOR in minutes and AFTER in seconds

Couple of things to keep in mind :
Try to avoid nested IF THEN as it is more difficult to understand what happens when you need to alter the code later :)
Always check status in lua and think ahead of what wil happen when the script runs next time.
Last edited by zicht on Tuesday 13 June 2017 11:49, edited 1 time in total.
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
zicht
Posts: 272
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Re: Help with smart switching

Post by zicht »

zicht wrote: assuming you have a switch and not a push button
if you have a push button it can be done like this :

Code: Select all

if (devicechanged['Binnendeur kleedkamer'] == "Open" or devicechanged['PIR kleedkamer'] == "On") and otherdevices['IsDonker'] == "On" and otherdevices['pLamp kleedkamer'] == "Off" then
   commandArray['pLamp kleedkamer']='On FOR 1' -- 1 minute : You can adust time to whatever you want
  -- **
end

if (devicechanged['Schakelaar kleedkamer Toggle']=='On' and otherdevices['pLamp kleedkamer'] == "Off" ) then
   commandArray['pLamp kleedkamer']='On FOR 1' -- if you push the button lamp stays on for 1 minute
end
Hope you get the idea.
Difference between pushbutton and switch : Switch stays in position you set it, Push button just signals that you push it shortly
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest