Fix mobile_app sensor re-registration handling (#36567)
This commit is contained in:
parent
5975ec340b
commit
85ba29012f
3 changed files with 45 additions and 19 deletions
|
@ -56,7 +56,6 @@ ERR_ENCRYPTION_ALREADY_ENABLED = "encryption_already_enabled"
|
|||
ERR_ENCRYPTION_NOT_AVAILABLE = "encryption_not_available"
|
||||
ERR_ENCRYPTION_REQUIRED = "encryption_required"
|
||||
ERR_SENSOR_NOT_REGISTERED = "not_registered"
|
||||
ERR_SENSOR_DUPLICATE_UNIQUE_ID = "duplicate_unique_id"
|
||||
ERR_INVALID_FORMAT = "invalid_format"
|
||||
|
||||
|
||||
|
|
|
@ -78,7 +78,6 @@ from .const import (
|
|||
ERR_ENCRYPTION_NOT_AVAILABLE,
|
||||
ERR_ENCRYPTION_REQUIRED,
|
||||
ERR_INVALID_FORMAT,
|
||||
ERR_SENSOR_DUPLICATE_UNIQUE_ID,
|
||||
ERR_SENSOR_NOT_REGISTERED,
|
||||
SIGNAL_LOCATION_UPDATE,
|
||||
SIGNAL_SENSOR_UPDATE,
|
||||
|
@ -364,29 +363,30 @@ async def webhook_enable_encryption(hass, config_entry, data):
|
|||
async def webhook_register_sensor(hass, config_entry, data):
|
||||
"""Handle a register sensor webhook."""
|
||||
entity_type = data[ATTR_SENSOR_TYPE]
|
||||
|
||||
unique_id = data[ATTR_SENSOR_UNIQUE_ID]
|
||||
|
||||
unique_store_key = f"{config_entry.data[CONF_WEBHOOK_ID]}_{unique_id}"
|
||||
|
||||
if unique_store_key in hass.data[DOMAIN][entity_type]:
|
||||
_LOGGER.error("Refusing to re-register existing sensor %s!", unique_id)
|
||||
return error_response(
|
||||
ERR_SENSOR_DUPLICATE_UNIQUE_ID,
|
||||
f"{entity_type} {unique_id} already exists!",
|
||||
status=409,
|
||||
)
|
||||
existing_sensor = unique_store_key in hass.data[DOMAIN][entity_type]
|
||||
|
||||
data[CONF_WEBHOOK_ID] = config_entry.data[CONF_WEBHOOK_ID]
|
||||
|
||||
# If sensor already is registered, update current state instead
|
||||
if existing_sensor:
|
||||
_LOGGER.debug("Re-register existing sensor %s", unique_id)
|
||||
entry = hass.data[DOMAIN][entity_type][unique_store_key]
|
||||
data = {**entry, **data}
|
||||
|
||||
hass.data[DOMAIN][entity_type][unique_store_key] = data
|
||||
|
||||
hass.data[DOMAIN][DATA_STORE].async_delay_save(
|
||||
lambda: savable_state(hass), DELAY_SAVE
|
||||
)
|
||||
|
||||
register_signal = f"{DOMAIN}_{data[ATTR_SENSOR_TYPE]}_register"
|
||||
async_dispatcher_send(hass, register_signal, data)
|
||||
if existing_sensor:
|
||||
async_dispatcher_send(hass, SIGNAL_SENSOR_UPDATE, data)
|
||||
else:
|
||||
register_signal = f"{DOMAIN}_{data[ATTR_SENSOR_TYPE]}_register"
|
||||
async_dispatcher_send(hass, register_signal, data)
|
||||
|
||||
return webhook_response(
|
||||
{"success": True}, registration=config_entry.data, status=HTTP_CREATED,
|
||||
|
|
|
@ -95,8 +95,8 @@ async def test_sensor_must_register(hass, create_registrations, webhook_client):
|
|||
assert json["battery_state"]["error"]["code"] == "not_registered"
|
||||
|
||||
|
||||
async def test_sensor_id_no_dupes(hass, create_registrations, webhook_client):
|
||||
"""Test that sensors must have a unique ID."""
|
||||
async def test_sensor_id_no_dupes(hass, create_registrations, webhook_client, caplog):
|
||||
"""Test that a duplicate unique ID in registration updates the sensor."""
|
||||
webhook_id = create_registrations[1]["webhook_id"]
|
||||
webhook_url = f"/api/webhook/{webhook_id}"
|
||||
|
||||
|
@ -120,14 +120,41 @@ async def test_sensor_id_no_dupes(hass, create_registrations, webhook_client):
|
|||
|
||||
reg_json = await reg_resp.json()
|
||||
assert reg_json == {"success": True}
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "Re-register existing sensor" not in caplog.text
|
||||
|
||||
entity = hass.states.get("sensor.test_1_battery_state")
|
||||
assert entity is not None
|
||||
|
||||
assert entity.attributes["device_class"] == "battery"
|
||||
assert entity.attributes["icon"] == "mdi:battery"
|
||||
assert entity.attributes["unit_of_measurement"] == UNIT_PERCENTAGE
|
||||
assert entity.attributes["foo"] == "bar"
|
||||
assert entity.domain == "sensor"
|
||||
assert entity.name == "Test 1 Battery State"
|
||||
assert entity.state == "100"
|
||||
|
||||
payload["data"]["state"] = 99
|
||||
dupe_resp = await webhook_client.post(webhook_url, json=payload)
|
||||
|
||||
assert dupe_resp.status == 409
|
||||
assert dupe_resp.status == 201
|
||||
dupe_reg_json = await dupe_resp.json()
|
||||
assert dupe_reg_json == {"success": True}
|
||||
await hass.async_block_till_done()
|
||||
|
||||
dupe_json = await dupe_resp.json()
|
||||
assert dupe_json["success"] is False
|
||||
assert dupe_json["error"]["code"] == "duplicate_unique_id"
|
||||
assert "Re-register existing sensor" in caplog.text
|
||||
|
||||
entity = hass.states.get("sensor.test_1_battery_state")
|
||||
assert entity is not None
|
||||
|
||||
assert entity.attributes["device_class"] == "battery"
|
||||
assert entity.attributes["icon"] == "mdi:battery"
|
||||
assert entity.attributes["unit_of_measurement"] == UNIT_PERCENTAGE
|
||||
assert entity.attributes["foo"] == "bar"
|
||||
assert entity.domain == "sensor"
|
||||
assert entity.name == "Test 1 Battery State"
|
||||
assert entity.state == "99"
|
||||
|
||||
|
||||
async def test_register_sensor_no_state(hass, create_registrations, webhook_client):
|
||||
|
|
Loading…
Add table
Reference in a new issue