133 lines
4.4 KiB
Python
133 lines
4.4 KiB
Python
import appdaemon.plugins.hass.hassapi as hass
|
|
import globals
|
|
import datetime
|
|
|
|
class LightButton(hass.Hass):
|
|
isLocked = False
|
|
|
|
def initialize(self):
|
|
if not globals.check_args(self,['entities', 'sensor']):
|
|
return
|
|
|
|
self.listen_event_handle_list = []
|
|
self.listen_event_handle_list.append(self.listen_event(self.event_detected, "xiaomi_aqara.click"))
|
|
self.listen_event_handle_list.append(self.listen_state(self.state_change, self.args['sensor'])) #, attribute='action'
|
|
|
|
def state_change(self, entity, attribute, old, new, kwargs):
|
|
if new == "single":
|
|
self.log('button_click')
|
|
self.make_action_by_mode("off")
|
|
if new == "double":
|
|
self.log('button_dblclick')
|
|
self.make_action_by_mode("on")
|
|
|
|
def event_detected(self, event_name, data, kwargs):
|
|
if data["entity_id"] != self.args["sensor"] or self.isLocked:
|
|
return
|
|
self.isLocked = True
|
|
if data["click_type"] == "single":
|
|
self.log('button_click')
|
|
self.make_action_by_mode("off")
|
|
if data["click_type"] == "double":
|
|
self.log('button_dblclick')
|
|
self.make_action_by_mode("on")
|
|
|
|
self.run_in(self.clear_lock, 1)
|
|
|
|
def clear_lock(self, kwargs):
|
|
self.isLocked = False
|
|
|
|
def make_action_by_mode(self, state):
|
|
states = self.fill_states()
|
|
control_entity = self.args.get('control_input', None)
|
|
if (control_entity != None):
|
|
entity_id = next(iter(states))
|
|
state = self.get_state(entity_id)
|
|
self.set_state(entity_id, self.invert_state(state))
|
|
self.set_state(control_entity, state)
|
|
return
|
|
|
|
if len(self.args["entities"]) > 1:
|
|
self.toggle_next_with_state(state, states)
|
|
|
|
def toggle_next_with_state(self, state, states):
|
|
for entity_id in states:
|
|
entity_state = states[entity_id]
|
|
if (entity_state == state):
|
|
self.set_state(entity_id, self.invert_state(state))
|
|
self.log('toggling {}'.format(entity_id))
|
|
return
|
|
|
|
for entity_id in states:
|
|
self.log('toggling {}'.format(entity_id))
|
|
self.toggle(entity_id)
|
|
|
|
def set_state(self, entity_id, state):
|
|
if (state == "off"):
|
|
self.log('turn_off {}'.format(entity_id))
|
|
self.set_off(entity_id)
|
|
if (state == "on"):
|
|
self.log('turn_on {}'.format(entity_id))
|
|
self.set_on(entity_id)
|
|
|
|
#light
|
|
def set_on(self, entity_id):
|
|
brightness = 1 #night mode
|
|
if self.time_is_between(self.datetime(), '07:00:00', '23:00:00'):
|
|
brightness=255 #day mode
|
|
|
|
if entity_id.startswith("light") and 'color' in entity_id:
|
|
self.call_service("homeassistant/turn_on", entity_id = entity_id, transition = 1, brightness = brightness, color_temp=204)
|
|
elif entity_id.startswith("light"):
|
|
self.call_service("homeassistant/turn_on", entity_id = entity_id, transition = 1, brightness = brightness)
|
|
else:
|
|
self.turn_on(entity_id)
|
|
|
|
def set_off(self, entity_id):
|
|
if entity_id.startswith("light"):
|
|
self.call_service("homeassistant/turn_off", entity_id = entity_id, transition = 1)
|
|
else:
|
|
self.turn_off(entity_id)
|
|
|
|
|
|
def invert_state(self, state):
|
|
if (state == "off"):
|
|
return "on"
|
|
return "off"
|
|
|
|
def fill_states(self):
|
|
states = {}
|
|
for entity_id in self.split_device_list(self.args["entities"]):
|
|
state = self.get_state(entity_id)
|
|
if (state == None):
|
|
self.log("Warning! Device {} not found (state: {}).".format(entity_id, state))
|
|
continue
|
|
states[entity_id] = state
|
|
return states
|
|
|
|
def terminate(self):
|
|
if self.listen_event_handle_list != None:
|
|
for listen_event_handle in self.listen_event_handle_list:
|
|
self.cancel_listen_event(listen_event_handle)
|
|
|
|
def time_is_between(
|
|
hass, target_dt: datetime, start_time: str,
|
|
end_time: str) -> bool:
|
|
"""Generalization of AppDaemon's now_is_between method."""
|
|
start_time_dt = hass.parse_time(start_time) # type: datetime
|
|
end_time_dt = hass.parse_time(end_time) # type: datetime
|
|
start_dt = target_dt.replace(
|
|
hour=start_time_dt.hour,
|
|
minute=start_time_dt.minute,
|
|
second=start_time_dt.second)
|
|
end_dt = target_dt.replace(
|
|
hour=end_time_dt.hour,
|
|
minute=end_time_dt.minute,
|
|
second=end_time_dt.second)
|
|
|
|
if end_dt < start_dt:
|
|
# Spans midnight
|
|
if target_dt < start_dt and target_dt < end_dt:
|
|
target_dt = target_dt + timedelta(days=1)
|
|
end_dt = end_dt + timedelta(days=1)
|
|
return start_dt <= target_dt <= end_dt |