"""
Various classes that construct representations of
HAP services and characteristics from a json
representation.
The idea is, give a name of a service and you get an
instance of it (as long as it is described in some
json file).
"""
import logging
import orjson
from pyhap import CHARACTERISTICS_FILE, SERVICES_FILE
from pyhap.characteristic import Characteristic
from pyhap.service import Service
_loader = None
logger = logging.getLogger(__name__)
[docs]class Loader:
"""Looks up type descriptions based on a name.
.. seealso:: pyhap/resources/services.json
.. seealso:: pyhap/resources/characteristics.json
"""
def __init__(self, path_char=CHARACTERISTICS_FILE, path_service=SERVICES_FILE):
"""Initialize a new Loader instance."""
self.char_types = self._read_file(path_char)
self.serv_types = self._read_file(path_service)
@staticmethod
def _read_file(path):
"""Read file and return a dict."""
with open(path, "r", encoding="utf8") as file:
return orjson.loads(file.read()) # pylint: disable=no-member
[docs] def get_char(self, name):
"""Return new Characteristic object."""
char_dict = self.char_types[name].copy()
if (
"Format" not in char_dict
or "Permissions" not in char_dict
or "UUID" not in char_dict
):
raise KeyError(f"Could not load char {name}!")
return Characteristic.from_dict(name, char_dict, from_loader=True)
[docs] def get_service(self, name):
"""Return new service object."""
service_dict = self.serv_types[name].copy()
if "RequiredCharacteristics" not in service_dict or "UUID" not in service_dict:
raise KeyError(f"Could not load service {name}!")
return Service.from_dict(name, service_dict, self)
[docs] @classmethod
def from_dict(cls, char_dict=None, serv_dict=None):
"""Create a new instance directly from json dicts."""
loader = cls.__new__(Loader)
loader.char_types = char_dict or {}
loader.serv_types = serv_dict or {}
return loader
def get_loader():
"""Get a service and char loader.
If already initialized it returns the existing one.
"""
# pylint: disable=global-statement
global _loader
if _loader is None:
_loader = Loader()
return _loader