Announcement

Collapse
No announcement yet.

Routines

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Routines


    #2
    I wholeheartedly endorse the use of 'modules' that can be implemented at different times and in varying order based on multiple conditions, including the state of virtual devices. As long as you can distill the things you want to happen to chunks that can be recombined, the resulting structure can be relatively easy to understand and maintain, grow, modify. Setting it up, though, will require considerable planning - and probably some frustration, backtracking, and even some colorful vocabulary.

    I started by isolating the things that happen only when we are home, vs those that happen only when we are away. (You've probably already done that!) The trick for me was to identify more subtle distinctions to subdivide what happens when the house is occupied, based on the types of activities taking place. My only real success was reliably identifying when a room/area is occupied or unoccupied. That simple concept, with just two people in the house, turned out to be quite difficult for some spaces.

    The problem gets more difficult very rapidly as the number of people in the house increases. If you live alone, it may be easier.
    You also need to identify how HS will 'know' what activities are underway - and planned - if location alone is not enough.

    One strategy that worked for me was to first determine how HS was going to identify a specific state. I then collected data from the relevant sensors and plotted the results over time (days at least, more often months) looking for patterns to use as "triggers" to identify activity.

    The prosaic ones were easy: Arming and disarming the alarm system. Turning a light on or off.
    Motion sensing is more difficult, but useful.
    The more clever you are, the better.
    Mike____________________________________________________________ __________________
    HS3 Pro Edition 3.0.0.548, NUC i3

    HW: Stargate | NX8e | CAV6.6 | Squeezebox | PCS | WGL 800RF | RFXCOM | Vantage Pro | Green-Eye | Edgeport/8 | Way2Call | Ecobee3 | EtherRain | Ubiquiti

    Comment


      #3
      Well I am on my own for now and since my ex limited everything to just automated lighting I’m really itching. With my run rate there will be another one this year but she won’t be moving in for a while and will need to accept my geekery and tinkering. Being a telecom project manager and engineer with idle hands is painful. Anyway that’s good advice I’ll design the system in a modular form and my “guest mode” will be easily transitionable to cohabitation in the future.

      Got any flow charts or anything I can look at? Interested in your use of motion sensors. You went the same route as me by monitoring routine and pattern of behaviors in a lab environment.

      Comment


        #4
        "with my run rate".... LOL

        Comment


          #5
          Originally posted by kideon View Post
          Got any flow charts or anything I can look at? Interested in your use of motion sensors.
          Here's a thread on the subject. There's a copy of the script and a description of the logic I use in one of the posts, but I'm not sure how transferable my approach might be.
          Mike____________________________________________________________ __________________
          HS3 Pro Edition 3.0.0.548, NUC i3

          HW: Stargate | NX8e | CAV6.6 | Squeezebox | PCS | WGL 800RF | RFXCOM | Vantage Pro | Green-Eye | Edgeport/8 | Way2Call | Ecobee3 | EtherRain | Ubiquiti

          Comment


            #6
            That’s exactly the same approach I was thinking of. Instead of making a decision based on direct sensor information it would use, for lack of a better term, mathematical weights impacting thresholds. It’s a basic tenant of neural networking.

            Going to start adapting everything, should be fun.

            Comment


              #7
              Originally posted by Tomgru View Post
              "with my run rate".... LOL
              Hah yeah it’s inevitable

              Comment


                #8
                I use virtual devices a lot. I'll highlight some of the more important ones.

                Scenes - For my house and our usage patterns, I have defined 11 'scenes'. These range from Sleeping to Cooking. On my HSTouch app using a couple of Fire tablets, I can select any scene - lets say 'Off To Bed'. The HSTouch app simply turns on the virtual device for 'Off To Bed'. I have an event that looks for 'Off To Bed' to change to ON. When it does, I adjust lights all over the house, turn on the reading lights at the bed, set the temperature lower, turn on the outside cameras, arm the door sensors. I have a DIY minimote by the bed. When I'm ready to sleep, I just push the Sleeping button which sets the virtual device and ......

                Overall House Status - I've defined AWAY, NO SECURITY, SLEEPING, and ARRIVING. All are virtual devices that are tested in events. I can access these when I'm away via the HSTouch app on my phone. That is mostly for the ARRIVING scene which turns on some lights, sets temperature to my preferred temp, turns off security so that things don't go crazy when I arrive.

                Global Variables - There are probably 50 other virtual devices I use to handle the equivalent of a global variable. One example is one called 'Outside Motion Detected'. I have several types of outside sensors. There are cameras (controlled by Blue Iris), PIR motion detectors, Door sensors on outside buildings. There are several events that do different things based on there being motion and the 'Overall House Status'. I have one event that has a bunch of ORIFs that test each of the various sensors and set the var. Then events just need to test for that one virtual device as being changed rather than worry about all the actual devices. I find it makes it a bit cleaner should the device mix change.

                I also use timers quite a bit. One example is the guest bath. I have a PIR motion sensor in there that fires anytime someone enters. That sets a virtual device to indicate the bath is occupied and then starts a timer for X seconds and then turns on the light. If additional motion is detected before the timer expires, the timer is reset to X seconds. When the timer expires, it turns off the bath occupied device and turns off the lights.

                Comment


                  #9
                  Originally posted by logbuilder View Post
                  I also use timers quite a bit. One example is the guest bath. I have a PIR motion sensor in there that fires anytime someone enters. That sets a virtual device to indicate the bath is occupied and then starts a timer for X seconds and then turns on the light. If additional motion is detected before the timer expires, the timer is reset to X seconds. When the timer expires, it turns off the bath occupied device and turns off the lights.
                  You might want to explain this more, since timers count up. The way it reads, it sounds like you have a countdown timer. This may confuse newer users.
                  HS4 Pro, 4.2.19.16 Windows 10 pro, Supermicro LP Xeon

                  Comment


                    #10
                    Originally posted by rprade View Post
                    You might want to explain this more, since timers count up. The way it reads, it sounds like you have a countdown timer. This may confuse newer users.
                    You are right, I explained it poorly. Here are the actual events.
                    Attached Files

                    Comment


                      #11

                      Comment


                        #12
                        Here is what I am doing for lights. I have a house mode device that tracks the time of day and the weather (if the weather rolls in and it starts to get dark, i have certain lights come on in the house). I also have a few LUX sensors outside around the house that will override if it gets darker earlier than usual.

                        I did away with creating a lot of events and timers to control the lights with motion (or just a delay if they are left on in areas where the wife didn't like the motion aspect). I created a master script that gets invoked by a motion sensor status change and sends variables when invoked (motion sensor and light device ID as well as delay amount). This script checks if the light is off and acts accordingly based off the house mode settings. If the motion status goes to no motion, it invokes another script (thru the main one, was just easier to split them into two for various reasons) to create a delay event accounting for the delay that gets deleted once run.

                        If the motion is tripped again, and the light is on because the delay event didn't fire, the script will delete the delayed event... and the process starts all over again.

                        I am not a coder, so I am sure there is a better way of doing this. But its been flawless for almost a year now and its dropped me down to only one event per light, tied to the motion sensor for that room and no timers. So adding a new light is super simple.


                        First script:
                        Code:
                        'Parameters Sent Motion Device RefId,Light Device RefId,Delay In Minutes,Dimmable(0/1),Door1(0 if no door),Door2(0 if no door)
                        Public Dim House_Mode_Device as string = 1060 'Change this to your house mode device
                        Public Dim Debug as Boolean = False 'Change For Debug Logs
                        'House Mode: Day/0 Evening/10 Sleep/20 Morning/30 Day Light/40 Day Heavy/50 No Motion/60 Dawn/70 Cleaning?Entertain/80
                        'Set below for the light level desired for each house mode
                        Public Dim Morning_Dim_Level as string = 15
                        Public Dim Evening_Dim_Level as string = 30
                        Public Dim Sleep_Dim_Level as string = 6
                        
                        
                        
                        '---------------------------------------------------
                        '-------Do Not Modify Below-------------------------
                        '---------------------------------------------------
                        
                        
                        Public Dim logName = "Motion Script"
                        '---------------------------------------------------
                        '-------Build Initial Array-------------------------
                        '---------------------------------------------------
                        
                        Sub Main(ByVal parms As Object)
                        Dim parmArray() As String
                        parmArray = parms.ToString().Split(",")
                        Dim delay_time = parmArray(2)
                        Dim Dimmable as string = parmArray(3)
                        Dim Door1 as string = parmArray(4)
                        Dim Door2 as string = parmArray(5)
                        Dim House_Mode as string
                        House_Mode = hs.deviceValueEX(House_Mode_Device)
                        If Debug then hs.writelog(logName, "<font color=blue>Build Array Sub Called")
                        Dim Array_Pass As String
                        
                        'Motion Device Name
                        Dim Motion_Device = parmArray(0)
                        Dim Motion_Name As Scheduler.Classes.DeviceClass 
                        Motion_Name = hs.GetDeviceByRef(Motion_Device)
                        Dim Total_Motion_Name = Motion_Name.Location(hs) & " " & Motion_Name.Name(hs)
                        
                        'Light Device Name
                        Dim Light_Device = parmArray(1)
                        Dim Light_Name As Scheduler.Classes.DeviceClass 
                        Light_Name = hs.GetDeviceByRef(Light_Device)
                        Dim Total_Light_Name = Light_Name.Location(hs) & " " & Light_Name.Name(hs)
                        
                        If Debug then hs.writelog(logName, "<font color=Orange>Array Received(Initial Array): Motion Device: " & Motion_Device & " Light Device: " & Light_Device & " Delay Time: " & delay_time & " Door 1: " & Door1 & " Door 2: " & Door2)
                        
                        'Send Array to Sub Light_Decision
                        Light_Decision (Light_Device & "," & Dimmable & "," & Motion_Device & "," & House_Mode & "," & Total_Light_Name & "," & Door1 & "," & Door2)
                        'Send Array to Sub Event_Decision
                        'Event_Decision (Motion_Device & "," & Light_Device & "," & Total_Light_Name & "," & House_Mode & "," & delay_time)
                        
                        Array_Pass = Motion_Device & "," & Light_Device & "," & delay_time
                        hs.runScriptFunc("Motion_Light_Update_No_On.vb","Main",Array_Pass,False,False)
                        
                        If Debug then hs.writelog(logName, "<font color=blue>Script Call Completed")
                        
                        End Sub
                        
                        
                        
                        '-------------------------------------------------------------------------------------
                        '------------------------------ LIGHT DECISION ---------------------------------------
                        '-------------------------------------------------------------------------------------
                        
                        Sub Light_Decision(ByVal parms as Object)
                        Dim parmArray() As String
                        parmArray = parms.ToString().Split(",")
                        Dim Light_Device as string = parmArray(0)
                        Dim Dimmable as string = parmArray(1)
                        Dim Motion_Device as string = parmArray(2)
                        Dim House_Mode as string = parmArray(3)
                        Dim Total_Light_Name as string = parmArray(4)
                        Dim Door1 as string = parmArray(5)
                        Dim Door2 as string = parmArray(6)
                        Dim Request_Status as string
                        Dim Light_Decision as string
                        Dim Device_Name As Scheduler.Classes.DeviceClass 
                        
                        Light_Decision = 0
                        If Motion_Device <> 0 then
                        	If hs.deviceValueEX(Motion_Device) <> 0 then
                        		If Light_Decision = 0
                        			Light_Decision = 1
                        			If Debug then
                        				Device_Name = hs.GetDeviceByRef(Motion_Device)
                        				Dim Total_Motion_Name = Device_Name.Location(hs) & " " & Device_Name.Name(hs)
                        				hs.writelog(logName, "<font color=OrangeRed>" & Total_Motion_Name & " Triggered Light Decision")
                        			End If
                        		End If
                        	End If
                        End If
                        
                        If Door2 <> 0 then
                        	If hs.deviceValueEX(Door2) <> 0 then
                        		If Light_Decision = 0
                        			Light_Decision = 1
                        			If Debug then
                        				Device_Name = hs.GetDeviceByRef(Door2)
                        				Dim Total_Door2_Name = Device_Name.Location(hs) & " " & Device_Name.Name(hs)
                        				hs.writelog(logName, "<font color=OrangeRed>" & Total_Door2_Name & " Triggered Light Decision")
                        			End If
                        		End If
                        	End If
                        End If
                        
                        If Door1 <> 0 then 
                        	If hs.deviceValueEX(Door1) <> 0 then
                        		If Light_Decision = 0
                        			Light_Decision = 1
                        			If Debug then 
                        				Device_Name = hs.GetDeviceByRef(Door1)
                        				Dim Total_Door1_Name = Device_Name.Location(hs) & " " & Device_Name.Name(hs)
                        				hs.writelog(logName, "<font color=OrangeRed>" & Total_Door1_Name & " Triggered Light Decision")
                        			End If
                        		End If
                        	End If
                        End If
                        
                        If Light_Decision = 0 then
                        	If Debug then hs.writelog(logName, "<font color=OrangeRed>No Light Decision Captured")
                        End If
                        
                        If Debug then hs.writelog(logName, "<font color=blue>Light Decision Sub Called")
                        
                        If Light_Decision <> 0 then
                        	If House_Mode <> 0 then
                        		If House_Mode <> 40 then 
                        			If hs.DeviceValueEX(Light_Device) <> 0 then
                        				If Debug then hs.writelog(logName, "<font color=green>" & Total_Light_Name & " is already on")
                        			Else
                        				If Dimmable = 0
                        					hs.CAPIControlHandler(hs.CAPIGetSingleControl(Light_Device,true ,"on",false,true))
                        					'hs.RunScriptFunc("pushover.vb","Main","Window Alert|"& Total_Light_Name & " was turned on" & "|Priority|Sound",false,false)
                        					If Debug then hs.writelog(logName, "<font color=green>" & Total_Light_Name & " was turned on")
                        				Else
                        					If House_Mode = 30 then
                        						'Morning Lights
                        						Request_Status = Morning_Dim_Level
                        					ElseIf House_Mode = 10 then
                        						'Evening Lights
                        						Request_Status = Evening_Dim_Level
                        					ElseIf House_Mode = 20 then
                        						'Sleep Lights
                        						Request_Status = Sleep_Dim_Level
                        					ElseIf House_Mode = 60 then
                        						'No Motion Lights
                        						Request_Status = Sleep_Dim_Level
                        					ElseIf House_Mode = 70 then
                        						'Dawn Lights
                        						Request_Status = Sleep_Dim_Level						
                        					Else
                        						'All Others
                        						Request_Status = 30
                        					End If
                        					hs.CAPIControlHandler(hs.CAPIGetSingleControl(Light_Device, false, Request_Status, false, true))
                        					'hs.RunScriptFunc("pushover.vb","Main","Window Alert|"& Total_Light_Name & " was turned on with Dim Level: " & Request_Status & "|Priority|Sound",false,false)
                        					If Debug then hs.writelog(logName, "<font color=green>" & Total_Light_Name & " was turned on with Dim Level: " & Request_Status)
                        				End If
                        			End If
                        		Else
                        			If Debug then hs.writelog(logName, "<font color=Purple>Current House Mode setting (" & House_Mode & ") won't allow for Light to be turned on")
                        		End If
                        	Else 
                        		If Debug then hs.writelog(logName, "<font color=Purple>Current House Mode setting (" & House_Mode & ") won't allow for Light to be turned on")
                        	End If
                        Else
                        	If Debug then hs.writelog(logName, "<font color=red>Error in Light Decision")
                        End If
                        
                        End Sub
                        Second Script (I also will use just this one if I don't want the light controlled by motion, but still want the delay if the lights get left on):
                        Code:
                        'Parameters Sent Motion Device RefId,Light Device RefId,Delay In Minutes
                        Public Dim House_Mode_Device as string = 1060 'Change this to your house mode device
                        Public Dim Debug as integer = 0 '0 No Logs / 1 Shows Logs
                        'House Mode: Day/0 Evening/10 Sleep/20 Morning/30 Day Light/40 Day Heavy/50 No Motion/60 Dawn/70 Cleaning?Entertain/80
                        'Set below for the light level desired for each house mode
                        
                        
                        '---------------------------------------------------
                        '-------Do Not Modify Below-------------------------
                        '---------------------------------------------------
                        
                        
                        Public Dim logName = "Motion Script"
                        '---------------------------------------------------
                        '-------Build Initial Array-------------------------
                        '---------------------------------------------------
                        
                        Sub Main(ByVal parms As Object)
                        Dim parmArray() As String
                        parmArray = parms.ToString().Split(",")
                        Dim delay_time = parmArray(2)
                        
                        Dim House_Mode as string
                        House_Mode = hs.deviceValueEX(House_Mode_Device)
                        If Debug = 1 then 
                        	hs.writelog(logName, "Build Array Sub Called")
                        End If
                        
                        'Motion Device Name
                        Dim Motion_Device = parmArray(0)
                        Dim Motion_Name As Scheduler.Classes.DeviceClass 
                        Motion_Name = hs.GetDeviceByRef(Motion_Device)
                        Dim Total_Motion_Name = Motion_Name.Location(hs) & " " & Motion_Name.Name(hs)
                        
                        'Light Device Name
                        Dim Light_Device = parmArray(1)
                        Dim Light_Name As Scheduler.Classes.DeviceClass 
                        Light_Name = hs.GetDeviceByRef(Light_Device)
                        Dim Total_Light_Name = Light_Name.Location(hs) & " " & Light_Name.Name(hs)
                        
                        If Debug = 1 then
                        	hs.writelog(logName, "Array Received(Initial Array): Motion Device: " & Motion_Device & " Light Device: " & Light_Device & " Delay Time: " & delay_time)
                        End If
                        
                        'Send Array to Sub Event_Decision
                        Event_Decision (Motion_Device & "," & Light_Device & "," & Total_Light_Name & "," & House_Mode & "," & delay_time)
                        
                        If Debug = 1 then
                        	hs.writelog(logName, "Script Call Completed")
                        End If
                        
                        End Sub
                        
                        '-------------------------------------------------------------------------------------
                        '------------------------------ EVENT DECISION ---------------------------------------
                        '-------------------------------------------------------------------------------------
                        
                        'This Will Create/Destroy Event depending on Needs
                        Sub Event_Decision(ByVal parms as Object)
                        Dim parmArray() As String
                        parmArray = parms.ToString().Split(",")
                        Dim Motion_Device as string = parmArray(0)
                        Dim Light_Device as string = parmArray(1)
                        Dim Total_Light_Name as string = parmArray(2)
                        Dim House_Mode as string = parmArray(3)
                        Dim delay_time as string = parmArray(4)
                        
                        If Debug = 1 then
                        	hs.writelog(logName, "Event Decision Sub Called")
                        End If
                        
                        If hs.DeviceValueEX(Motion_Device) = 0 Then
                        	If Debug = 1 then
                        		hs.writelog(logName, "Array Received(Event_Decision): Motion Device: " & Motion_Device & " Light Device: " & Light_Device & " Total Light Name: " & Total_Light_Name & " House Mode: " & House_Mode & " Delay: " & delay_time)
                        	End If	
                        	If hs.EventExists(Total_Light_Name & " Delayed") then
                        		'hs.RunScriptFunc("pushover.vb","Main","Window Alert|"& Total_Light_Name & " Delayed event already exists." & "|Priority|Sound",false,false)
                        		If Debug = 1 then
                        			hs.writelog(logName, Total_Light_Name & " Delayed event already exists.")
                        		End If
                        	Else
                        		If (House_Mode <> 80) orElse (House_Mode = 80 and (Instr(Total_Light_Name,"Laundry") orElse Instr(Total_Light_Name,"Garage"))) then
                        			'If hs.deviceValueEX(Light_Device) <> 19 then 'Basement Light Check to keep on
                        				If hs.DeviceValueEX(Light_Device) <> 0 then
                        					Dim Event_Ref
                        					Dim etime = Date.Now().AddMinutes(delay_time)
                        					Event_Ref = hs.newEventEx(Total_Light_Name & " Delayed", "Delayed Events", "")
                        					hs.EventSetTimeTrigger(Event_Ref,etime)
                        					hs.DeleteAfterTrigger_Set(Event_Ref)
                        					hs.AddDeviceActionToEvent(Event_Ref,hs.CAPIGetSingleControl(Light_Device, False, "off", False, False))
                        					'hs.RunScriptFunc("pushover.vb","Main","Window Alert|"& Total_Light_Name & " Delayed event created." & "|Priority|Sound",false,false)
                        					If Debug = 1 then 
                        						hs.writelog (logName, Total_Light_Name & " Delayed event created.")
                        					End If
                        				Else
                        					If Debug = 1 then 
                        						hs.writelog (logName, Total_Light_Name & " Not On, Event Not Created.")
                        					End If					
                        				End If
                        			'End If
                        		Else
                        			If Debug = 1 then
                        				hs.writelog(logName, "Current House Mode setting won't allow for Event Creation")
                        			End If
                        		End If
                        	End If
                        Else
                        	If hs.EventExists(Total_Light_Name & " Delayed") then
                        		hs.DeleteEvent(Total_Light_Name & " Delayed")
                        		'hs.RunScriptFunc("pushover.vb","Main","Window Alert|"& Total_Light_Name & " Motion Detected, Delay Event Deleted" & "|Priority|Sound",false,false)
                        		If Debug = 1 then
                        			hs.writelog(logName, Total_Light_Name & " Motion Detected, Delay Event Deleted")
                        		End If
                        	Else
                        		If Debug = 1 then
                        			hs.writelog(logName, Total_Light_Name & " Motion Detected, No Event to Delete")
                        		End If
                        	End If
                        End If
                        
                        If Debug = 1 then
                        	hs.writelog(logName, "Exit Event Decision Sub")
                        End If
                        
                        End Sub
                        Attached Files

                        Comment


                          #13
                          This is a good example of what we’ve even discussing https://www.home-assistant.io/compon...nsor.bayesian/

                          I was familiar with the concept but couldn’t remember formal name. It’s what I’d like to see implemented here. Someone could write into a script or plugin in day.

                          Comment

                          Working...
                          X