3737REAUTH_SCHEMA = BLUETOOTH_SCHEMA
3838
3939
40- def _is_supported (discovery_info : BluetoothServiceInfo ):
41- """Check if device is supported."""
42- if ScanService not in discovery_info .service_uuids :
43- LOGGER .debug (
44- "Unsupported device, missing service %s: %s" , ScanService , discovery_info
45- )
46- return False
47-
48- if not (data := discovery_info .manufacturer_data .get (ManufacturerData .company )):
49- LOGGER .debug (
50- "Unsupported device, missing manufacturer data %s: %s" ,
51- ManufacturerData .company ,
52- discovery_info ,
53- )
54- return False
55-
56- manufacturer_data = ManufacturerData .decode (data )
57- product_type = ProductType .from_manufacturer_data (manufacturer_data )
58-
59- # Some mowers only expose the serial number in the manufacturer data
60- # and not the product type, so we allow None here as well.
61- if product_type not in (ProductType .MOWER , ProductType .UNKNOWN ):
62- LOGGER .debug ("Unsupported device: %s (%s)" , manufacturer_data , discovery_info )
63- return False
64-
65- if not manufacturer_data .pairable :
66- LOGGER .error (
67- "The mower does not appear to be pairable. "
68- "Ensure the mower is in pairing mode before continuing. "
69- "If the mower isn't pariable you will receive authentication "
70- "errors and be unable to connect"
71- )
72-
73- LOGGER .debug ("Supported device: %s" , manufacturer_data )
74- return True
75-
76-
7740def _pin_valid (pin : str ) -> bool :
7841 """Check if the pin is valid."""
7942 try :
@@ -91,14 +54,49 @@ class HusqvarnaAutomowerBleConfigFlow(ConfigFlow, domain=DOMAIN):
9154 address : str | None = None
9255 mower_name : str = ""
9356 pin : str | None = None
57+ pairable : bool = True
58+
59+ def _is_supported (self , discovery_info : BluetoothServiceInfo ):
60+ """Check if device is supported."""
61+ if ScanService not in discovery_info .service_uuids :
62+ LOGGER .debug (
63+ "Unsupported device, missing service %s: %s" ,
64+ ScanService ,
65+ discovery_info ,
66+ )
67+ return False
68+
69+ if not (data := discovery_info .manufacturer_data .get (ManufacturerData .company )):
70+ LOGGER .debug (
71+ "Unsupported device, missing manufacturer data %s: %s" ,
72+ ManufacturerData .company ,
73+ discovery_info ,
74+ )
75+ return False
76+
77+ manufacturer_data = ManufacturerData .decode (data )
78+ product_type = ProductType .from_manufacturer_data (manufacturer_data )
79+
80+ # Some mowers only expose the serial number in the manufacturer data
81+ # and not the product type, so we allow UNKNOWN here as well.
82+ if product_type not in (ProductType .MOWER , ProductType .UNKNOWN ):
83+ LOGGER .debug (
84+ "Unsupported device: %s (%s)" , manufacturer_data , discovery_info
85+ )
86+ return False
87+
88+ self .pairable = manufacturer_data .pairable
89+
90+ LOGGER .debug ("Supported device: %s" , manufacturer_data )
91+ return True
9492
9593 async def async_step_bluetooth (
9694 self , discovery_info : BluetoothServiceInfo
9795 ) -> ConfigFlowResult :
9896 """Handle the bluetooth discovery step."""
9997
10098 LOGGER .debug ("Discovered device: %s" , discovery_info )
101- if not _is_supported (discovery_info ):
99+ if not self . _is_supported (discovery_info ):
102100 return self .async_abort (reason = "no_devices_found" )
103101
104102 self .context ["title_placeholders" ] = {
@@ -117,6 +115,14 @@ async def async_step_bluetooth_confirm(
117115 assert self .address
118116 errors : dict [str , str ] = {}
119117
118+ if not self .pairable :
119+ LOGGER .error (
120+ "The mower does not appear to be pairable. "
121+ "Ensure the mower is in pairing mode before continuing. "
122+ "If the mower isn't pairable you will receive authentication "
123+ "errors and be unable to connect"
124+ )
125+
120126 if user_input is not None :
121127 if not _pin_valid (user_input [CONF_PIN ]):
122128 errors ["base" ] = "invalid_pin"
0 commit comments