From d587f134ca7d57bf2948c711fc9bd330aa48aa0c Mon Sep 17 00:00:00 2001 From: Daniel Shokouhi Date: Fri, 28 Aug 2020 13:13:43 -0700 Subject: [PATCH] Reload mobile app notify service upon device name change, add device name to all webhook logs (#39364) * Add device name to all webhook logs to help with multiple devices * Reload notifications when we update the registration, update from rebase * Make hassfest happy * Adjust caplog test to accomodate log message change Co-authored-by: J. Nick Koston --- .../components/mobile_app/manifest.json | 2 +- .../components/mobile_app/webhook.py | 35 +++++++++++++------ tests/components/mobile_app/test_entity.py | 4 +-- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/mobile_app/manifest.json b/homeassistant/components/mobile_app/manifest.json index 732a2495311..758df70c3d0 100644 --- a/homeassistant/components/mobile_app/manifest.json +++ b/homeassistant/components/mobile_app/manifest.json @@ -5,7 +5,7 @@ "documentation": "https://www.home-assistant.io/integrations/mobile_app", "requirements": ["PyNaCl==1.3.0", "emoji==0.5.4"], "dependencies": ["http", "webhook", "person", "tag"], - "after_dependencies": ["cloud", "camera"], + "after_dependencies": ["cloud", "camera", "notify"], "codeowners": ["@robbiet480"], "quality_scale": "internal" } diff --git a/homeassistant/components/mobile_app/webhook.py b/homeassistant/components/mobile_app/webhook.py index 9d614664a62..2f5e69fd02b 100644 --- a/homeassistant/components/mobile_app/webhook.py +++ b/homeassistant/components/mobile_app/webhook.py @@ -8,7 +8,7 @@ from aiohttp.web import HTTPBadRequest, Request, Response, json_response from nacl.secret import SecretBox import voluptuous as vol -from homeassistant.components import tag +from homeassistant.components import notify as hass_notify, tag from homeassistant.components.binary_sensor import ( DEVICE_CLASSES as BINARY_SENSOR_CLASSES, ) @@ -149,10 +149,12 @@ async def handle_webhook( config_entry = hass.data[DOMAIN][DATA_CONFIG_ENTRIES][webhook_id] + device_name = config_entry.data[ATTR_DEVICE_NAME] + try: req_data = await request.json() except ValueError: - _LOGGER.warning("Received invalid JSON from mobile_app") + _LOGGER.warning("Received invalid JSON from mobile_app device: %s", device_name) return empty_okay_response(status=HTTP_BAD_REQUEST) if ( @@ -161,7 +163,7 @@ async def handle_webhook( ): _LOGGER.warning( "Refusing to accept unencrypted webhook from %s", - config_entry.data[ATTR_DEVICE_NAME], + device_name, ) return error_response(ERR_ENCRYPTION_REQUIRED, "Encryption required") @@ -169,7 +171,9 @@ async def handle_webhook( req_data = WEBHOOK_PAYLOAD_SCHEMA(req_data) except vol.Invalid as ex: err = vol.humanize.humanize_error(req_data, ex) - _LOGGER.error("Received invalid webhook payload: %s", err) + _LOGGER.error( + "Received invalid webhook from %s with payload: %s", device_name, err + ) return empty_okay_response() webhook_type = req_data[ATTR_WEBHOOK_TYPE] @@ -181,11 +185,11 @@ async def handle_webhook( webhook_payload = _decrypt_payload(config_entry.data[CONF_SECRET], enc_data) if webhook_type not in WEBHOOK_COMMANDS: - _LOGGER.error("Received invalid webhook type: %s", webhook_type) + _LOGGER.error( + "Received invalid webhook from %s of type: %s", device_name, webhook_type + ) return empty_okay_response() - device_name = config_entry.data[ATTR_DEVICE_NAME] - _LOGGER.debug( "Received webhook payload from %s for type %s: %s", device_name, @@ -348,6 +352,8 @@ async def webhook_update_registration(hass, config_entry, data): hass.config_entries.async_update_entry(config_entry, data=new_registration) + await hass_notify.async_reload(hass, DOMAIN) + return webhook_response( safe_registration(new_registration), registration=new_registration, @@ -403,6 +409,7 @@ 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] + device_name = config_entry.data[ATTR_DEVICE_NAME] unique_store_key = f"{config_entry.data[CONF_WEBHOOK_ID]}_{unique_id}" existing_sensor = unique_store_key in hass.data[DOMAIN][entity_type] @@ -411,7 +418,9 @@ async def webhook_register_sensor(hass, config_entry, data): # If sensor already is registered, update current state instead if existing_sensor: - _LOGGER.debug("Re-register existing sensor %s", unique_id) + _LOGGER.debug( + "Re-register for %s of existing sensor %s", device_name, unique_id + ) entry = hass.data[DOMAIN][entity_type][unique_store_key] data = {**entry, **data} @@ -464,6 +473,7 @@ async def webhook_update_sensor_states(hass, config_entry, data): } ) + device_name = config_entry.data[ATTR_DEVICE_NAME] resp = {} for sensor in data: entity_type = sensor[ATTR_SENSOR_TYPE] @@ -474,7 +484,9 @@ async def webhook_update_sensor_states(hass, config_entry, data): if unique_store_key not in hass.data[DOMAIN][entity_type]: _LOGGER.error( - "Refusing to update non-registered sensor: %s", unique_store_key + "Refusing to update %s non-registered sensor: %s", + device_name, + unique_store_key, ) err_msg = f"{entity_type} {unique_id} is not registered" resp[unique_id] = { @@ -490,7 +502,10 @@ async def webhook_update_sensor_states(hass, config_entry, data): except vol.Invalid as err: err_msg = vol.humanize.humanize_error(sensor, err) _LOGGER.error( - "Received invalid sensor payload for %s: %s", unique_id, err_msg + "Received invalid sensor payload from %s for %s: %s", + device_name, + unique_id, + err_msg, ) resp[unique_id] = { "success": False, diff --git a/tests/components/mobile_app/test_entity.py b/tests/components/mobile_app/test_entity.py index fd5baf50beb..df1493c084e 100644 --- a/tests/components/mobile_app/test_entity.py +++ b/tests/components/mobile_app/test_entity.py @@ -122,7 +122,7 @@ async def test_sensor_id_no_dupes(hass, create_registrations, webhook_client, ca assert reg_json == {"success": True} await hass.async_block_till_done() - assert "Re-register existing sensor" not in caplog.text + assert "Re-register" not in caplog.text entity = hass.states.get("sensor.test_1_battery_state") assert entity is not None @@ -143,7 +143,7 @@ async def test_sensor_id_no_dupes(hass, create_registrations, webhook_client, ca assert dupe_reg_json == {"success": True} await hass.async_block_till_done() - assert "Re-register existing sensor" in caplog.text + assert "Re-register" in caplog.text entity = hass.states.get("sensor.test_1_battery_state") assert entity is not None