#!/sheBangs/sheBangs♫ -o hBaby | when she && mv ./es♫ \ READ FORWARD, BUILD BACKWARDS (IN SECTION BOTTOM->TOP) ## VIRTUAL DEVICE DEF def norte_aircon: virtualDevice "norte_aircon_vent" exec.off"actionGroup_norte_aircon_kickstart_on_vent" exec.on"actionGroup_norte_aircon_kickstart_on_kill" print.status"norte_aircon_on_vent" virtualDevice "norte_aircon_cool" exec.on"actionGroup_norte_aircon_kickstart_on_vent" exec.off"actionGroup_norte_aircon_kickstart_on_kill" print.status"norte_aircon_on_cool" ## KEYPAD/BUTTON CONTROL -- DEVICE-INITIATED TRIGGERS DEF trigger ("if norte:kpad-bttn2 sends insteonON turnOFF aircon-norte") trig.type = insteon command received trig.from = device.keypadLincNorte trig.received = on.buttonGroup2 eval: always: is: True exec 1: action1.delay: 00:00:00 action1.type: exec actionGroup action1.group: actionGroup_norte_aircon_kickstart_on_kill else: exec 1: else.type: doNothing trigger ("if norte:kpad-bttn4 sends insteonON turnON aircon-norte @vent") trig.type = insteon command received trig.from = device.keypadLincNorte trig.received = on.buttonGroup4 eval: always: is: True exec 1: action1.delay: 00:00:00 action1.type: exec actionGroup action1.group: actionGroup_norte_aircon_kickstart_on_vent else: exec 1: else.type: doNothing trigger ("if norte:kpad-bttn6 sends insteonON turnON aircon-norte @cool") trig.type = insteon command received trig.from = device.keypadLincNorte trig.received = on.buttonGroup6 eval: always: is: True exec 1: action1.delay: 00:00:00 action1.type: exec actionGroup action1.group: actionGroup_norte_aircon_kickstart_on_cool else: exec 1: else.type: doNothing ## KICKSTARTERS DEF def actionGroup_norte_aircon_kickstart_on_kill exec 1: action1.delay: 00:00:00 action1.type: modify variable action1.variable: "norte_aircon_kickstart_on_kill" action1.value: +=1 def actionGroup_norte_aircon_kickstart_on_vent exec 1: action1.delay: 00:00:00 action1.type: modify variable action1.variable: "norte_aircon_kickstart_on_vent" action1.value: +=1 def actionGroup_norte_aircon_kickstart_on_cool exec 1: action1.delay: 00:00:00 action1.type: modify variable action1.variable: "norte_aircon_kickstart_on_cool" action1.value: +=1 ## KICKSTARTED CONTROL -- CONDITION-MATCHED TRIGGERS trigger ("norte_aircon_kickstart_on_kill detection") trig.type = variable changed trig.variable = norte_aircon_kickstart_on_kill trig.value = changes eval: always: is: True exec 1: action1.delay: 00:00:00 action1.type: exec actionGroup action1.group: "actionGroup_norte_aircon_on_kill" exec 2: action2.delay: 00:00:01 action2.type: enable schedule action2.disable: "norte_aircon_on_kill_runtime" else: exec 1: else.type: doNothing trigger ("norte_aircon_kickstart_on_vent detection") trig.type = variable changed trig.variable = norte_aircon_kickstart_on_vent trig.value = changes eval: always: is: True exec 1: action1.delay: 00:00:00 action1.type: exec actionGroup action1.group: "actionGroup_norte_aircon_on_vent" exec 2: action2.delay: 00:00:01 action2.type: enable schedule action2.disable: "norte_aircon_on_vent_runtime" else: exec 1: else.type: doNothing trigger ("norte_aircon_kickstart_on_cool detection") trig.type = variable changed trig.variable = norte_aircon_kickstart_on_cool trig.value = changes eval: if: cond1.type: systemVariable cond1.dark: True or: cond2.type: device cond2.device: "insteon wireless thermostat, non-climate controlled area" cond2.property: zone1temperature cond2.value: > 34 or: cond3.type: variable cond3.variable: norte_aircon_enabled cond3.value: True or: cond4.type: variable cond4.variable: norte_aircon_enabled_override cond4.value: True exec 1: action1.delay: 00:00:00 action1.type: exec actionGroup action1.group: "actionGroup_norte_aircon_on_cool" exec 2: action2.delay: 00:00:01 action2.type: enable schedule action2.disable: "norte_aircon_on_cool_runtime" else: # not input anywhere, just for reference exec: else.type: doNothing ## L0 ACTIONGROUPS DEF def actionGroup_norte_aircon_on_kill exec 1: action1.delay: 00:00:00 action1.type: modify variable action1.variable: "norte_aircon_on_vent" action1.value: False exec 2: action2.delay: 00:00:01 action2.type: modify variable action2.variable: "norte_aircon_on_cool" action2.value: False exec 3: action3.delay: 00:00:02 action1.type: disable schedule action1.disable: "norte_aircon_on_vent_runtime" exec 4: action4.delay: 00:00:03 action4.type: disable schedule action4.disable: "norte_aircon_on_cool_runtime" exec 5: action5.delay: 00:00:04 action5.type: modify variable action5.variable: "norte_aircon_on" action5.value: False exec 6: action6.delay: 00:00:05 action6.type: send device specific command (harmony hub actions) action6.device: "harmonyHub" harmonyHub.device: airconnorte harmonyHub.commandGroup: home harmonyHub.command: powerOFF def actionGroup_norte_aircon_on_vent exec 1: action1.delay: 00:00:00 action1.type: modify variable action1.variable: "norte_aircon_on_cool" action1.value: False exec 2: action2.delay: 00:00:01 action2.type: disable schedule action2.disable: "norte_aircon_on_kill_runtime" exec 3: action3.delay: 00:00:02 action3.type: disable schedule action3.disable: "norte_aircon_on_cool_runtime" exec 4: action4.delay: 00:00:03 action4.type: exec actionGroup action4.group: "actionGroup_norte_aircon_on_L2" exec 5: action5.delay: 00:00:04 action5.type: modify variable action5.variable: "norte_aircon_on_vent" action5.value: True exec 6: action6.delay: 00:00:06 action6.type: send device specific command (harmony hub actions) action6.device: "harmonyHub" harmonyHub.device: airconnorte harmonyHub.commandGroup: miscellaneous harmonyHub.command: fanOnly def actionGroup_norte_aircon_on_cool exec 1: action1.delay: 00:00:00 action1.type: modify variable action1.variable: "norte_aircon_on_vent" action1.value: False exec 2: action2.delay: 00:00:01 action2.type: disable schedule action2.disable: "norte_aircon_on_kill_runtime" exec 3: action3.delay: 00:00:02 action3.type: disable schedule action3.disable: "norte_aircon_on_vent_runtime" exec 4: action4.delay: 00:00:03 action4.type: exec actionGroup action4.group: "actionGroup_norte_aircon_on_L2" exec 5: action5.delay: 00:00:04 action5.type: modify variable action5.variable: "norte_aircon_on_cool" action5.value: True exec 6: action6.delay: 00:00:06 action6.type: send device specific command (harmony hub actions) action6.device: "harmonyHub" harmonyHub.device: airconnorte harmonyHub.commandGroup: miscellaneous harmonyHub.command: 28 ## L2 ACTIONGROUPS DEF # "actionGroup_norte_aircon_on_L2" & "norte_aircon_poweron_runtime" can be swapped # in the actionsGroups above therefore, there's no need to define both. \def actionGroup_norte_aircon_on_L2: \ exec 1: \ action1.delay: 00:00:00 \ action1.type: conditional_eps_super_conditions \ conditional.conditions: variable value \ conditional.variable: norte_aircon_on \ conditional.value: == False \ exec 1.1: \ action1.type: exec actionGroup \ action1.group: "actionGroup_norte_aircon_on_L3" \ conditional.else: \ exec 1.2: \ action2.type: doNothing ## L3 ACTIONGROUPS DEF def actionGroup_norte_aircon_on_L3: exec 1: action1.delay: 00:00:00 action1.device: "harmonyHub" harmonyHub.device: airconnorte harmonyHub.commandGroup: home harmonyHub.command: powerON exec 2: action2.delay: 00:00:01 action2.type: modify variable action2.variable: norte_aircon_on action2.value: True ## SCHEDULES DEF # Create schedules without actions so they can be added right away. # Adding no actions to them allows to duplicate actionGroups to finish quicker, # Indigo doesn't notice when a component in a program is updated, therefore # adding the action at a later stage forces Indigo to notice things changed. schedule("norte_aircon_on_kill_runtime") interval 300 # seconds exec actionGroup_norte_aircon_on_kill schedule("norte_aircon_on_vent_runtime") interval 600 # seconds exec actionGroup_norte_aircon_on_vent schedule("norte_aircon_on_cool_runtime") interval 600 # seconds exec actionGroup_norte_aircon_on_cool_L0 \schedule "norte_aircon_poweron_runtime" interval 1 # seconds \ !print(ExecutionInEventLog) # way too many at ^^^^^^^ interval! \ eval: \ if: \ cond1.type: variable \ cond1.variable: norte_aircon_on \ cond1.value: True \ exec 1: \ action1.delay: 00:00:00 \ action1.type: exec actionGroup \ action1.group: "actionGroup_norte_aircon_on_L3" \ else: \ exec 1: \ else.type: doNothing schedule (norte_aircon_enable) interval .at!Sunset exec 1: action1.type: modify variable action1.variable: norte_aircon_enabled action1.modify: True schedule (norte_aircon_disable) interval .at!Sunrise exec 1: action1.type: modify variable action1.variable: norte_aircon_enabled action1.modify: False exec 2: action2.type: modify variable action2.variable: norte_aircon_kickstart_kill action2.modify: increment1 ## VARIABLES DEF norte_aircon_kickstart_kill = 356 norte_aircon_kickstart_vent = 356 norte_aircon_kickstart_cool = 357 norte_aircon_on = True|False norte_aircon_on_vent = True|False norte_aircon_on_cool = True|False norte_aircon_enabled = True|False norte_aircon_enabled_override = 1|0 daytime = True|False # This is meant for devices that don't report status back to automation controllers, # like ductless (mini split) AC units, the example here, hence all the repetition. # Repetition also avoids manual override appliance-mounted buttons. SCHEDULE "norte_aircon_poweron_runtime" IS A WORKAROUND FOR THE SUPERCONDITIONS PLUGIN, IE; THE PLUGIN IS NOT DESIRED/COMPATIBLE/DISCONTINUED/ETC. THE DOWNSIDE IS THAT IT REPEATS CRAZY FAST SO IT WOULD FKUP THE NEXT SCHEDULE READOUT BY HAVING IT ALWAYS BEING RIGHT NOW.