Skip to content

Commit 7b99c32

Browse files
committed
Add attributes restore
1 parent 4fe141f commit 7b99c32

File tree

1 file changed

+114
-62
lines changed

1 file changed

+114
-62
lines changed
+114-62
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,89 @@
1+
"""variable implementation for Homme Assistant."""
12
import asyncio
23
import logging
34
import json
45

56
import voluptuous as vol
67

7-
from homeassistant.const import (CONF_NAME, ATTR_ICON)
8+
from homeassistant.const import CONF_NAME, ATTR_ICON
89
from homeassistant.helpers import config_validation as cv
9-
from homeassistant.helpers import template
1010
from homeassistant.exceptions import TemplateError
1111
from homeassistant.loader import bind_hass
12-
from homeassistant.helpers.entity import Entity
1312
from homeassistant.helpers.entity_component import EntityComponent
1413
from homeassistant.helpers.restore_state import RestoreEntity
1514

1615
_LOGGER = logging.getLogger(__name__)
1716

18-
DOMAIN = 'variable'
19-
ENTITY_ID_FORMAT = DOMAIN + '.{}'
17+
DOMAIN = "variable"
18+
ENTITY_ID_FORMAT = DOMAIN + ".{}"
2019

2120
CONF_ATTRIBUTES = "attributes"
2221
CONF_VALUE = "value"
2322
CONF_RESTORE = "restore"
2423

2524
ATTR_VARIABLE = "variable"
26-
ATTR_VALUE = 'value'
27-
ATTR_VALUE_TEMPLATE = 'value_template'
25+
ATTR_VALUE = "value"
26+
ATTR_VALUE_TEMPLATE = "value_template"
2827
ATTR_ATTRIBUTES = "attributes"
2928
ATTR_ATTRIBUTES_TEMPLATE = "attributes_template"
3029
ATTR_REPLACE_ATTRIBUTES = "replace_attributes"
3130

3231
SERVICE_SET_VARIABLE = "set_variable"
33-
SERVICE_SET_VARIABLE_SCHEMA = vol.Schema({
34-
vol.Required(ATTR_VARIABLE): cv.string,
35-
vol.Optional(ATTR_VALUE): cv.match_all,
36-
vol.Optional(ATTR_VALUE_TEMPLATE): cv.template,
37-
vol.Optional(ATTR_ATTRIBUTES): dict,
38-
vol.Optional(ATTR_ATTRIBUTES_TEMPLATE): cv.template,
39-
vol.Optional(ATTR_REPLACE_ATTRIBUTES): cv.boolean
40-
})
41-
42-
CONFIG_SCHEMA = vol.Schema({
43-
DOMAIN: vol.Schema({
44-
cv.slug: vol.Any({
45-
vol.Optional(CONF_NAME): cv.string,
46-
vol.Optional(CONF_VALUE): cv.match_all,
47-
vol.Optional(CONF_ATTRIBUTES): dict,
48-
vol.Optional(CONF_RESTORE): cv.boolean,
49-
}, None)
50-
})
51-
}, extra=vol.ALLOW_EXTRA)
32+
SERVICE_SET_VARIABLE_SCHEMA = vol.Schema(
33+
{
34+
vol.Required(ATTR_VARIABLE): cv.string,
35+
vol.Optional(ATTR_VALUE): cv.match_all,
36+
vol.Optional(ATTR_VALUE_TEMPLATE): cv.template,
37+
vol.Optional(ATTR_ATTRIBUTES): dict,
38+
vol.Optional(ATTR_ATTRIBUTES_TEMPLATE): cv.template,
39+
vol.Optional(ATTR_REPLACE_ATTRIBUTES): cv.boolean,
40+
}
41+
)
42+
43+
CONFIG_SCHEMA = vol.Schema(
44+
{
45+
DOMAIN: vol.Schema(
46+
{
47+
cv.slug: vol.Any(
48+
{
49+
vol.Optional(CONF_NAME): cv.string,
50+
vol.Optional(CONF_VALUE): cv.match_all,
51+
vol.Optional(CONF_ATTRIBUTES): dict,
52+
vol.Optional(CONF_RESTORE): cv.boolean,
53+
},
54+
None,
55+
)
56+
}
57+
)
58+
},
59+
extra=vol.ALLOW_EXTRA,
60+
)
61+
5262

5363
@bind_hass
54-
def set_variable(hass, variable, value, value_template, attributes, attributes_template, replace_attributes):
64+
def set_variable(
65+
hass,
66+
variable,
67+
value,
68+
value_template,
69+
attributes,
70+
attributes_template,
71+
replace_attributes,
72+
):
5573
"""Set input_boolean to True."""
56-
hass.services.call(DOMAIN, SERVICE_SET_VARIABLE, {
57-
ATTR_VARIABLE: variable,
58-
ATTR_VALUE: value,
59-
ATTR_VALUE_TEMPLATE: value_template,
60-
ATTR_ATTRIBUTES: attributes,
61-
ATTR_ATTRIBUTES_TEMPLATE: attributes_template,
62-
ATTR_REPLACE_ATTRIBUTES: replace_attributes,
63-
})
74+
hass.services.call(
75+
DOMAIN,
76+
SERVICE_SET_VARIABLE,
77+
{
78+
ATTR_VARIABLE: variable,
79+
ATTR_VALUE: value,
80+
ATTR_VALUE_TEMPLATE: value_template,
81+
ATTR_ATTRIBUTES: attributes,
82+
ATTR_ATTRIBUTES_TEMPLATE: attributes_template,
83+
ATTR_REPLACE_ATTRIBUTES: replace_attributes,
84+
},
85+
)
86+
6487

