1
+ """variable implementation for Homme Assistant."""
1
2
import asyncio
2
3
import logging
3
4
import json
4
5
5
6
import voluptuous as vol
6
7
7
- from homeassistant .const import ( CONF_NAME , ATTR_ICON )
8
+ from homeassistant .const import CONF_NAME , ATTR_ICON
8
9
from homeassistant .helpers import config_validation as cv
9
- from homeassistant .helpers import template
10
10
from homeassistant .exceptions import TemplateError
11
11
from homeassistant .loader import bind_hass
12
- from homeassistant .helpers .entity import Entity
13
12
from homeassistant .helpers .entity_component import EntityComponent
14
13
from homeassistant .helpers .restore_state import RestoreEntity
15
14
16
15
_LOGGER = logging .getLogger (__name__ )
17
16
18
- DOMAIN = ' variable'
19
- ENTITY_ID_FORMAT = DOMAIN + ' .{}'
17
+ DOMAIN = " variable"
18
+ ENTITY_ID_FORMAT = DOMAIN + " .{}"
20
19
21
20
CONF_ATTRIBUTES = "attributes"
22
21
CONF_VALUE = "value"
23
22
CONF_RESTORE = "restore"
24
23
25
24
ATTR_VARIABLE = "variable"
26
- ATTR_VALUE = ' value'
27
- ATTR_VALUE_TEMPLATE = ' value_template'
25
+ ATTR_VALUE = " value"
26
+ ATTR_VALUE_TEMPLATE = " value_template"
28
27
ATTR_ATTRIBUTES = "attributes"
29
28
ATTR_ATTRIBUTES_TEMPLATE = "attributes_template"
30
29
ATTR_REPLACE_ATTRIBUTES = "replace_attributes"
31
30
32
31
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
+
52
62
53
63
@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
+ ):
55
73
"""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
+
64
87
65
88
async def async_setup (hass , config ):
66
89
"""Set up variables."""
@@ -77,37 +100,45 @@ async def async_setup(hass, config):
77
100
attributes = variable_config .get (CONF_ATTRIBUTES )
78
101
restore = variable_config .get (CONF_RESTORE , False )
79
102
80
- entities .append (Variable (variable_id , name , value , attributes , restore ))
103
+ entities .append (
104
+ Variable (variable_id , name , value , attributes , restore )
105
+ )
81
106
82
107
@asyncio .coroutine
83
108
def async_set_variable_service (call ):
84
109
"""Handle calls to the set_variable service."""
85
-
86
110
entity_id = ENTITY_ID_FORMAT .format (call .data .get (ATTR_VARIABLE ))
87
111
entity = component .get_entity (entity_id )
88
112
89
113
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
+ ]
98
125
if tasks :
99
126
yield from asyncio .wait (tasks , loop = hass .loop )
100
127
101
128
else :
102
- _LOGGER .warning (' Failed to set unknown variable: %s' , entity_id )
129
+ _LOGGER .warning (" Failed to set unknown variable: %s" , entity_id )
103
130
104
131
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
+ )
107
137
108
138
await component .async_add_entities (entities )
109
139
return True
110
140
141
+
111
142
class Variable (RestoreEntity ):
112
143
"""Representation of a variable."""
113
144
@@ -122,10 +153,14 @@ def __init__(self, variable_id, name, value, attributes, restore):
122
153
async def async_added_to_hass (self ):
123
154
"""Run when entity about to be added."""
124
155
await super ().async_added_to_hass ()
125
- if self ._restore == True :
156
+ if self ._restore is True :
157
+ # If variable state have been saved.
126
158
state = await self .async_get_last_state ()
127
159
if state :
160
+ # restore state
128
161
self ._value = state .state
162
+ # restore value
163
+ self ._attributes = state .attributes
129
164
130
165
@property
131
166
def should_poll (self ):
@@ -142,8 +177,7 @@ def icon(self):
142
177
"""Return the icon to be used for this entity."""
143
178
if self ._attributes is not None :
144
179
return self ._attributes .get (ATTR_ICON )
145
- else :
146
- return None
180
+ return None
147
181
148
182
@property
149
183
def state (self ):
@@ -156,9 +190,15 @@ def state_attributes(self):
156
190
return self ._attributes
157
191
158
192
@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
+ ):
160
201
"""Update variable."""
161
-
162
202
current_state = self .hass .states .get (self .entity_id )
163
203
updated_attributes = None
164
204
updated_value = None
@@ -176,7 +216,11 @@ def async_set_variable(self, value, value_template, attributes, attributes_templ
176
216
attributes_template .hass = self .hass
177
217
178
218
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
+ )
180
224
181
225
if isinstance (attributes , dict ):
182
226
if updated_attributes is not None :
@@ -185,23 +229,31 @@ def async_set_variable(self, value, value_template, attributes, attributes_templ
185
229
updated_attributes = attributes
186
230
187
231
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
+ )
190
237
191
238
if value is not None :
192
239
updated_value = value
193
240
194
241
elif value_template is not None :
195
242
try :
196
243
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
+ )
198
247
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
+ )
201
253
202
- self ._attributes = updated_attributes ;
254
+ self ._attributes = updated_attributes
203
255
204
256
if updated_value is not None :
205
- self ._value = updated_value ;
257
+ self ._value = updated_value
206
258
207
- yield from self .async_update_ha_state ()
259
+ yield from self .async_update_ha_state ()
0 commit comments