@@ -125,7 +125,7 @@ def schedules_schedule_temp(schedules: dict[str, Any], name: str) -> Any:
125125 return None
126126
127127
128- def types_finder (data : etree ) -> set [str ]:
128+ def types_finder (data : etree ) -> set [str | None ]:
129129 """Detect types within locations from logs."""
130130 types = set ()
131131 for measure , attrs in HOME_MEASUREMENTS .items ():
@@ -449,42 +449,50 @@ def _get_module_data(
449449
450450 return model_data
451451
452- def _energy_device_info_finder (self , appliance : etree , appl : Munch ) -> Munch :
452+ def _energy_device_info_finder (self , appliance : etree , appl : Munch ) -> Munch | None :
453453 """Helper-function for _appliance_info_finder().
454454 Collect energy device info (Circle, Plug, Stealth): firmware, model and vendor name.
455455 """
456456 if self ._stretch_v2 or self ._stretch_v3 :
457457 locator = "./services/electricity_point_meter"
458458 mod_type = "electricity_point_meter"
459+
459460 module_data = self ._get_module_data (appliance , locator , mod_type )
460- if not module_data ["contents" ]:
461+ # Filter appliance without zigbee_mac, it's an orphaned device
462+ appl .zigbee_mac = module_data ["zigbee_mac_address" ]
463+ if appl .zigbee_mac is None :
461464 return None
462465
463466 appl .v_name = module_data ["vendor_name" ]
464- if appl .model != "Switchgroup" :
465- appl .model = None
466467 appl .hw = module_data ["hardware_version" ]
467468 if appl .hw :
468469 hw_version = module_data ["hardware_version" ].replace ("-" , "" )
469470 appl .model = version_to_model (hw_version )
470471 appl .fw = module_data ["firmware_version" ]
471- appl . zigbee_mac = module_data [ "zigbee_mac_address" ]
472+
472473 return appl
473474
474475 if self .smile_type != "stretch" and "plug" in appl .types :
475476 locator = "./logs/point_log/electricity_point_meter"
476477 mod_type = "electricity_point_meter"
477478 module_data = self ._get_module_data (appliance , locator , mod_type )
479+ # Filter appliance without zigbee_mac, it's an orphaned device
480+ appl .zigbee_mac = module_data ["zigbee_mac_address" ]
481+ if appl .zigbee_mac is None :
482+ return None
483+
478484 appl .v_name = module_data ["vendor_name" ]
479485 appl .model = version_to_model (module_data ["vendor_model" ])
480486 appl .hw = module_data ["hardware_version" ]
481487 appl .fw = module_data ["firmware_version" ]
482- appl . zigbee_mac = module_data [ "zigbee_mac_address" ]
488+
483489 return appl
484490
491+ return appl # pragma: no cover
492+
485493 def _appliance_info_finder (self , appliance : etree , appl : Munch ) -> Munch :
486494 """Collect device info (Smile/Stretch, Thermostats, OpenTherm/On-Off): firmware, model and vendor name."""
487- # Find gateway and heater_central devices
495+ # Collect gateway device info
488496 if appl .pwclass == "gateway" :
489497 self .gateway_id = appliance .attrib ["id" ]
490498 appl .fw = self .smile_fw_version
@@ -511,6 +519,7 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
511519
512520 return appl
513521
522+ # Collect thermostat device info
514523 if appl .pwclass in THERMOSTAT_CLASSES :
515524 locator = "./logs/point_log[type='thermostat']/thermostat"
516525 mod_type = "thermostat"
@@ -519,23 +528,25 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
519528 appl .model = check_model (module_data ["vendor_model" ], appl .v_name )
520529 appl .hw = module_data ["hardware_version" ]
521530 appl .fw = module_data ["firmware_version" ]
531+ appl .zigbee_mac = module_data ["zigbee_mac_address" ]
522532
523533 return appl
524534
535+ # Collect heater_central device info
525536 if appl .pwclass == "heater_central" :
526537 # Remove heater_central when no active device present
527538 if not self ._opentherm_device and not self ._on_off_device :
528539 return None
529540
530541 self ._heater_id = appliance .attrib ["id" ]
531- # info for On-Off device
542+ # Info for On-Off device
532543 if self ._on_off_device :
533544 appl .name = "OnOff"
534545 appl .v_name = None
535546 appl .model = "Unknown"
536547 return appl
537548
538- # Obtain info for OpenTherm device
549+ # Info for OpenTherm device
539550 appl .name = "OpenTherm"
540551 locator1 = "./logs/point_log[type='flame_state']/boiler_state"
541552 locator2 = "./services/boiler_state"
@@ -554,13 +565,10 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
554565 )
555566 return appl
556567
557- # Handle stretches
568+ # Collect info from Stretches
558569 appl = self ._energy_device_info_finder (appliance , appl )
559- if not appl :
560- return None
561570
562- # Cornercase just return existing dict-object
563- return appl # pragma: no cover
571+ return appl
564572
565573 def _appliance_types_finder (self , appliance : etree , appl : Munch ) -> Munch :
566574 """Helper-function for _all_appliances() - determine type(s) per appliance."""
@@ -600,29 +608,29 @@ def _all_appliances(self) -> None:
600608 "class" : "gateway" ,
601609 "fw" : self .smile_fw_version ,
602610 "hw" : self .smile_hw_version ,
603- "mac_address" : self .smile_mac_address ,
604611 "location" : self ._home_location ,
605- "vendor " : "Plugwise B.V." ,
612+ "mac_address " : self . smile_mac_address ,
606613 }
607614 self .gateway_id = self ._home_location
608615
609616 if self .smile_type == "power" :
610617 self ._appl_data [self ._home_location ].update (
611- {"model" : "P1" , "name" : "P1" }
618+ {"model" : "P1" , "name" : "P1" , "vendor" : "Plugwise B.V." }
612619 )
613620 # legacy p1 has no more devices
614621 return
615622
616623 if self .smile_type == "thermostat" :
617624 self ._appl_data [self ._home_location ].update (
618- {"model" : "Anna" , "name" : "Anna" }
625+ {"model" : "Anna" , "name" : "Anna" , "vendor" : "Plugwise B.V." }
619626 )
620627
621628 if self .smile_type == "stretch" :
622629 self ._appl_data [self ._home_location ].update (
623630 {
624631 "model" : "Stretch" ,
625632 "name" : "Stretch" ,
633+ "vendor" : "Plugwise B.V." ,
626634 "zigbee_mac_address" : self .smile_zigbee_mac_address ,
627635 }
628636 )
@@ -666,7 +674,7 @@ def _all_appliances(self) -> None:
666674 # Determine class for this appliance
667675 appl = self ._appliance_info_finder (appliance , appl )
668676 # Skip on heater_central when no active device present or on orphaned stretch devices
669- if not appl :
677+ if appl is None :
670678 continue
671679
672680 if appl .pwclass == "gateway" :
@@ -1019,7 +1027,6 @@ def _group_switches(self) -> dict[str, dict[str, Any]]:
10191027 "model" : "Switchgroup" ,
10201028 "name" : group_name ,
10211029 "members" : members ,
1022- "types" : {"switch_group" },
10231030 "vendor" : None ,
10241031 }
10251032
0 commit comments