|
13 | 13 | _LOGGER = logging.getLogger(LOGGER_PATH + ".state")
|
14 | 14 |
|
15 | 15 |
|
| 16 | +class StateVar(str): |
| 17 | + """Class for representing the value and attributes of a state variable.""" |
| 18 | + |
| 19 | + def __new__(cls, state): |
| 20 | + """Create a new instance given a state variable.""" |
| 21 | + new_var = super().__new__(cls, state.state) |
| 22 | + new_var.__dict__ = state.attributes.copy() |
| 23 | + new_var.last_updated = state.last_updated |
| 24 | + new_var.last_changed = state.last_changed |
| 25 | + return new_var |
| 26 | + |
| 27 | + |
16 | 28 | class State:
|
17 | 29 | """Class for state functions."""
|
18 | 30 |
|
@@ -217,21 +229,15 @@ async def get(cls, var_name):
|
217 | 229 | parts = var_name.split(".")
|
218 | 230 | if len(parts) != 2 and len(parts) != 3:
|
219 | 231 | raise NameError(f"invalid name '{var_name}' (should be 'domain.entity' or 'domain.entity.attr')")
|
220 |
| - value = cls.hass.states.get(f"{parts[0]}.{parts[1]}") |
221 |
| - if not value: |
| 232 | + state = cls.hass.states.get(f"{parts[0]}.{parts[1]}") |
| 233 | + if not state: |
222 | 234 | raise NameError(f"name '{parts[0]}.{parts[1]}' is not defined")
|
223 | 235 | #
|
224 | 236 | # simplest case is just the state value
|
225 | 237 | #
|
| 238 | + state = StateVar(state) |
226 | 239 | if len(parts) == 2:
|
227 |
| - return value.state |
228 |
| - # |
229 |
| - # handle virtual attributes |
230 |
| - # |
231 |
| - if parts[2] == "last_changed": |
232 |
| - return value.last_changed |
233 |
| - if parts[2] == "last_updated": |
234 |
| - return value.last_updated |
| 240 | + return state |
235 | 241 | #
|
236 | 242 | # see if this is a service that has an entity_id parameter
|
237 | 243 | #
|
@@ -264,9 +270,12 @@ async def service_call(*args, **kwargs):
|
264 | 270 | #
|
265 | 271 | # finally see if it is an attribute
|
266 | 272 | #
|
267 |
| - if parts[2] not in value.attributes: |
268 |
| - raise AttributeError(f"state '{parts[0]}.{parts[1]}' has no attribute '{parts[2]}'") |
269 |
| - return value.attributes.get(parts[2]) |
| 273 | + try: |
| 274 | + return getattr(state, parts[2]) |
| 275 | + except AttributeError: |
| 276 | + raise AttributeError( # pylint: disable=raise-missing-from |
| 277 | + f"state '{parts[0]}.{parts[1]}' has no attribute '{parts[2]}'" |
| 278 | + ) |
270 | 279 |
|
271 | 280 | @classmethod
|
272 | 281 | async def getattr(cls, var_name):
|
|
0 commit comments