Add generic interface for accessing device features (#741)

This adds a generic interface for all device classes to introspect available device features,
that is necessary to make it easier to support a wide variety of supported devices with different set of features.
This will allow constructing generic interfaces (e.g., in homeassistant) that fetch and change these features without hard-coding the API calls.

`Device.features()` now returns a mapping of `<identifier, Feature>` where the `Feature` contains all necessary information (like the name, the icon, a way to get and change the setting) to present and change the defined feature through its interface.
This commit is contained in:
Teemu R
2024-02-15 16:25:08 +01:00
committed by GitHub
parent 57835276e3
commit 64da736717
12 changed files with 345 additions and 28 deletions

View File

@@ -3,13 +3,14 @@ import logging
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime
from typing import Any, Dict, List, Optional, Sequence, Set, Union
from typing import Any, Dict, List, Optional, Sequence, Union
from .credentials import Credentials
from .device_type import DeviceType
from .deviceconfig import DeviceConfig
from .emeterstatus import EmeterStatus
from .exceptions import SmartDeviceException
from .feature import Feature
from .iotprotocol import IotProtocol
from .protocol import BaseProtocol
from .xortransport import XorTransport
@@ -69,6 +70,7 @@ class Device(ABC):
self._discovery_info: Optional[Dict[str, Any]] = None
self.modules: Dict[str, Any] = {}
self._features: Dict[str, Feature] = {}
@staticmethod
async def connect(
@@ -296,9 +298,16 @@ class Device(ABC):
"""Return the key state information."""
@property
@abstractmethod
def features(self) -> Set[str]:
def features(self) -> Dict[str, Feature]:
"""Return the list of supported features."""
return self._features
def _add_feature(self, feature: Feature):
"""Add a new feature to the device."""
desc_name = feature.name.lower().replace(" ", "_")
if desc_name in self._features:
raise SmartDeviceException("Duplicate feature name %s" % desc_name)
self._features[desc_name] = feature
@property
@abstractmethod