"""This module implements the HAP Service."""
from pyhap.const import (
HAP_REPR_CHARS,
HAP_REPR_IID,
HAP_REPR_LINKED,
HAP_REPR_PRIMARY,
HAP_REPR_TYPE,
)
from .util import hap_type_to_uuid, uuid_to_hap_type
[docs]class Service:
"""A representation of a HAP service.
A Service contains multiple characteristics. For example, a
TemperatureSensor service has the characteristic CurrentTemperature.
"""
__slots__ = (
"broker",
"characteristics",
"display_name",
"type_id",
"linked_services",
"is_primary_service",
"setter_callback",
"unique_id",
"_uuid_str",
)
def __init__(self, type_id, display_name=None, unique_id=None):
"""Initialize a new Service object."""
self.broker = None
self.characteristics = []
self.linked_services = []
self.display_name = display_name
self.type_id = type_id
self.is_primary_service = None
self.setter_callback = None
self.unique_id = unique_id
self._uuid_str = uuid_to_hap_type(type_id)
def __repr__(self):
"""Return the representation of the service."""
chars_dict = {c.display_name: c.value for c in self.characteristics}
return f"<service display_name={self.display_name} unique_id={self.unique_id} chars={chars_dict}>"
[docs] def add_linked_service(self, service):
"""Add the given service as "linked" to this Service."""
if not any(
self.broker.iid_manager.get_iid(service)
== self.broker.iid_manager.get_iid(original_service)
for original_service in self.linked_services
):
self.linked_services.append(service)
[docs] def add_characteristic(self, *chars):
"""Add the given characteristics as "mandatory" for this Service."""
for char in chars:
if not any(
char.type_id == original_char.type_id
for original_char in self.characteristics
):
char.service = self
self.characteristics.append(char)
[docs] def get_characteristic(self, name):
"""Return a Characteristic object by the given name from this Service.
:param name: The name of the characteristic to search for.
:type name: str
:raise ValueError if characteristic is not found.
:return: A characteristic with the given name.
:rtype: Characteristic
"""
for char in self.characteristics:
if char.display_name == name:
return char
raise ValueError("Characteristic not found")
# pylint: disable=invalid-name
[docs] def to_HAP(self):
"""Create a HAP representation of this Service.
:return: A HAP representation.
:rtype: dict.
"""
hap = {
HAP_REPR_IID: self.broker.iid_manager.get_iid(self),
HAP_REPR_TYPE: self._uuid_str,
HAP_REPR_CHARS: [c.to_HAP() for c in self.characteristics],
}
if self.is_primary_service is not None:
hap[HAP_REPR_PRIMARY] = self.is_primary_service
if self.linked_services:
hap[HAP_REPR_LINKED] = []
for linked_service in self.linked_services:
hap[HAP_REPR_LINKED].append(
linked_service.broker.iid_manager.get_iid(linked_service)
)
return hap
[docs] @classmethod
def from_dict(cls, name, json_dict, loader):
"""Initialize a service object from a dict.
:param json_dict: Dictionary containing at least the keys `UUID` and
`RequiredCharacteristics`
:type json_dict: dict
"""
type_id = hap_type_to_uuid(json_dict.pop("UUID"))
service = cls(type_id, name)
for char_name in json_dict["RequiredCharacteristics"]:
service.add_characteristic(loader.get_char(char_name))
return service