@@ -14,6 +14,30 @@ class InverterMQTTFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
1414
1515 VERSION = 1
1616
17+ def _normalize_dongle_id (self , dongle_id ):
18+ """Normalize dongle ID to format: dongle-XX:XX:XX:XX:XX:XX."""
19+ if not dongle_id :
20+ return ""
21+
22+ # Remove any whitespace
23+ dongle_id = dongle_id .strip ()
24+
25+ # Extract MAC address part (everything after 'dongle-' or the whole string if no prefix)
26+ if dongle_id .lower ().startswith ("dongle-" ):
27+ mac_part = dongle_id [7 :] # Remove 'dongle-' prefix
28+ else :
29+ mac_part = dongle_id
30+
31+ # Normalize MAC address: remove non-alphanumeric chars and ensure uppercase
32+ mac_part = '' .join (c for c in mac_part if c .isalnum ()).upper ()
33+
34+ # Insert colons if not present (assuming 12 character MAC)
35+ if len (mac_part ) == 12 and ':' not in mac_part :
36+ mac_part = ':' .join (mac_part [i :i + 2 ] for i in range (0 , 12 , 2 ))
37+
38+ # Return normalized format
39+ return f"dongle-{ mac_part } "
40+
1741 def _get_inverter_title (self , brand , dongle_count = 1 ):
1842 """Generate a proper title based on brand and number of dongles."""
1943 # Map brand codes to proper names
@@ -40,6 +64,9 @@ async def async_step_user(self, user_input=None):
4064 if user_input is not None :
4165 _LOGGER .debug ("User input received: %s" , user_input )
4266
67+ # Normalize the dongle ID
68+ user_input ["dongle_id" ] = self ._normalize_dongle_id (user_input ["dongle_id" ])
69+
4370 # If parallel inverters is selected, store the data and move to the parallel step
4471 if user_input .get ("parallel_inverters" , False ):
4572 self .initial_data = user_input
@@ -90,7 +117,9 @@ async def async_step_parallel(self, user_input=None):
90117 for i in range (1 , 4 ): # Check for dongle_id_2, dongle_id_3, dongle_id_4
91118 additional_dongle = user_input .get (f"dongle_id_{ i + 1 } " )
92119 if additional_dongle and additional_dongle .strip ():
93- dongle_ids .append (additional_dongle )
120+ # Normalize the additional dongle ID
121+ normalized_dongle = self ._normalize_dongle_id (additional_dongle )
122+ dongle_ids .append (normalized_dongle )
94123 # Get corresponding IP or empty string
95124 additional_ip = user_input .get (f"dongle_ip_{ i + 1 } " , "" )
96125 dongle_ips .append (additional_ip )
@@ -141,6 +170,30 @@ def config_entry(self):
141170 """Return the config entry."""
142171 return self ._config_entry
143172
173+ def _normalize_dongle_id (self , dongle_id ):
174+ """Normalize dongle ID to format: dongle-XX:XX:XX:XX:XX:XX."""
175+ if not dongle_id :
176+ return ""
177+
178+ # Remove any whitespace
179+ dongle_id = dongle_id .strip ()
180+
181+ # Extract MAC address part (everything after 'dongle-' or the whole string if no prefix)
182+ if dongle_id .lower ().startswith ("dongle-" ):
183+ mac_part = dongle_id [7 :] # Remove 'dongle-' prefix
184+ else :
185+ mac_part = dongle_id
186+
187+ # Normalize MAC address: remove non-alphanumeric chars and ensure uppercase
188+ mac_part = '' .join (c for c in mac_part if c .isalnum ()).upper ()
189+
190+ # Insert colons if not present (assuming 12 character MAC)
191+ if len (mac_part ) == 12 and ':' not in mac_part :
192+ mac_part = ':' .join (mac_part [i :i + 2 ] for i in range (0 , 12 , 2 ))
193+
194+ # Return normalized format
195+ return f"dongle-{ mac_part } "
196+
144197 def _get_inverter_title (self , brand , dongle_count = 1 ):
145198 """Generate a proper title based on brand and number of dongles."""
146199 # Map brand codes to proper names
@@ -198,7 +251,8 @@ async def async_step_add_dongle(self, user_input=None):
198251 errors = {}
199252
200253 if user_input is not None :
201- new_dongle_id = user_input ["dongle_id" ]
254+ # Normalize the new dongle ID
255+ new_dongle_id = self ._normalize_dongle_id (user_input ["dongle_id" ])
202256 new_dongle_ip = user_input .get ("dongle_ip" , "" )
203257
204258 # Get current data
0 commit comments