mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Remove redundant parameter from config_entry data of LCN integration (#135912)
This commit is contained in:
parent
e9789e0b3e
commit
e56f6fafdc
@ -24,12 +24,17 @@ from homeassistant.const import (
|
||||
CONF_IP_ADDRESS,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_RESOURCE,
|
||||
CONF_USERNAME,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv, device_registry as dr
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
)
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import (
|
||||
@ -38,6 +43,7 @@ from .const import (
|
||||
CONF_DIM_MODE,
|
||||
CONF_DOMAIN_DATA,
|
||||
CONF_SK_NUM_TRIES,
|
||||
CONF_TARGET_VALUE_LOCKED,
|
||||
CONF_TRANSITION,
|
||||
CONNECTION,
|
||||
DEVICE_CONNECTIONS,
|
||||
@ -155,6 +161,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||
if config_entry.minor_version < 2:
|
||||
new_data[CONF_ACKNOWLEDGE] = False
|
||||
|
||||
if config_entry.version < 2:
|
||||
# update to 2.1 (fix transitions for lights and switches)
|
||||
new_entities_data = [*new_data[CONF_ENTITIES]]
|
||||
for entity in new_entities_data:
|
||||
@ -164,8 +171,19 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||
entity[CONF_DOMAIN_DATA][CONF_TRANSITION] /= 1000.0
|
||||
new_data[CONF_ENTITIES] = new_entities_data
|
||||
|
||||
if config_entry.version < 3:
|
||||
# update to 3.1 (remove resource parameter, add climate target lock value parameter)
|
||||
for entity in new_data[CONF_ENTITIES]:
|
||||
entity.pop(CONF_RESOURCE, None)
|
||||
|
||||
if entity[CONF_DOMAIN] == Platform.CLIMATE:
|
||||
entity[CONF_DOMAIN_DATA].setdefault(CONF_TARGET_VALUE_LOCKED, -1)
|
||||
|
||||
# migrate climate and scene unique ids
|
||||
await async_migrate_entities(hass, config_entry)
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry, data=new_data, minor_version=1, version=2
|
||||
config_entry, data=new_data, minor_version=1, version=3
|
||||
)
|
||||
|
||||
_LOGGER.debug(
|
||||
@ -176,6 +194,29 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
||||
return True
|
||||
|
||||
|
||||
async def async_migrate_entities(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Migrate entity registry."""
|
||||
|
||||
@callback
|
||||
def update_unique_id(entity_entry: er.RegistryEntry) -> dict[str, str] | None:
|
||||
"""Update unique ID of entity entry."""
|
||||
# fix unique entity ids for climate and scene
|
||||
if "." in entity_entry.unique_id:
|
||||
if entity_entry.domain == Platform.CLIMATE:
|
||||
setpoint = entity_entry.unique_id.split(".")[-1]
|
||||
return {
|
||||
"new_unique_id": entity_entry.unique_id.rsplit("-", 1)[0]
|
||||
+ f"-{setpoint}"
|
||||
}
|
||||
if entity_entry.domain == Platform.SCENE:
|
||||
return {"new_unique_id": entity_entry.unique_id.replace(".", "")}
|
||||
return None
|
||||
|
||||
await er.async_migrate_entries(hass, config_entry.entry_id, update_unique_id)
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
"""Close connection to PCHK host represented by config_entry."""
|
||||
# forward unloading to platforms
|
||||
|
@ -110,7 +110,7 @@ async def validate_connection(data: ConfigType) -> str | None:
|
||||
class LcnFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a LCN config flow."""
|
||||
|
||||
VERSION = 2
|
||||
VERSION = 3
|
||||
MINOR_VERSION = 1
|
||||
|
||||
async def async_step_user(
|
||||
|
@ -3,18 +3,19 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_RESOURCE
|
||||
from homeassistant.const import CONF_ADDRESS, CONF_DOMAIN, CONF_NAME
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import CONF_DOMAIN_DATA, DOMAIN
|
||||
from .helpers import (
|
||||
AddressType,
|
||||
DeviceConnectionType,
|
||||
InputType,
|
||||
generate_unique_id,
|
||||
get_device_connection,
|
||||
get_resource,
|
||||
)
|
||||
|
||||
|
||||
@ -48,7 +49,11 @@ class LcnEntity(Entity):
|
||||
def unique_id(self) -> str:
|
||||
"""Return a unique ID."""
|
||||
return generate_unique_id(
|
||||
self.config_entry.entry_id, self.address, self.config[CONF_RESOURCE]
|
||||
self.config_entry.entry_id,
|
||||
self.address,
|
||||
get_resource(
|
||||
self.config[CONF_DOMAIN], self.config[CONF_DOMAIN_DATA]
|
||||
).lower(),
|
||||
)
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
|
@ -19,7 +19,6 @@ from homeassistant.const import (
|
||||
CONF_ENTITIES,
|
||||
CONF_LIGHTS,
|
||||
CONF_NAME,
|
||||
CONF_RESOURCE,
|
||||
CONF_SENSORS,
|
||||
CONF_SWITCHES,
|
||||
)
|
||||
@ -29,6 +28,7 @@ from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import (
|
||||
CONF_CLIMATES,
|
||||
CONF_DOMAIN_DATA,
|
||||
CONF_HARDWARE_SERIAL,
|
||||
CONF_HARDWARE_TYPE,
|
||||
CONF_SCENES,
|
||||
@ -79,9 +79,9 @@ def get_resource(domain_name: str, domain_data: ConfigType) -> str:
|
||||
if domain_name == "cover":
|
||||
return cast(str, domain_data["motor"])
|
||||
if domain_name == "climate":
|
||||
return f"{domain_data['source']}.{domain_data['setpoint']}"
|
||||
return cast(str, domain_data["setpoint"])
|
||||
if domain_name == "scene":
|
||||
return f"{domain_data['register']}.{domain_data['scene']}"
|
||||
return f"{domain_data['register']}{domain_data['scene']}"
|
||||
raise ValueError("Unknown domain")
|
||||
|
||||
|
||||
@ -115,7 +115,9 @@ def purge_entity_registry(
|
||||
references_entry_data = set()
|
||||
for entity_data in imported_entry_data[CONF_ENTITIES]:
|
||||
entity_unique_id = generate_unique_id(
|
||||
entry_id, entity_data[CONF_ADDRESS], entity_data[CONF_RESOURCE]
|
||||
entry_id,
|
||||
entity_data[CONF_ADDRESS],
|
||||
get_resource(entity_data[CONF_DOMAIN], entity_data[CONF_DOMAIN_DATA]),
|
||||
)
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
entity_data[CONF_DOMAIN], DOMAIN, entity_unique_id
|
||||
|
@ -8,5 +8,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/lcn",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pypck"],
|
||||
"requirements": ["pypck==0.8.5", "lcn-frontend==0.2.3"]
|
||||
"requirements": ["pypck==0.8.5", "lcn-frontend==0.2.4"]
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ from homeassistant.const import (
|
||||
CONF_DOMAIN,
|
||||
CONF_ENTITIES,
|
||||
CONF_NAME,
|
||||
CONF_RESOURCE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import (
|
||||
@ -343,7 +342,6 @@ async def websocket_add_entity(
|
||||
entity_config = {
|
||||
CONF_ADDRESS: msg[CONF_ADDRESS],
|
||||
CONF_NAME: msg[CONF_NAME],
|
||||
CONF_RESOURCE: resource,
|
||||
CONF_DOMAIN: domain_name,
|
||||
CONF_DOMAIN_DATA: domain_data,
|
||||
}
|
||||
@ -371,7 +369,15 @@ async def websocket_add_entity(
|
||||
vol.Required("entry_id"): cv.string,
|
||||
vol.Required(CONF_ADDRESS): ADDRESS_SCHEMA,
|
||||
vol.Required(CONF_DOMAIN): cv.string,
|
||||
vol.Required(CONF_RESOURCE): cv.string,
|
||||
vol.Required(CONF_DOMAIN_DATA): vol.Any(
|
||||
DOMAIN_DATA_BINARY_SENSOR,
|
||||
DOMAIN_DATA_SENSOR,
|
||||
DOMAIN_DATA_SWITCH,
|
||||
DOMAIN_DATA_LIGHT,
|
||||
DOMAIN_DATA_CLIMATE,
|
||||
DOMAIN_DATA_COVER,
|
||||
DOMAIN_DATA_SCENE,
|
||||
),
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
@ -390,7 +396,10 @@ async def websocket_delete_entity(
|
||||
if (
|
||||
tuple(entity_config[CONF_ADDRESS]) == msg[CONF_ADDRESS]
|
||||
and entity_config[CONF_DOMAIN] == msg[CONF_DOMAIN]
|
||||
and entity_config[CONF_RESOURCE] == msg[CONF_RESOURCE]
|
||||
and get_resource(
|
||||
entity_config[CONF_DOMAIN], entity_config[CONF_DOMAIN_DATA]
|
||||
)
|
||||
== get_resource(msg[CONF_DOMAIN], msg[CONF_DOMAIN_DATA])
|
||||
)
|
||||
),
|
||||
None,
|
||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -1308,7 +1308,7 @@ lakeside==0.13
|
||||
laundrify-aio==1.2.2
|
||||
|
||||
# homeassistant.components.lcn
|
||||
lcn-frontend==0.2.3
|
||||
lcn-frontend==0.2.4
|
||||
|
||||
# homeassistant.components.ld2410_ble
|
||||
ld2410-ble==0.1.1
|
||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -1108,7 +1108,7 @@ lacrosse-view==1.1.1
|
||||
laundrify-aio==1.2.2
|
||||
|
||||
# homeassistant.components.lcn
|
||||
lcn-frontend==0.2.3
|
||||
lcn-frontend==0.2.4
|
||||
|
||||
# homeassistant.components.ld2410_ble
|
||||
ld2410-ble==0.1.1
|
||||
|
@ -88,7 +88,7 @@ def create_config_entry(
|
||||
|
||||
title = entry_data[CONF_HOST]
|
||||
return MockConfigEntry(
|
||||
entry_id=fixture_filename,
|
||||
entry_id=fixture_filename.replace(".", "_"),
|
||||
domain=DOMAIN,
|
||||
title=title,
|
||||
data=entry_data,
|
||||
|
@ -27,7 +27,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Light_Output1",
|
||||
"resource": "output1",
|
||||
"domain": "light",
|
||||
"domain_data": {
|
||||
"output": "OUTPUT1",
|
||||
@ -38,7 +37,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Light_Output2",
|
||||
"resource": "output2",
|
||||
"domain": "light",
|
||||
"domain_data": {
|
||||
"output": "OUTPUT2",
|
||||
@ -49,7 +47,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Light_Relay1",
|
||||
"resource": "relay1",
|
||||
"domain": "light",
|
||||
"domain_data": {
|
||||
"output": "RELAY1",
|
||||
@ -60,7 +57,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_Output1",
|
||||
"resource": "output1",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "OUTPUT1"
|
||||
@ -69,7 +65,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_Output2",
|
||||
"resource": "output2",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "OUTPUT2"
|
||||
@ -78,7 +73,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_Relay1",
|
||||
"resource": "relay1",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "RELAY1"
|
||||
@ -87,7 +81,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_Relay2",
|
||||
"resource": "relay2",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "RELAY2"
|
||||
@ -96,7 +89,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_Regulator1",
|
||||
"resource": "r1varsetpoint",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "R1VARSETPOINT"
|
||||
@ -105,7 +97,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_KeyLock1",
|
||||
"resource": "a1",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "A1"
|
||||
@ -114,7 +105,6 @@
|
||||
{
|
||||
"address": [0, 5, true],
|
||||
"name": "Switch_Group5",
|
||||
"resource": "relay1",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "RELAY1"
|
||||
@ -123,7 +113,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Cover_Outputs",
|
||||
"resource": "outputs",
|
||||
"domain": "cover",
|
||||
"domain_data": {
|
||||
"motor": "OUTPUTS",
|
||||
@ -133,7 +122,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Cover_Relays",
|
||||
"resource": "motor1",
|
||||
"domain": "cover",
|
||||
"domain_data": {
|
||||
"motor": "MOTOR1",
|
||||
@ -143,12 +131,12 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Climate1",
|
||||
"resource": "var1.r1varsetpoint",
|
||||
"domain": "climate",
|
||||
"domain_data": {
|
||||
"source": "VAR1",
|
||||
"setpoint": "R1VARSETPOINT",
|
||||
"lockable": true,
|
||||
"target_value_locked": -1,
|
||||
"min_temp": 0.0,
|
||||
"max_temp": 40.0,
|
||||
"unit_of_measurement": "°C"
|
||||
@ -157,7 +145,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Romantic",
|
||||
"resource": "0.0",
|
||||
"domain": "scene",
|
||||
"domain_data": {
|
||||
"register": 0,
|
||||
@ -169,7 +156,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Romantic Transition",
|
||||
"resource": "0.1",
|
||||
"domain": "scene",
|
||||
"domain_data": {
|
||||
"register": 0,
|
||||
@ -181,7 +167,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_LockRegulator1",
|
||||
"resource": "r1varsetpoint",
|
||||
"domain": "binary_sensor",
|
||||
"domain_data": {
|
||||
"source": "R1VARSETPOINT"
|
||||
@ -190,7 +175,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Binary_Sensor1",
|
||||
"resource": "binsensor1",
|
||||
"domain": "binary_sensor",
|
||||
"domain_data": {
|
||||
"source": "BINSENSOR1"
|
||||
@ -199,7 +183,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_KeyLock",
|
||||
"resource": "a5",
|
||||
"domain": "binary_sensor",
|
||||
"domain_data": {
|
||||
"source": "A5"
|
||||
@ -208,7 +191,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_Var1",
|
||||
"resource": "var1",
|
||||
"domain": "sensor",
|
||||
"domain_data": {
|
||||
"source": "VAR1",
|
||||
@ -218,7 +200,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_Setpoint1",
|
||||
"resource": "r1varsetpoint",
|
||||
"domain": "sensor",
|
||||
"domain_data": {
|
||||
"source": "R1VARSETPOINT",
|
||||
@ -228,7 +209,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_Led6",
|
||||
"resource": "led6",
|
||||
"domain": "sensor",
|
||||
"domain_data": {
|
||||
"source": "LED6",
|
||||
@ -238,7 +218,6 @@
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_LogicOp1",
|
||||
"resource": "logicop1",
|
||||
"domain": "sensor",
|
||||
"domain_data": {
|
||||
"source": "LOGICOP1",
|
||||
|
96
tests/components/lcn/fixtures/config_entry_pchk_v2_1.json
Normal file
96
tests/components/lcn/fixtures/config_entry_pchk_v2_1.json
Normal file
@ -0,0 +1,96 @@
|
||||
{
|
||||
"host": "pchk",
|
||||
"ip_address": "192.168.2.41",
|
||||
"port": 4114,
|
||||
"username": "lcn",
|
||||
"password": "lcn",
|
||||
"sk_num_tries": 0,
|
||||
"dim_mode": "STEPS200",
|
||||
"acknowledge": false,
|
||||
"devices": [
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "TestModule",
|
||||
"hardware_serial": -1,
|
||||
"software_serial": -1,
|
||||
"hardware_type": -1
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Light_Output1",
|
||||
"resource": "output1",
|
||||
"domain": "light",
|
||||
"domain_data": {
|
||||
"output": "OUTPUT1",
|
||||
"dimmable": true,
|
||||
"transition": 5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Switch_Relay1",
|
||||
"resource": "relay1",
|
||||
"domain": "switch",
|
||||
"domain_data": {
|
||||
"output": "RELAY1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Cover_Relays",
|
||||
"resource": "motor1",
|
||||
"domain": "cover",
|
||||
"domain_data": {
|
||||
"motor": "MOTOR1",
|
||||
"reverse_time": "RT1200"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Climate1",
|
||||
"resource": "var1.r1varsetpoint",
|
||||
"domain": "climate",
|
||||
"domain_data": {
|
||||
"source": "VAR1",
|
||||
"setpoint": "R1VARSETPOINT",
|
||||
"lockable": true,
|
||||
"min_temp": 0.0,
|
||||
"max_temp": 40.0,
|
||||
"unit_of_measurement": "°C"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Romantic",
|
||||
"resource": "0.0",
|
||||
"domain": "scene",
|
||||
"domain_data": {
|
||||
"register": 0,
|
||||
"scene": 0,
|
||||
"outputs": ["OUTPUT1", "OUTPUT2", "RELAY1"],
|
||||
"transition": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Binary_Sensor1",
|
||||
"resource": "binsensor1",
|
||||
"domain": "binary_sensor",
|
||||
"domain_data": {
|
||||
"source": "BINSENSOR1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_Var1",
|
||||
"resource": "var1",
|
||||
"domain": "sensor",
|
||||
"domain_data": {
|
||||
"source": "VAR1",
|
||||
"unit_of_measurement": "°C"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -29,7 +29,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-binsensor1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-binsensor1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -76,7 +76,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-a5',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-a5',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -123,7 +123,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-r1varsetpoint',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-r1varsetpoint',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
@ -36,7 +36,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 385>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-var1.r1varsetpoint',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-r1varsetpoint',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
@ -29,7 +29,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <CoverEntityFeature: 11>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-outputs',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-outputs',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -78,7 +78,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <CoverEntityFeature: 11>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-motor1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-motor1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
@ -30,7 +30,6 @@
|
||||
'transition': 5.0,
|
||||
}),
|
||||
'name': 'Light_Output1',
|
||||
'resource': 'output1',
|
||||
}),
|
||||
]),
|
||||
'host': 'pchk',
|
||||
@ -72,7 +71,6 @@
|
||||
'transition': 5.0,
|
||||
}),
|
||||
'name': 'Light_Output1',
|
||||
'resource': 'output1',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
@ -87,7 +85,6 @@
|
||||
'transition': 0.0,
|
||||
}),
|
||||
'name': 'Light_Output2',
|
||||
'resource': 'output2',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
@ -107,7 +104,6 @@
|
||||
'transition': 0.0,
|
||||
}),
|
||||
'name': 'Romantic',
|
||||
'resource': '0.0',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
@ -127,7 +123,134 @@
|
||||
'transition': 10.0,
|
||||
}),
|
||||
'name': 'Romantic Transition',
|
||||
'resource': '0.1',
|
||||
}),
|
||||
]),
|
||||
'host': 'pchk',
|
||||
'ip_address': '192.168.2.41',
|
||||
'password': 'lcn',
|
||||
'port': 4114,
|
||||
'sk_num_tries': 0,
|
||||
'username': 'lcn',
|
||||
})
|
||||
# ---
|
||||
# name: test_migrate_2_1
|
||||
dict({
|
||||
'acknowledge': False,
|
||||
'devices': list([
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'hardware_serial': -1,
|
||||
'hardware_type': -1,
|
||||
'name': 'TestModule',
|
||||
'software_serial': -1,
|
||||
}),
|
||||
]),
|
||||
'dim_mode': 'STEPS200',
|
||||
'entities': list([
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'light',
|
||||
'domain_data': dict({
|
||||
'dimmable': True,
|
||||
'output': 'OUTPUT1',
|
||||
'transition': 5.0,
|
||||
}),
|
||||
'name': 'Light_Output1',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'switch',
|
||||
'domain_data': dict({
|
||||
'output': 'RELAY1',
|
||||
}),
|
||||
'name': 'Switch_Relay1',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'cover',
|
||||
'domain_data': dict({
|
||||
'motor': 'MOTOR1',
|
||||
'reverse_time': 'RT1200',
|
||||
}),
|
||||
'name': 'Cover_Relays',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'climate',
|
||||
'domain_data': dict({
|
||||
'lockable': True,
|
||||
'max_temp': 40.0,
|
||||
'min_temp': 0.0,
|
||||
'setpoint': 'R1VARSETPOINT',
|
||||
'source': 'VAR1',
|
||||
'target_value_locked': -1,
|
||||
'unit_of_measurement': '°C',
|
||||
}),
|
||||
'name': 'Climate1',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'scene',
|
||||
'domain_data': dict({
|
||||
'outputs': list([
|
||||
'OUTPUT1',
|
||||
'OUTPUT2',
|
||||
'RELAY1',
|
||||
]),
|
||||
'register': 0,
|
||||
'scene': 0,
|
||||
'transition': 0.0,
|
||||
}),
|
||||
'name': 'Romantic',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'binary_sensor',
|
||||
'domain_data': dict({
|
||||
'source': 'BINSENSOR1',
|
||||
}),
|
||||
'name': 'Binary_Sensor1',
|
||||
}),
|
||||
dict({
|
||||
'address': tuple(
|
||||
0,
|
||||
7,
|
||||
False,
|
||||
),
|
||||
'domain': 'sensor',
|
||||
'domain_data': dict({
|
||||
'source': 'VAR1',
|
||||
'unit_of_measurement': '°C',
|
||||
}),
|
||||
'name': 'Sensor_Var1',
|
||||
}),
|
||||
]),
|
||||
'host': 'pchk',
|
||||
|
@ -33,7 +33,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-output1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-output1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -90,7 +90,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-output2',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-output2',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -146,7 +146,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-relay1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-relay1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
@ -29,7 +29,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-0.0',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-00',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -76,7 +76,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-0.1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-01',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
@ -29,7 +29,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-led6',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-led6',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -76,7 +76,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-logicop1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-logicop1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -123,7 +123,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-r1varsetpoint',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-r1varsetpoint',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
@ -172,7 +172,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-var1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-var1',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
|
@ -29,7 +29,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-g000005-relay1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-g000005-relay1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -76,7 +76,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-a1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-a1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -123,7 +123,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-output1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-output1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -170,7 +170,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-output2',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-output2',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -217,7 +217,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-r1varsetpoint',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-r1varsetpoint',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -264,7 +264,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-relay1',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-relay1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@ -311,7 +311,7 @@
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-relay2',
|
||||
'unique_id': 'lcn/config_entry_pchk_json-m000007-relay2',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
@ -138,15 +138,12 @@ async def test_async_entry_reload_on_host_event_received(
|
||||
async def test_migrate_1_1(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
"""Test migration config entry."""
|
||||
entry_v1_1 = create_config_entry("pchk_v1_1", version=(1, 1))
|
||||
entry_v1_1.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(entry_v1_1.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
await init_integration(hass, entry_v1_1)
|
||||
|
||||
entry_migrated = hass.config_entries.async_get_entry(entry_v1_1.entry_id)
|
||||
|
||||
assert entry_migrated.state is ConfigEntryState.LOADED
|
||||
assert entry_migrated.version == 2
|
||||
assert entry_migrated.version == 3
|
||||
assert entry_migrated.minor_version == 1
|
||||
assert entry_migrated.data == snapshot
|
||||
|
||||
@ -155,14 +152,51 @@ async def test_migrate_1_1(hass: HomeAssistant, snapshot: SnapshotAssertion) ->
|
||||
async def test_migrate_1_2(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
"""Test migration config entry."""
|
||||
entry_v1_2 = create_config_entry("pchk_v1_2", version=(1, 2))
|
||||
entry_v1_2.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(entry_v1_2.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
await init_integration(hass, entry_v1_2)
|
||||
|
||||
entry_migrated = hass.config_entries.async_get_entry(entry_v1_2.entry_id)
|
||||
|
||||
assert entry_migrated.state is ConfigEntryState.LOADED
|
||||
assert entry_migrated.version == 2
|
||||
assert entry_migrated.version == 3
|
||||
assert entry_migrated.minor_version == 1
|
||||
assert entry_migrated.data == snapshot
|
||||
|
||||
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_migrate_2_1(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
"""Test migration config entry."""
|
||||
entry_v2_1 = create_config_entry("pchk_v2_1", version=(2, 1))
|
||||
await init_integration(hass, entry_v2_1)
|
||||
|
||||
entry_migrated = hass.config_entries.async_get_entry(entry_v2_1.entry_id)
|
||||
assert entry_migrated.state is ConfigEntryState.LOADED
|
||||
assert entry_migrated.version == 3
|
||||
assert entry_migrated.minor_version == 1
|
||||
assert entry_migrated.data == snapshot
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "replace"),
|
||||
[
|
||||
("climate.climate1", ("-r1varsetpoint", "-var1.r1varsetpoint")),
|
||||
("scene.romantic", ("-00", "-0.0")),
|
||||
],
|
||||
)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_entity_migration_on_2_1(
|
||||
hass: HomeAssistant, entity_registry: er.EntityRegistry, entity_id, replace
|
||||
) -> None:
|
||||
"""Test entity.unique_id migration on config_entry migration from 2.1."""
|
||||
entry_v2_1 = create_config_entry("pchk_v2_1", version=(2, 1))
|
||||
await init_integration(hass, entry_v2_1)
|
||||
|
||||
migrated_unique_id = entity_registry.async_get(entity_id).unique_id
|
||||
old_unique_id = migrated_unique_id.replace(*replace)
|
||||
entity_registry.async_update_entity(entity_id, new_unique_id=old_unique_id)
|
||||
assert entity_registry.async_get(entity_id).unique_id == old_unique_id
|
||||
|
||||
await hass.config_entries.async_unload(entry_v2_1.entry_id)
|
||||
|
||||
entry_v2_1 = create_config_entry("pchk_v2_1", version=(2, 1))
|
||||
await init_integration(hass, entry_v2_1)
|
||||
assert entity_registry.async_get(entity_id).unique_id == migrated_unique_id
|
||||
|
@ -7,14 +7,13 @@ import pytest
|
||||
|
||||
from homeassistant.components.lcn import AddressType
|
||||
from homeassistant.components.lcn.const import CONF_DOMAIN_DATA
|
||||
from homeassistant.components.lcn.helpers import get_device_config, get_resource
|
||||
from homeassistant.components.lcn.helpers import get_device_config
|
||||
from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_DEVICES,
|
||||
CONF_DOMAIN,
|
||||
CONF_ENTITIES,
|
||||
CONF_NAME,
|
||||
CONF_RESOURCE,
|
||||
CONF_TYPE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -52,7 +51,7 @@ ENTITIES_DELETE_PAYLOAD = {
|
||||
"entry_id": "",
|
||||
CONF_ADDRESS: (0, 7, False),
|
||||
CONF_DOMAIN: "switch",
|
||||
CONF_RESOURCE: "relay1",
|
||||
CONF_DOMAIN_DATA: {"output": "RELAY1"},
|
||||
}
|
||||
|
||||
|
||||
@ -184,18 +183,14 @@ async def test_lcn_entities_add_command(
|
||||
for key in (CONF_ADDRESS, CONF_NAME, CONF_DOMAIN, CONF_DOMAIN_DATA)
|
||||
}
|
||||
|
||||
resource = get_resource(
|
||||
ENTITIES_ADD_PAYLOAD[CONF_DOMAIN], ENTITIES_ADD_PAYLOAD[CONF_DOMAIN_DATA]
|
||||
).lower()
|
||||
|
||||
assert {**entity_config, CONF_RESOURCE: resource} not in entry.data[CONF_ENTITIES]
|
||||
assert entity_config not in entry.data[CONF_ENTITIES]
|
||||
|
||||
await client.send_json_auto_id({**ENTITIES_ADD_PAYLOAD, "entry_id": entry.entry_id})
|
||||
|
||||
res = await client.receive_json()
|
||||
assert res["success"], res
|
||||
|
||||
assert {**entity_config, CONF_RESOURCE: resource} in entry.data[CONF_ENTITIES]
|
||||
assert entity_config in entry.data[CONF_ENTITIES]
|
||||
|
||||
|
||||
async def test_lcn_entities_delete_command(
|
||||
@ -213,7 +208,8 @@ async def test_lcn_entities_delete_command(
|
||||
for entity in entry.data[CONF_ENTITIES]
|
||||
if entity[CONF_ADDRESS] == ENTITIES_DELETE_PAYLOAD[CONF_ADDRESS]
|
||||
and entity[CONF_DOMAIN] == ENTITIES_DELETE_PAYLOAD[CONF_DOMAIN]
|
||||
and entity[CONF_RESOURCE] == ENTITIES_DELETE_PAYLOAD[CONF_RESOURCE]
|
||||
and entity[CONF_DOMAIN_DATA]
|
||||
== ENTITIES_DELETE_PAYLOAD[CONF_DOMAIN_DATA]
|
||||
]
|
||||
)
|
||||
== 1
|
||||
@ -233,7 +229,8 @@ async def test_lcn_entities_delete_command(
|
||||
for entity in entry.data[CONF_ENTITIES]
|
||||
if entity[CONF_ADDRESS] == ENTITIES_DELETE_PAYLOAD[CONF_ADDRESS]
|
||||
and entity[CONF_DOMAIN] == ENTITIES_DELETE_PAYLOAD[CONF_DOMAIN]
|
||||
and entity[CONF_RESOURCE] == ENTITIES_DELETE_PAYLOAD[CONF_RESOURCE]
|
||||
and entity[CONF_DOMAIN_DATA]
|
||||
== ENTITIES_DELETE_PAYLOAD[CONF_DOMAIN_DATA]
|
||||
]
|
||||
)
|
||||
== 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user