11"""Module for the Accessory classes."""
22import itertools
33import logging
4+ from typing import TYPE_CHECKING ,Any ,Callable ,Dict ,Iterable ,List ,Optional
45from uuid import UUID
56
6- from pyhap import SUPPORT_QR_CODE ,util
7- from pyhap .const import (
7+ from . import SUPPORT_QR_CODE ,util
8+ from .const import (
89CATEGORY_BRIDGE ,
910CATEGORY_OTHER ,
1011HAP_PROTOCOL_VERSION ,
1415HAP_REPR_VALUE ,
1516STANDALONE_AID ,
1617)
17- from pyhap .iid_manager import IIDManager
18- from pyhap .service import Service
18+ from .iid_manager import IIDManager
19+ from .service import Service
1920
2021if SUPPORT_QR_CODE :
2122import base36
2223from pyqrcode import QRCode
2324
2425
26+ if TYPE_CHECKING :
27+ from .accessory_driver import AccessoryDriver
28+ from .characteristic import Characteristic
29+
30+
2531HAP_PROTOCOL_INFORMATION_SERVICE_UUID = UUID ("000000A2-0000-1000-8000-0026BB765291" )
2632
2733logger = logging .getLogger (__name__ )
@@ -35,7 +41,13 @@ class Accessory:
3541
3642category = CATEGORY_OTHER
3743
38- def __init__ (self ,driver ,display_name ,aid = None ,iid_manager = None ):
44+ def __init__ (
45+ self ,
46+ driver :"AccessoryDriver" ,
47+ display_name :Optional [str ],
48+ aid :Optional [int ]= None ,
49+ iid_manager :Optional [IIDManager ]= None ,
50+ )-> None :
3951"""Initialise with the given properties.
4052
4153 :param display_name: Name to be displayed in the Home app.
@@ -47,24 +59,24 @@ def __init__(self, driver, display_name, aid=None, iid_manager=None):
4759 will assign the standalone AID to this `Accessory`.
4860 :type aid: int
4961 """
50- self .aid = aid
51- self .display_name = display_name
62+ self .aid : Optional [ int ] = aid
63+ self .display_name : Optional [ str ] = display_name
5264self .driver = driver
53- self .services = []
65+ self .services : List [ Service ] = []
5466self .iid_manager = iid_manager or IIDManager ()
55- self .setter_callback = None
67+ self .setter_callback : Optional [ Callable [[ Any ], None ]] = None
5668
5769self .add_info_service ()
5870if aid == STANDALONE_AID :
5971self .add_protocol_version_service ()
6072
61- def __repr__ (self ):
73+ def __repr__ (self )-> str :
6274"""Return the representation of the accessory."""
6375services = [s .display_name for s in self .services ]
6476return f"<accessory display_name='{ self .display_name } ' services={ services } >"
6577
6678@property
67- def available (self ):
79+ def available (self )-> bool :
6880"""Accessory is available.
6981
7082 If available is False, get_characteristics will return
@@ -75,7 +87,7 @@ def available(self):
7587 """
7688return True
7789
78- def add_info_service (self ):
90+ def add_info_service (self )-> None :
7991"""Helper method to add the required `AccessoryInformation` service.
8092
8193 Called in `__init__` to be sure that it is the first service added.
@@ -116,7 +128,12 @@ def set_info_service(
116128self .display_name ,
117129 )
118130
119- def add_preload_service (self ,service ,chars = None ,unique_id = None ):
131+ def add_preload_service (
132+ self ,
133+ service :Service ,
134+ chars :Optional [Iterable ["Characteristic" ]]= None ,
135+ unique_id :Optional [str ]= None ,
136+ )-> Service :
120137"""Create a service with the given name and add it to this acc."""
121138service = self .driver .loader .get_service (service )
122139if unique_id is not None :
@@ -129,12 +146,12 @@ def add_preload_service(self, service, chars=None, unique_id=None):
129146self .add_service (service )
130147return service
131148
132- def set_primary_service (self ,primary_service ) :
149+ def set_primary_service (self ,primary_service : Service ) -> None :
133150"""Set the primary service of the acc."""
134151for service in self .services :
135152service .is_primary_service = service .type_id == primary_service .type_id
136153
137- def add_service (self ,* servs ) :
154+ def add_service (self ,* servs : Service ) -> None :
138155"""Add the given services to this Accessory.
139156
140157 This also assigns unique IIDS to the services and their Characteristics.
@@ -153,7 +170,7 @@ def add_service(self, *servs):
153170c .broker = self
154171self .iid_manager .assign (c )
155172
156- def get_service (self ,name ) :
173+ def get_service (self ,name : str ) -> Optional [ Service ] :
157174"""Return a Service with the given name.
158175
159176 A single Service is returned even if more than one Service with the same name
@@ -168,7 +185,7 @@ def get_service(self, name):
168185 """
169186return next ((s for s in self .services if s .display_name == name ),None )
170187
171- def xhm_uri (self ):
188+ def xhm_uri (self )-> str :
172189"""Generates the X-HM:// uri (Setup Code URI)
173190
174191 :rtype: str
@@ -195,7 +212,7 @@ def xhm_uri(self):
195212
196213return "X-HM://" + encoded_payload + self .driver .state .setup_id
197214
198- def get_characteristic (self ,aid ,iid ) :
215+ def get_characteristic (self ,aid : int ,iid : int ) -> Optional [ "Characteristic" ] :
199216"""Get the characteristic for the given IID.
200217
201218 The AID is used to verify if the search is in the correct accessory.
@@ -205,7 +222,7 @@ def get_characteristic(self, aid, iid):
205222
206223return self .iid_manager .get_obj (iid )
207224
208- def to_HAP (self ) :
225+ def to_HAP (self , include_value : bool = True ) -> Dict [ str , Any ] :
209226"""A HAP representation of this Accessory.
210227
211228 :return: A HAP representation of this accessory. For example:
@@ -224,7 +241,7 @@ def to_HAP(self):
224241 """
225242return {
226243HAP_REPR_AID :self .aid ,
227- HAP_REPR_SERVICES : [s .to_HAP ()for s in self .services ],
244+ HAP_REPR_SERVICES : [s .to_HAP (include_value = include_value )for s in self .services ],
228245 }
229246
230247def setup_message (self ):
@@ -325,13 +342,18 @@ class Bridge(Accessory):
325342
326343category = CATEGORY_BRIDGE
327344
328- def __init__ (self ,driver ,display_name ,iid_manager = None ):
345+ def __init__ (
346+ self ,
347+ driver :"AccessoryDriver" ,
348+ display_name :Optional [str ],
349+ iid_manager :Optional [IIDManager ]= None ,
350+ )-> None :
329351super ().__init__ (
330352driver ,display_name ,aid = STANDALONE_AID ,iid_manager = iid_manager
331353 )
332354self .accessories = {}# aid: acc
333355
334- def add_accessory (self ,acc ) :
356+ def add_accessory (self ,acc : "Accessory" ) -> None :
335357"""Add the given ``Accessory`` to this ``Bridge``.
336358
337359 Every ``Accessory`` in a ``Bridge`` must have an AID and this AID must be
@@ -364,14 +386,14 @@ def add_accessory(self, acc):
364386
365387self .accessories [acc .aid ]= acc
366388
367- def to_HAP (self ) :
389+ def to_HAP (self , include_value : bool = True ) -> List [ Dict [ str , Any ]] :
368390"""Returns a HAP representation of itself and all contained accessories.
369391
370392 .. seealso:: Accessory.to_HAP
371393 """
372- return [acc .to_HAP ()for acc in (super (),* self .accessories .values ())]
394+ return [acc .to_HAP (include_value = include_value )for acc in (super (),* self .accessories .values ())]
373395
374- def get_characteristic (self ,aid ,iid ) :
396+ def get_characteristic (self ,aid : int ,iid : int ) -> Optional [ "Characteristic" ] :
375397""".. seealso:: Accessory.to_HAP"""
376398if self .aid == aid :
377399return self .iid_manager .get_obj (iid )
@@ -382,17 +404,17 @@ def get_characteristic(self, aid, iid):
382404
383405return acc .get_characteristic (aid ,iid )
384406
385- async def run (self ):
407+ async def run (self )-> None :
386408"""Schedule tasks for each of the accessories' run method."""
387409for acc in self .accessories .values ():
388410self .driver .async_add_job (acc .run )
389411
390- async def stop (self ):
412+ async def stop (self )-> None :
391413"""Calls stop() on all contained accessories."""
392414await self .driver .async_add_job (super ().stop )
393415for acc in self .accessories .values ():
394416await self .driver .async_add_job (acc .stop )
395417
396418
397- def get_topic (aid ,iid ) :
419+ def get_topic (aid : int ,iid : int ) -> str :
398420return str (aid )+ "." + str (iid )