forked from pnbruckner/homeassistant-config
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlight_store.py
119 lines (105 loc) · 4.85 KB
/
light_store.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
VERSION = '1.2.0'
DOMAIN = 'light_store'
ATTR_OPERATION = 'operation'
ATTR_OP_SAVE = 'save'
ATTR_OP_RESTORE = 'restore'
ATTR_OVERWRITE = 'overwrite'
ATTR_STORE_NAME = 'store_name'
ATTR_ENTITY_ID = 'entity_id'
# Select light attributes to save/restore.
ATTR_BRIGHTNESS = "brightness"
ATTR_EFFECT = "effect"
ATTR_WHITE_VALUE = "white_value"
ATTR_COLOR_TEMP = "color_temp"
ATTR_HS_COLOR = "hs_color"
# Save any of these attributes.
GEN_ATTRS = [ATTR_BRIGHTNESS, ATTR_EFFECT]
# Save only one of these attributes, in order of precedence.
COLOR_ATTRS = [ATTR_WHITE_VALUE, ATTR_COLOR_TEMP, ATTR_HS_COLOR]
def store_entity_id(store_name, entity_id):
return '{}.{}'.format(store_name, entity_id.replace('.', '_'))
# Get operation (default to save.)
operation = data.get(ATTR_OPERATION, ATTR_OP_SAVE)
if operation not in [ATTR_OP_SAVE, ATTR_OP_RESTORE]:
logger.error('Invalid operation. Expected {} or {}, got: {}'.format(
ATTR_OP_SAVE, ATTR_OP_RESTORE, operation))
else:
# Get optional store name (default to DOMAIN.)
store_name = data.get(ATTR_STORE_NAME, DOMAIN)
# Get optional overwrite parameter (only applies to saving.)
overwrite = data.get(ATTR_OVERWRITE, True)
# Get optional list (or comma separated string) of switches & lights to
# save/restore.
entity_id = data.get(ATTR_ENTITY_ID)
if isinstance(entity_id, str):
entity_id = [e.strip() for e in entity_id.split(',')]
# Replace any group entities with their contents.
# Repeat until no groups left in list.
expanded_a_group = True
while entity_id and expanded_a_group:
expanded_a_group = False
for e in entity_id:
if e.startswith('group.'):
entity_id.remove(e)
g = hass.states.get(e)
if g and 'entity_id' in g.attributes:
entity_id.extend(g.attributes['entity_id'])
expanded_a_group = True
# Get lists of switches and lights that actually exist,
# and list of entities that were previously saved.
entity_ids = (hass.states.entity_ids('switch') +
hass.states.entity_ids('light'))
saved = hass.states.entity_ids(store_name)
# When restoring, limit to existing entities that were saved.
if operation == ATTR_OP_RESTORE:
saved_entity_ids = []
for e in entity_ids:
if store_entity_id(store_name, e) in saved:
saved_entity_ids.append(e)
entity_ids = saved_entity_ids
# If a list of entities was specified, further limit to just those.
# Otherwise, save all existing switches and lights, or restore
# all existing switches and lights that were previously saved.
if entity_id:
entity_ids = tuple(set(entity_ids).intersection(set(entity_id)))
if operation == ATTR_OP_SAVE:
# Only save if not already saved, or if overwite is True.
if not saved or overwrite:
# Clear out any previously saved states.
for entity_id in saved:
hass.states.remove(entity_id)
# Save selected switches and lights to store.
for entity_id in entity_ids:
cur_state = hass.states.get(entity_id)
if cur_state is None:
logger.error('Could not get state of {}.'.format(entity_id))
else:
attributes = {}
if entity_id.startswith('light.') and cur_state.state == 'on':
for attr in GEN_ATTRS:
if attr in cur_state.attributes:
attributes[attr] = cur_state.attributes[attr]
for attr in COLOR_ATTRS:
if attr in cur_state.attributes:
attributes[attr] = cur_state.attributes[attr]
break
hass.states.set(store_entity_id(store_name, entity_id),
cur_state.state, attributes)
else:
# Restore selected switches and lights from store.
for entity_id in entity_ids:
old_state = hass.states.get(store_entity_id(store_name, entity_id))
if old_state is None:
logger.error('No saved state for {}.'.format(entity_id))
else:
turn_on = old_state.state == 'on'
service_data = {'entity_id': entity_id}
component = entity_id.split('.')[0]
if component == 'light' and turn_on and old_state.attributes:
service_data.update(old_state.attributes)
hass.services.call(component,
'turn_on' if turn_on else 'turn_off',
service_data)
# Remove saved states now that we're done with them.
for entity_id in saved:
hass.states.remove(entity_id)