3535class SatFlowHandler (config_entries .ConfigFlow , domain = DOMAIN ):
3636 """Config flow for SAT."""
3737 VERSION = 5
38+ MINOR_VERSION = 0
39+
3840 calibration = None
3941 overshoot_protection_value = None
4042
4143 def __init__ (self ):
4244 """Initialize."""
43- self ._data = {}
44- self ._errors = {}
45+ self .data = {}
46+ self .errors = {}
4547
4648 @staticmethod
4749 @callback
@@ -58,7 +60,7 @@ async def async_step_user(self, _user_input=None) -> FlowResult:
5860 menu_options = []
5961
6062 # Since we rely on the availability logic in 2023.5, we do not support below it.
61- if MAJOR_VERSION >= 2023 and MINOR_VERSION >= 5 :
63+ if MAJOR_VERSION >= 2023 and ( MINOR_VERSION >= 5 or MAJOR_VERSION > 2023 ) :
6264 menu_options .append ("mosquitto" )
6365
6466 menu_options .append ("serial" )
@@ -72,12 +74,12 @@ async def async_step_user(self, _user_input=None) -> FlowResult:
7274 async def async_step_dhcp (self , discovery_info : DhcpServiceInfo ) -> FlowResult :
7375 """Handle dhcp discovery."""
7476 _LOGGER .debug ("Discovered OTGW at [socket://%s]" , discovery_info .hostname )
75- self ._data [CONF_DEVICE ] = f"socket://{ discovery_info .hostname } :25238"
77+ self .data [CONF_DEVICE ] = f"socket://{ discovery_info .hostname } :25238"
7678
7779 # abort if we already have exactly this gateway id/host
7880 # reload the integration if the host got updated
7981 await self .async_set_unique_id (discovery_info .hostname )
80- self ._abort_if_unique_id_configured (updates = self ._data , reload_on_update = True )
82+ self ._abort_if_unique_id_configured (updates = self .data , reload_on_update = True )
8183
8284 return await self .async_step_serial ()
8385
@@ -88,77 +90,77 @@ async def async_step_mqtt(self, discovery_info: MqttServiceInfo):
8890 )
8991
9092 _LOGGER .debug ("Discovered OTGW at [mqtt://%s]" , discovery_info .topic )
91- self ._data [CONF_DEVICE ] = device .id
93+ self .data [CONF_DEVICE ] = device .id
9294
9395 # abort if we already have exactly this gateway id/host
9496 # reload the integration if the host got updated
9597 await self .async_set_unique_id (device .id )
96- self ._abort_if_unique_id_configured (updates = self ._data , reload_on_update = True )
98+ self ._abort_if_unique_id_configured (updates = self .data , reload_on_update = True )
9799
98100 return await self .async_step_mosquitto ()
99101
100102 async def async_step_mosquitto (self , _user_input = None ):
101- self ._errors = {}
103+ self .errors = {}
102104
103105 if _user_input is not None :
104- self ._data .update (_user_input )
105- self ._data [CONF_MODE ] = MODE_MQTT
106+ self .data .update (_user_input )
107+ self .data [CONF_MODE ] = MODE_MQTT
106108
107109 if not await mqtt .async_wait_for_mqtt_client (self .hass ):
108- self ._errors ["base" ] = "mqtt_component"
110+ self .errors ["base" ] = "mqtt_component"
109111 return await self .async_step_mosquitto ()
110112
111113 return await self .async_step_sensors ()
112114
113115 return self .async_show_form (
114116 step_id = "mosquitto" ,
115117 last_step = False ,
116- errors = self ._errors ,
118+ errors = self .errors ,
117119 data_schema = vol .Schema ({
118120 vol .Required (CONF_NAME , default = DEFAULT_NAME ): str ,
119121 vol .Required (CONF_MQTT_TOPIC , default = OPTIONS_DEFAULTS [CONF_MQTT_TOPIC ]): str ,
120- vol .Required (CONF_DEVICE , default = self ._data .get (CONF_DEVICE )): selector .DeviceSelector (
122+ vol .Required (CONF_DEVICE , default = self .data .get (CONF_DEVICE )): selector .DeviceSelector (
121123 selector .DeviceSelectorConfig (model = "otgw-nodo" )
122124 ),
123125 }),
124126 )
125127
126128 async def async_step_serial (self , _user_input = None ):
127- self ._errors = {}
129+ self .errors = {}
128130
129131 if _user_input is not None :
130- self ._data .update (_user_input )
131- self ._data [CONF_MODE ] = MODE_SERIAL
132+ self .data .update (_user_input )
133+ self .data [CONF_MODE ] = MODE_SERIAL
132134
133135 gateway = OpenThermGateway ()
134- if not await gateway .connect (port = self ._data [CONF_DEVICE ], skip_init = True , timeout = 5 ):
136+ if not await gateway .connect (port = self .data [CONF_DEVICE ], skip_init = True , timeout = 5 ):
135137 await gateway .disconnect ()
136- self ._errors ["base" ] = "connection"
138+ self .errors ["base" ] = "connection"
137139 return await self .async_step_serial ()
138140
139141 return await self .async_step_sensors ()
140142
141143 return self .async_show_form (
142144 step_id = "serial" ,
143145 last_step = False ,
144- errors = self ._errors ,
146+ errors = self .errors ,
145147 data_schema = vol .Schema ({
146148 vol .Required (CONF_NAME , default = DEFAULT_NAME ): str ,
147- vol .Required (CONF_DEVICE , default = self ._data .get (CONF_DEVICE , "socket://otgw.local:25238" )): str ,
149+ vol .Required (CONF_DEVICE , default = self .data .get (CONF_DEVICE , "socket://otgw.local:25238" )): str ,
148150 }),
149151 )
150152
151153 async def async_step_switch (self , _user_input = None ):
152154 if _user_input is not None :
153- self ._data .update (_user_input )
154- self ._data [CONF_MODE ] = MODE_SWITCH
155+ self .data .update (_user_input )
156+ self .data [CONF_MODE ] = MODE_SWITCH
155157
156158 return await self .async_step_sensors ()
157159
158160 return self .async_show_form (
159161 step_id = "switch" ,
160162 last_step = False ,
161- errors = self ._errors ,
163+ errors = self .errors ,
162164 data_schema = vol .Schema ({
163165 vol .Required (CONF_NAME , default = DEFAULT_NAME ): str ,
164166 vol .Required (CONF_DEVICE ): selector .EntitySelector (
@@ -172,16 +174,16 @@ async def async_step_switch(self, _user_input=None):
172174
173175 async def async_step_simulator (self , _user_input = None ):
174176 if _user_input is not None :
175- self ._data .update (_user_input )
176- self ._data [CONF_MODE ] = MODE_SIMULATOR
177- self ._data [CONF_DEVICE ] = f"%s_%s" .format (MODE_SIMULATOR , snake_case (_user_input .get (CONF_NAME )))
177+ self .data .update (_user_input )
178+ self .data [CONF_MODE ] = MODE_SIMULATOR
179+ self .data [CONF_DEVICE ] = f"%s_%s" .format (MODE_SIMULATOR , snake_case (_user_input .get (CONF_NAME )))
178180
179181 return await self .async_step_sensors ()
180182
181183 return self .async_show_form (
182184 step_id = "simulator" ,
183185 last_step = False ,
184- errors = self ._errors ,
186+ errors = self .errors ,
185187 data_schema = vol .Schema ({
186188 vol .Required (CONF_NAME , default = DEFAULT_NAME ): str ,
187189 vol .Required (CONF_SIMULATED_HEATING , default = OPTIONS_DEFAULTS [CONF_SIMULATED_HEATING ]): selector .NumberSelector (
@@ -198,13 +200,13 @@ async def async_step_simulator(self, _user_input=None):
198200 )
199201
200202 async def async_step_sensors (self , _user_input = None ):
201- await self .async_set_unique_id (self ._data [CONF_DEVICE ], raise_on_progress = False )
203+ await self .async_set_unique_id (self .data [CONF_DEVICE ], raise_on_progress = False )
202204 self ._abort_if_unique_id_configured ()
203205
204206 if _user_input is not None :
205- self ._data .update (_user_input )
207+ self .data .update (_user_input )
206208
207- if self ._data [CONF_MODE ] in [MODE_MQTT , MODE_SERIAL , MODE_SIMULATOR ]:
209+ if self .data [CONF_MODE ] in [MODE_MQTT , MODE_SERIAL , MODE_SIMULATOR ]:
208210 return await self .async_step_heating_system ()
209211
210212 return await self .async_step_areas ()
@@ -236,7 +238,7 @@ async def async_step_sensors(self, _user_input=None):
236238
237239 async def async_step_heating_system (self , _user_input = None ):
238240 if _user_input is not None :
239- self ._data .update (_user_input )
241+ self .data .update (_user_input )
240242
241243 return await self .async_step_areas ()
242244
@@ -256,9 +258,9 @@ async def async_step_heating_system(self, _user_input=None):
256258
257259 async def async_step_areas (self , _user_input = None ):
258260 if _user_input is not None :
259- self ._data .update (_user_input )
261+ self .data .update (_user_input )
260262
261- if (await self ._create_coordinator ()).supports_setpoint_management :
263+ if (await self .async_create_coordinator ()).supports_setpoint_management :
262264 return await self .async_step_calibrate_system ()
263265
264266 return await self .async_step_automatic_gains ()
@@ -277,9 +279,9 @@ async def async_step_areas(self, _user_input=None):
277279
278280 async def async_step_automatic_gains (self , _user_input = None ):
279281 if _user_input is not None :
280- self ._data .update (_user_input )
282+ self .data .update (_user_input )
281283
282- if not self ._data [CONF_AUTOMATIC_GAINS ]:
284+ if not self .data [CONF_AUTOMATIC_GAINS ]:
283285 return await self .async_step_pid_controller ()
284286
285287 return await self .async_step_finish ()
@@ -297,7 +299,7 @@ async def async_step_calibrate_system(self, _user_input=None):
297299 )
298300
299301 async def async_step_calibrate (self , _user_input = None ):
300- coordinator = await self ._create_coordinator ()
302+ coordinator = await self .async_create_coordinator ()
301303
302304 async def start_calibration ():
303305 try :
@@ -341,7 +343,7 @@ async def start_calibration():
341343 async def async_step_calibrated (self , _user_input = None ):
342344 return self .async_show_menu (
343345 step_id = "calibrated" ,
344- description_placeholders = self ._data ,
346+ description_placeholders = self .data ,
345347 menu_options = ["calibrate" , "finish" ],
346348 )
347349
@@ -363,10 +365,10 @@ async def async_step_overshoot_protection(self, _user_input=None):
363365 )
364366
365367 async def async_step_pid_controller (self , _user_input = None ):
366- self ._data [CONF_AUTOMATIC_GAINS ] = False
368+ self .data [CONF_AUTOMATIC_GAINS ] = False
367369
368370 if _user_input is not None :
369- self ._data .update (_user_input )
371+ self .data .update (_user_input )
370372 return await self .async_step_finish ()
371373
372374 return self .async_show_form (
@@ -379,22 +381,33 @@ async def async_step_pid_controller(self, _user_input=None):
379381 )
380382
381383 async def async_step_finish (self , _user_input = None ):
382- return self .async_create_entry (title = self ._data [CONF_NAME ], data = self ._data )
384+ return self .async_create_entry (title = self .data [CONF_NAME ], data = self .data )
385+
386+ async def async_create_coordinator (self ) -> SatDataUpdateCoordinator :
387+ # Set up the config entry parameters, since they differ per version
388+ config_params = {
389+ "version" : self .VERSION ,
390+ "domain" : DOMAIN ,
391+ "title" : self .data [CONF_NAME ],
392+ "data" : self .data ,
393+ "source" : SOURCE_USER ,
394+ }
395+
396+ # Check Home Assistant version and add parameters accordingly
397+ if MAJOR_VERSION >= 2024 :
398+ config_params ["minor_version" ] = self .MINOR_VERSION
383399
384- async def _create_coordinator (self ) -> SatDataUpdateCoordinator :
385400 # Create a new config to use
386- config = ConfigEntry (
387- version = self .VERSION , domain = DOMAIN , title = self ._data [CONF_NAME ], data = self ._data , source = SOURCE_USER
388- )
401+ config = ConfigEntry (** config_params )
389402
390403 # Resolve the coordinator by using the factory according to the mode
391404 return await SatDataUpdateCoordinatorFactory ().resolve (
392- hass = self .hass , config_entry = config , mode = self ._data [CONF_MODE ], device = self ._data [CONF_DEVICE ]
405+ hass = self .hass , config_entry = config , mode = self .data [CONF_MODE ], device = self .data [CONF_DEVICE ]
393406 )
394407
395408 async def _enable_overshoot_protection (self , overshoot_protection_value : float ):
396- self ._data [CONF_OVERSHOOT_PROTECTION ] = True
397- self ._data [CONF_MINIMUM_SETPOINT ] = overshoot_protection_value
409+ self .data [CONF_OVERSHOOT_PROTECTION ] = True
410+ self .data [CONF_MINIMUM_SETPOINT ] = overshoot_protection_value
398411
399412
400413class SatOptionsFlowHandler (config_entries .OptionsFlow ):
0 commit comments