6
6
from homeassistant .config_entries import ConfigEntry
7
7
from homeassistant .const import CONF_HOST , CONF_PORT , EVENT_HOMEASSISTANT_STOP
8
8
from homeassistant .core import Event , HomeAssistant
9
+ from homeassistant .helpers import device_registry as dr
9
10
from homeassistant .helpers .entity import DeviceInfo , EntityDescription
10
11
from homeassistant .helpers .typing import ConfigType
11
-
12
12
from luxtronik import LOGGER as LuxLogger
13
13
14
14
from .const import (
@@ -131,39 +131,32 @@ def setup_internal(hass, data, conf):
131
131
hass .data [f"{ DOMAIN } _conf" ] = conf
132
132
133
133
# Create DeviceInfos:
134
- serial_number_date = luxtronik .get_value ("parameters.ID_WP_SerienNummer_DATUM" )
135
- serial_number_hex = hex (
136
- int (luxtronik .get_value ("parameters.ID_WP_SerienNummer_HEX" ))
137
- )
138
- serial_number = f"{ serial_number_date } -{ serial_number_hex } " .replace ("x" , "" )
139
- model = luxtronik .get_value ("calculations.ID_WEB_Code_WP_akt" )
140
-
141
134
hass .data [f"{ DOMAIN } _DeviceInfo" ] = build_device_info (
142
- luxtronik , serial_number , text_heatpump , data [CONF_HOST ]
135
+ luxtronik , text_heatpump , data [CONF_HOST ]
143
136
)
144
137
hass .data [f"{ DOMAIN } _DeviceInfo_Domestic_Water" ] = DeviceInfo (
145
- identifiers = {(DOMAIN , "Domestic_Water" , serial_number )},
138
+ identifiers = {(DOMAIN , f" { luxtronik . unique_id } _domestic_water" )},
146
139
configuration_url = "https://www.heatpump24.com/" ,
147
140
default_name = text_domestic_water ,
148
141
name = text_domestic_water ,
149
- manufacturer = get_manufacturer_by_model ( model ) ,
150
- model = model ,
142
+ manufacturer = luxtronik . manufacturer ,
143
+ model = luxtronik . model ,
151
144
)
152
145
hass .data [f"{ DOMAIN } _DeviceInfo_Heating" ] = DeviceInfo (
153
- identifiers = {(DOMAIN , "Heating" , serial_number )},
154
- configuration_url = get_manufacturer_firmware_url_by_model (model ),
146
+ identifiers = {(DOMAIN , f" { luxtronik . unique_id } _heating" )},
147
+ configuration_url = get_manufacturer_firmware_url_by_model (luxtronik . model ),
155
148
default_name = text_heating ,
156
149
name = text_heating ,
157
- manufacturer = get_manufacturer_by_model ( model ) ,
158
- model = model ,
150
+ manufacturer = luxtronik . manufacturer ,
151
+ model = luxtronik . model ,
159
152
)
160
153
hass .data [f"{ DOMAIN } _DeviceInfo_Cooling" ] = (
161
154
DeviceInfo (
162
- identifiers = {(DOMAIN , "Cooling" , serial_number )},
155
+ identifiers = {(DOMAIN , f" { luxtronik . unique_id } _cooling" )},
163
156
default_name = text_cooling ,
164
157
name = text_cooling ,
165
- manufacturer = get_manufacturer_by_model ( model ) ,
166
- model = model ,
158
+ manufacturer = luxtronik . manufacturer ,
159
+ model = luxtronik . model ,
167
160
)
168
161
if luxtronik .detect_cooling_present ()
169
162
else None
@@ -185,39 +178,88 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
185
178
if luxtronik is None :
186
179
return True
187
180
181
+ unload_ok = False
188
182
try :
189
183
await hass .async_add_executor_job (luxtronik .disconnect )
190
184
191
185
await hass .services .async_remove (DOMAIN , SERVICE_WRITE )
186
+
187
+ unload_ok = await hass .config_entries .async_unload_platforms (
188
+ config_entry , PLATFORMS
189
+ )
190
+ if unload_ok :
191
+ hass .data [DOMAIN ] = None
192
+ hass .data .pop (DOMAIN )
193
+
192
194
except Exception as e :
193
195
LOGGER .critical ("Remove service!" , e , exc_info = True )
194
196
195
- unload_ok = await hass .config_entries .async_unload_platforms (
196
- config_entry , PLATFORMS
197
- )
198
- if unload_ok :
199
- hass .data [DOMAIN ] = None
200
- hass .data .pop (DOMAIN )
201
-
202
197
return unload_ok
203
198
204
199
205
200
def build_device_info (
206
- luxtronik : LuxtronikDevice , sn : str , name : str , ip_host : str
201
+ luxtronik : LuxtronikDevice , name : str , ip_host : str
207
202
) -> DeviceInfo :
208
203
"""Build luxtronik device info."""
209
- model = luxtronik .get_value ("calculations.ID_WEB_Code_WP_akt" )
210
204
device_info = DeviceInfo (
211
- identifiers = {(DOMAIN , "Heatpump" , sn )}, # type: ignore
205
+ identifiers = {
206
+ (
207
+ DOMAIN ,
208
+ f"{ luxtronik .unique_id } _heatpump" ,
209
+ )
210
+ },
212
211
configuration_url = f"http://{ ip_host } /" ,
213
- name = f"{ name } S/N { sn } " ,
212
+ name = f"{ name } { luxtronik . serial_number } " ,
214
213
default_name = name ,
215
214
default_manufacturer = "Alpha Innotec" ,
216
- manufacturer = get_manufacturer_by_model ( model ) ,
215
+ manufacturer = luxtronik . manufacturer ,
217
216
default_model = "" ,
218
- model = model ,
217
+ model = luxtronik . model ,
219
218
suggested_area = "Utility room" ,
220
219
sw_version = luxtronik .get_value ("calculations.ID_WEB_SoftStand" ),
221
220
)
222
221
LOGGER .debug ("build_device_info '%s'" , device_info )
223
222
return device_info
223
+
224
+
225
+ async def async_migrate_entry (hass : HomeAssistant , config_entry : ConfigEntry ) -> bool :
226
+ """Migrate old entry."""
227
+ LOGGER .debug ("Migrating from version %s" , config_entry .version )
228
+
229
+ if config_entry .version == 1 :
230
+ new = {** config_entry .data }
231
+ luxtronik = LuxtronikDevice .connect (new [CONF_HOST ], new [CONF_PORT ])
232
+
233
+ _delete_legacy_devices (hass , config_entry , luxtronik .unique_id )
234
+ config_entry .unique_id = luxtronik .unique_id
235
+ config_entry .title = f"{ luxtronik .manufacturer } { luxtronik .model } { luxtronik .serial_number } "
236
+ config_entry .version = 2
237
+ hass .config_entries .async_update_entry (config_entry , data = new )
238
+
239
+ LOGGER .info ("Migration to version %s successful" , config_entry .version )
240
+
241
+ return True
242
+
243
+
244
+ def _identifiers_exists (
245
+ identifiers_list : list [set [tuple [str , str ]]], identifiers : set [tuple [str , str ]]
246
+ ) -> bool :
247
+ for ident in identifiers_list :
248
+ if ident == identifiers :
249
+ return True
250
+ return False
251
+
252
+
253
+ def _delete_legacy_devices (hass : HomeAssistant , config_entry : ConfigEntry , unique_id : str ):
254
+ dr_instance = dr .async_get (hass )
255
+ devices : list [dr .DeviceEntry ] = dr .async_entries_for_config_entry (
256
+ dr_instance , config_entry .entry_id
257
+ )
258
+ identifiers_list = list ()
259
+ identifiers_list .append ({(DOMAIN , f"{ unique_id } _heatpump" )})
260
+ identifiers_list .append ({(DOMAIN , f"{ unique_id } _domestic_water" )})
261
+ identifiers_list .append ({(DOMAIN , f"{ unique_id } _heating" )})
262
+ identifiers_list .append ({(DOMAIN , f"{ unique_id } _cooling" )})
263
+ for device in devices :
264
+ if not _identifiers_exists (identifiers_list , device .identifiers ):
265
+ dr_instance .async_remove_device (device .id )
0 commit comments