66
77import asyncio
88import datetime as dt
9- from typing import Any , cast
109
1110# This way of importing aiohttp is because of patch/mocking in testing (aiohttp timeouts)
1211from aiohttp import BasicAuth , ClientError , ClientResponse , ClientSession , ClientTimeout
4948 THERMOSTAT_CLASSES ,
5049 TOGGLES ,
5150 UOM ,
51+ ActuatorData ,
5252 ApplianceData ,
5353 DeviceData ,
54- DeviceDataPoints ,
5554 GatewayData ,
5655 ModelData ,
5756 SmileBinarySensors ,
7271 version_to_model ,
7372)
7473
74+ # from typing import cast
75+
7576
7677def update_helper (
77- data : DeviceDataPoints ,
78+ data : DeviceData ,
7879 devices : dict [str , DeviceData ],
7980 device_dict : DeviceData ,
8081 device_id : str ,
@@ -102,20 +103,20 @@ def check_model(name: str | None, vendor_name: str | None) -> str | None:
102103 return name
103104
104105
105- def _get_actuator_functionalities (xml : etree , data : dict [ str , Any ] ) -> None :
106+ def _get_actuator_functionalities (xml : etree , data : DeviceData ) -> None :
106107 """Helper-function for _get_appliance_data()."""
107108 for item in ACTIVE_ACTUATORS :
108- temp_dict : dict [ str , float ] = {}
109+ temp_dict : ActuatorData = {}
109110 for key in LIMITS :
110111 locator = f'.//actuator_functionalities/thermostat_functionality[type="{ item } "]/{ key } '
111112 if (function := xml .find (locator )) is not None :
112113 if function .text == "nil" :
113114 break
114115
115- temp_dict . update ({ key : format_measure (function .text , TEMP_CELSIUS )})
116+ temp_dict [ key ] = format_measure (function .text , TEMP_CELSIUS ) # type: ignore [literal-required]
116117
117118 if temp_dict :
118- data [item ] = temp_dict
119+ data [item ] = temp_dict # type: ignore [literal-required]
119120
120121
121122def schedules_temps (
@@ -443,12 +444,12 @@ def _get_module_data(
443444 """
444445 model_data : ModelData = {
445446 "contents" : False ,
447+ "firmware_version" : None ,
448+ "hardware_version" : None ,
449+ "reachable" : None ,
446450 "vendor_name" : None ,
447451 "vendor_model" : None ,
448- "hardware_version" : None ,
449- "firmware_version" : None ,
450452 "zigbee_mac_address" : None ,
451- "available" : None ,
452453 }
453454 if (appl_search := appliance .find (locator )) is not None :
454455 link_id = appl_search .attrib ["id" ]
@@ -466,7 +467,7 @@ def _get_module_data(
466467 # Adam
467468 if found := module .find ("./protocols/zig_bee_node" ):
468469 model_data ["zigbee_mac_address" ] = found .find ("mac_address" ).text
469- model_data ["available " ] = found .find ("reachable" ).text == "true"
470+ model_data ["reachable " ] = found .find ("reachable" ).text == "true"
470471 # Stretches
471472 if found := module .find ("./protocols/network_router" ):
472473 model_data ["zigbee_mac_address" ] = found .find ("mac_address" ).text
@@ -873,7 +874,7 @@ def _rule_ids_by_tag(self, tag: str, loc_id: str) -> dict[str, str]:
873874 def _appliance_measurements (
874875 self ,
875876 appliance : etree ,
876- data : dict [ str , Any ] ,
877+ data : DeviceData ,
877878 measurements : dict [str , DATA | UOM ],
878879 ) -> None :
879880 """Helper-function for _get_appliance_data() - collect appliance measurement data."""
@@ -894,28 +895,28 @@ def _appliance_measurements(
894895 if new_name := getattr (attrs , ATTR_NAME , None ):
895896 measurement = new_name
896897
897- data [measurement ] = appl_p_loc .text
898+ data [measurement ] = appl_p_loc .text # type: ignore [literal-required]
898899 # measurements with states "on" or "off" that need to be passed directly
899900 if measurement not in ("dhw_mode" ):
900- data [measurement ] = format_measure (
901+ data [measurement ] = format_measure ( # type: ignore [literal-required]
901902 appl_p_loc .text , getattr (attrs , ATTR_UNIT_OF_MEASUREMENT )
902903 )
903904
904905 # Anna: save cooling-related measurements for later use
905906 # Use the local outdoor temperature as reference for turning cooling on/off
906907 if measurement == "cooling_activation_outdoor_temperature" :
907- self ._cooling_activation_outdoor_temp = data [measurement ]
908+ self ._cooling_activation_outdoor_temp = data [measurement ] # type: ignore [literal-required]
908909 if measurement == "cooling_deactivation_threshold" :
909- self ._cooling_deactivation_threshold = data [measurement ]
910+ self ._cooling_deactivation_threshold = data [measurement ] # type: ignore [literal-required]
910911 if measurement == "outdoor_air_temperature" :
911- self ._outdoor_temp = data [measurement ]
912+ self ._outdoor_temp = data [measurement ] # type: ignore [literal-required]
912913
913914 i_locator = f'.//logs/interval_log[type="{ measurement } "]/period/measurement'
914915 if (appl_i_loc := appliance .find (i_locator )) is not None :
915916 name = f"{ measurement } _interval"
916- data [name ] = format_measure (appl_i_loc .text , ENERGY_WATT_HOUR )
917+ data [name ] = format_measure (appl_i_loc .text , ENERGY_WATT_HOUR ) # type: ignore [literal-required]
917918
918- def _wireless_availablity (self , appliance : etree , data : dict [ str , Any ] ) -> None :
919+ def _wireless_availablity (self , appliance : etree , data : DeviceData ) -> None :
919920 """
920921 Helper-function for _get_appliance_data().
921922
@@ -926,16 +927,16 @@ def _wireless_availablity(self, appliance: etree, data: dict[str, Any]) -> None:
926927 locator = "./logs/interval_log/electricity_interval_meter"
927928 mod_type = "electricity_interval_meter"
928929 module_data = self ._get_module_data (appliance , locator , mod_type )
929- if module_data ["available " ] is None :
930+ if module_data ["reachable " ] is None :
930931 # Collect for wireless thermostats
931932 locator = "./logs/point_log[type='thermostat']/thermostat"
932933 mod_type = "thermostat"
933934 module_data = self ._get_module_data (appliance , locator , mod_type )
934935
935- if module_data ["available " ] is not None :
936- data ["available" ] = module_data ["available " ]
936+ if module_data ["reachable " ] is not None :
937+ data ["available" ] = module_data ["reachable " ]
937938
938- def _get_regulation_mode (self , appliance : etree , data : dict [ str , Any ] ) -> None :
939+ def _get_regulation_mode (self , appliance : etree , data : DeviceData ) -> None :
939940 """
940941 Helper-function for _get_appliance_data().
941942
@@ -946,7 +947,7 @@ def _get_regulation_mode(self, appliance: etree, data: dict[str, Any]) -> None:
946947 data ["regulation_mode" ] = search .find ("mode" ).text
947948 self ._cooling_enabled = search .find ("mode" ).text == "cooling"
948949
949- def _cleanup_data (self , data : dict [ str , Any ] ) -> None :
950+ def _cleanup_data (self , data : DeviceData ) -> None :
950951 """
951952 Helper-function for _get_appliance_data().
952953
@@ -960,12 +961,12 @@ def _cleanup_data(self, data: dict[str, Any]) -> None:
960961 if not self ._cooling_present :
961962 for item in ("cooling_state" , "cooling_ena_switch" ):
962963 if item in data :
963- data .pop (item )
964+ data .pop (item ) # type: ignore [misc]
964965 # Keep cooling_enabled for Elga
965966 if not self ._elga and "cooling_enabled" in data :
966967 data .pop ("cooling_enabled" ) # pragma: no cover
967968
968- def _process_c_heating_state (self , data : dict [ str , Any ] ) -> None :
969+ def _process_c_heating_state (self , data : DeviceData ) -> None :
969970 """
970971 Helper-function for _get_appliance_data().
971972
@@ -992,10 +993,10 @@ def _get_appliance_data(self, d_id: str) -> DeviceData:
992993 Collect the appliance-data based on device id.
993994 Determined from APPLIANCES, for legacy from DOMAIN_OBJECTS.
994995 """
995- data : dict [ str , Any ] = {}
996+ data : DeviceData = {}
996997 # P1 legacy has no APPLIANCES, also not present in DOMAIN_OBJECTS
997998 if self ._smile_legacy and self .smile_type == "power" :
998- return cast ( DeviceData , data )
999+ return data
9991000
10001001 measurements = DEVICE_MEASUREMENTS
10011002 if d_id == self ._heater_id :
@@ -1055,7 +1056,7 @@ def _get_appliance_data(self, d_id: str) -> DeviceData:
10551056
10561057 self ._cleanup_data (data )
10571058
1058- return cast ( DeviceData , data )
1059+ return data
10591060
10601061 def _rank_thermostat (
10611062 self ,
@@ -1439,7 +1440,7 @@ def _object_value(self, obj_id: str, measurement: str) -> float | int | None:
14391440
14401441 return val
14411442
1442- def _get_lock_state (self , xml : etree , data : dict [ str , Any ] ) -> None :
1443+ def _get_lock_state (self , xml : etree , data : DeviceData ) -> None :
14431444 """
14441445 Helper-function for _get_appliance_data().
14451446
@@ -1456,7 +1457,7 @@ def _get_lock_state(self, xml: etree, data: dict[str, Any]) -> None:
14561457 data ["lock" ] = found .text == "true"
14571458
14581459 def _get_toggle_state (
1459- self , xml : etree , toggle : str , name : str , data : dict [ str , Any ]
1460+ self , xml : etree , toggle : str , name : str , data : DeviceData
14601461 ) -> None :
14611462 """
14621463 Helper-function for _get_appliance_data().
@@ -1469,7 +1470,7 @@ def _get_toggle_state(
14691470 for item in found :
14701471 if (toggle_type := item .find ("type" )) is not None :
14711472 if toggle_type .text == toggle :
1472- data . update ({ name : item .find ("state" ).text == "on" })
1473+ data [ name ] = item .find ("state" ).text == "on" # type: ignore [literal-required]
14731474 # Remove the cooling_enabled key when the corresponding toggle is present
14741475 # Except for Elga
14751476 if toggle == "cooling_enabled" and not self ._elga :
0 commit comments