6588
async def async_setup(hass, config):
6689
"""Set up variables."""
@@ -77,37 +100,45 @@ async def async_setup(hass, config):
77100
attributes = variable_config.get(CONF_ATTRIBUTES)
78101
restore = variable_config.get(CONF_RESTORE, False)
79102

80-
entities.append(Variable(variable_id, name, value, attributes, restore))
103+
entities.append(
104+
Variable(variable_id, name, value, attributes, restore)
105+
)
81106

82107
@asyncio.coroutine
83108
def async_set_variable_service(call):
84109
"""Handle calls to the set_variable service."""
85-
86110
entity_id = ENTITY_ID_FORMAT.format(call.data.get(ATTR_VARIABLE))
87111
entity = component.get_entity(entity_id)
88112

89113
if entity:
90-
target_variables = [ entity ]
91-
tasks = [variable.async_set_variable(
92-
call.data.get(ATTR_VALUE),
93-
call.data.get(ATTR_VALUE_TEMPLATE),
94-
call.data.get(ATTR_ATTRIBUTES),
95-
call.data.get(ATTR_ATTRIBUTES_TEMPLATE),
96-
call.data.get(ATTR_REPLACE_ATTRIBUTES, False))
97-
for variable in target_variables]
114+
target_variables = [entity]
115+
tasks = [
116+
variable.async_set_variable(
117+
call.data.get(ATTR_VALUE),
118+
call.data.get(ATTR_VALUE_TEMPLATE),
119+
call.data.get(ATTR_ATTRIBUTES),
120+
call.data.get(ATTR_ATTRIBUTES_TEMPLATE),
121+
call.data.get(ATTR_REPLACE_ATTRIBUTES, False),
122+
)
123+
for variable in target_variables
124+
]
98125
if tasks:
99126
yield from asyncio.wait(tasks, loop=hass.loop)
100127

101128
else:
102-
_LOGGER.warning('Failed to set unknown variable: %s', entity_id)
129+
_LOGGER.warning("Failed to set unknown variable: %s", entity_id)
103130

104131
hass.services.async_register(
105-
DOMAIN, SERVICE_SET_VARIABLE, async_set_variable_service,
106-
schema=SERVICE_SET_VARIABLE_SCHEMA)
132+
DOMAIN,
133+
SERVICE_SET_VARIABLE,
134+
async_set_variable_service,
135+
schema=SERVICE_SET_VARIABLE_SCHEMA,
136+
)
107137

108138
await component.async_add_entities(entities)
109139
return True
110140

141+
111142
class Variable(RestoreEntity):
112143
"""Representation of a variable."""
113144

@@ -122,10 +153,14 @@ def __init__(self, variable_id, name, value, attributes, restore):
122153
async def async_added_to_hass(self):
123154
"""Run when entity about to be added."""
124155
await super().async_added_to_hass()
125-
if self._restore == True:
156+
if self._restore is True:
157+
# If variable state have been saved.
126158
state = await self.async_get_last_state()
127159
if state:
160+
# restore state
128161
self._value = state.state
162+
# restore value
163+
self._attributes = state.attributes
129164

130165
@property
131166
def should_poll(self):
@@ -142,8 +177,7 @@ def icon(self):
142177
"""Return the icon to be used for this entity."""
143178
if self._attributes is not None:
144179
return self._attributes.get(ATTR_ICON)
145-
else:
146-
return None
180+
return None
147181

148182
@property
149183
def state(self):
@@ -156,9 +190,15 @@ def state_attributes(self):
156190
return self._attributes
157191

158192
@asyncio.coroutine
159-
def async_set_variable(self, value, value_template, attributes, attributes_template, replace_attributes):
193+
def async_set_variable(
194+
self,
195+
value,
196+
value_template,
197+
attributes,
198+
attributes_template,
199+
replace_attributes,
200+
):
160201
"""Update variable."""
161-
162202
current_state = self.hass.states.get(self.entity_id)
163203
updated_attributes = None
164204
updated_value = None
@@ -176,7 +216,11 @@ def async_set_variable(self, value, value_template, attributes, attributes_templ
176216
attributes_template.hass = self.hass
177217

178218
try:
179-
attributes = json.loads(attributes_template.async_render({ 'variable': current_state }))
219+
attributes = json.loads(
220+
attributes_template.async_render(
221+
{"variable": current_state}
222+
)
223+
)
180224

181225
if isinstance(attributes, dict):
182226
if updated_attributes is not None:
@@ -185,23 +229,31 @@ def async_set_variable(self, value, value_template, attributes, attributes_templ
185229
updated_attributes = attributes
186230

187231
except TemplateError as ex:
188-
_LOGGER.error('Could not render attribute_template %s: %s',
189-
self.entity_id, ex)
232+
_LOGGER.error(
233+
"Could not render attribute_template %s: %s",
234+
self.entity_id,
235+
ex,
236+
)
190237

191238
if value is not None:
192239
updated_value = value
193240

194241
elif value_template is not None:
195242
try:
196243
value_template.hass = self.hass
197-
updated_value = value_template.async_render({ 'variable': current_state })
244+
updated_value = value_template.async_render(
245+
{"variable": current_state}
246+
)
198247
except TemplateError as ex:
199-
_LOGGER.error('Could not render value_template %s: %s',
200-
self.entity_id, ex)
248+
_LOGGER.error(
249+
"Could not render value_template %s: %s",
250+
self.entity_id,
251+
ex,
252+
)
201253

202-
self._attributes = updated_attributes;
254+
self._attributes = updated_attributes
203255

204256
if updated_value is not None:
205-
self._value = updated_value;
257+
self._value = updated_value
206258

207-
yield from self.async_update_ha_state()
259+
yield from self.async_update_ha_state()

0 commit comments

Comments
 (0)