2020from pydantic import Field
2121
2222from homeassistant_api .errors import RequestError
23+ from homeassistant_api .utils import JSONType
2324
2425from .base import BaseModel
2526from .states import State
@@ -55,13 +56,13 @@ def __init__(
5556
5657 @classmethod
5758 def from_json (
58- cls , json : Dict [str , Any ], client : Union ["Client" , "WebsocketClient" ]
59+ cls , json : Dict [str , JSONType ], client : Union ["Client" , "WebsocketClient" ]
5960 ) -> "Domain" :
6061 """Constructs Domain and Service models from json data."""
6162 if "domain" not in json or "services" not in json :
6263 raise ValueError ("Missing services or domain attribute in json argument." )
6364 domain = cls (domain_id = cast (str , json .get ("domain" )), _client = client )
64- services = json .get ("services" )
65+ services = cast ( dict [ str , dict [ str , JSONType ]], json .get ("services" ) )
6566 assert isinstance (services , dict )
6667 for service_id , data in services .items ():
6768 domain ._add_service (service_id , ** data )
@@ -103,8 +104,6 @@ def __getattr__(self, attr: str):
103104# https://github.com/home-assistant/frontend/blob/dev/src/data/selector.ts
104105# https://github.com/home-assistant/home-assistant-js-websocket/blob/master/lib/types.ts
105106
106- number = Union [int , float ]
107-
108107
109108# Helpers
110109class ServiceFieldSelectorEntityFilter (BaseModel ):
@@ -124,8 +123,8 @@ class ServiceFieldSelectorDeviceFilter(BaseModel):
124123class CropOptions (BaseModel ):
125124 round : bool
126125 type : Optional [str ] # "image/jpeg" / "image/png"
127- quality : Optional [number ] = None
128- aspectRatio : Optional [number ] = None
126+ quality : Optional [int | float ] = None
127+ aspectRatio : Optional [int | float ] = None
129128
130129
131130class SelectBoxOptionImage (BaseModel ):
@@ -226,10 +225,10 @@ class ServiceFieldSelectorColorRGB(BaseModel):
226225
227226class ServiceFieldSelectorColorTemp (BaseModel ):
228227 unit : Optional [str ] = None
229- min : Optional [number ] = None
230- max : Optional [number ] = None
231- min_mireds : Optional [number ] = None
232- max_mireds : Optional [number ] = None
228+ min : Optional [int | float ] = None
229+ max : Optional [int | float ] = None
230+ min_mireds : Optional [int | float ] = None
231+ max_mireds : Optional [int | float ] = None
233232
234233
235234class ServiceFieldSelectorCondition (BaseModel ):
@@ -242,7 +241,7 @@ class ServiceFieldSelectorConfigEntry(BaseModel):
242241
243242class ServiceFieldSelectorConstant (BaseModel ):
244243 label : Optional [str ] = None
245- value : Union [str , number , bool ]
244+ value : Union [str , int , float , bool ]
246245 translation_key : Optional [str ] = None
247246
248247
@@ -349,9 +348,9 @@ class ServiceFieldSelectorNavigation(BaseModel):
349348
350349
351350class ServiceFieldSelectorNumber (BaseModel ):
352- min : Optional [number ] = None
353- max : Optional [number ] = None
354- step : Optional [Union [number , str ]] = None
351+ min : Optional [int | float ] = None
352+ max : Optional [int | float ] = None
353+ step : Optional [Union [int | float , str ]] = None
355354 unit_of_measurement : Optional [str ] = None
356355 mode : Optional [ServiceFieldSelectorNumberMode ] = None
357356 slider_ticks : Optional [bool ] = None
@@ -374,7 +373,7 @@ class ServiceFieldSelectorObject(BaseModel):
374373
375374class ServiceFieldSelectorQRCode (BaseModel ):
376375 data : str
377- scale : Optional [number ] = None
376+ scale : Optional [int | float ] = None
378377 error_correction_level : Optional [ServiceFieldSelectorQRCodeErrorCorrectionLevel ] = (
379378 None
380379 )
@@ -555,14 +554,12 @@ class ServiceField(BaseModel):
555554 """Model for service parameters/fields."""
556555
557556 description : Optional [str ] = None
558- example : Optional [Union [ str , number , bool , List [ str ], Dict ] ] = None
559- default : Optional [Union [ str , number , bool , List [ str ], Dict ] ] = None
557+ example : Optional [JSONType ] = None
558+ default : Optional [JSONType ] = None
560559 name : Optional [str ] = None
561560 required : Optional [bool ] = None
562561 advanced : Optional [bool ] = None
563- selector : Optional [Dict [str , Any ]] = (
564- None # TODO: I believe it would be beneficial to parse it the way I do
565- )
562+ selector : Optional [ServiceFieldSelector ] = None
566563 filter : Optional [ServiceFieldFilter ] = None
567564
568565
@@ -588,8 +585,8 @@ class Service(BaseModel):
588585
589586 def trigger (self , entity_id : Optional [str ] = None , ** service_data ) -> Union [
590587 Tuple [State , ...],
591- Tuple [Tuple [State , ...], Dict [str , Any ]],
592- dict [str , Any ],
588+ Tuple [Tuple [State , ...], dict [str , JSONType ]],
589+ dict [str , JSONType ],
593590 None ,
594591 ]:
595592 """Triggers the service associated with this object."""
@@ -612,7 +609,7 @@ def trigger(self, entity_id: Optional[str] = None, **service_data) -> Union[
612609
613610 async def async_trigger (
614611 self , entity_id : Optional [str ] = None , ** service_data
615- ) -> Union [Tuple [State , ...], Tuple [Tuple [State , ...], Dict [str , Any ]]]:
612+ ) -> Union [Tuple [State , ...], Tuple [Tuple [State , ...], dict [str , JSONType ]]]:
616613 """Triggers the service associated with this object."""
617614 if entity_id is not None :
618615 service_data ["entity_id" ] = entity_id
@@ -639,12 +636,14 @@ async def async_trigger(
639636 def __call__ (self , entity_id : Optional [str ] = None , ** service_data ) -> Union [
640637 Union [
641638 Tuple [State , ...],
642- Tuple [Tuple [State , ...], Dict [str , Any ]],
643- dict [str , Any ],
639+ Tuple [Tuple [State , ...], dict [str , JSONType ]],
640+ dict [str , JSONType ],
644641 None ,
645642 ],
646643 Coroutine [
647- Any , Any , Union [Tuple [State , ...], Tuple [Tuple [State , ...], Dict [str , Any ]]]
644+ Any ,
645+ Any ,
646+ Union [Tuple [State , ...], Tuple [Tuple [State , ...], dict [str , JSONType ]]],
648647 ],
649648 ]:
650649 """
0 commit comments