diff --git a/homeassistant/components/mobile_app/config_flow.py b/homeassistant/components/mobile_app/config_flow.py index bc9c6167da8..f06754b5bec 100644 --- a/homeassistant/components/mobile_app/config_flow.py +++ b/homeassistant/components/mobile_app/config_flow.py @@ -1,7 +1,7 @@ """Config flow for Mobile App.""" from homeassistant import config_entries -from .const import ATTR_DEVICE_NAME, DOMAIN +from .const import ATTR_DEVICE_ID, ATTR_DEVICE_NAME, DOMAIN @config_entries.HANDLERS.register(DOMAIN) @@ -23,6 +23,8 @@ class MobileAppFlowHandler(config_entries.ConfigFlow): async def async_step_registration(self, user_input=None): """Handle a flow initialized during registration.""" + await self.async_set_unique_id(user_input[ATTR_DEVICE_ID]) + return self.async_create_entry( title=user_input[ATTR_DEVICE_NAME], data=user_input ) diff --git a/homeassistant/components/mobile_app/const.py b/homeassistant/components/mobile_app/const.py index 720cf7106e7..5a5b86269af 100644 --- a/homeassistant/components/mobile_app/const.py +++ b/homeassistant/components/mobile_app/const.py @@ -25,6 +25,7 @@ ATTR_DEVICE_ID = "device_id" ATTR_DEVICE_NAME = "device_name" ATTR_MANUFACTURER = "manufacturer" ATTR_MODEL = "model" +ATTR_MODEL_ID = "model_id" ATTR_OS_NAME = "os_name" ATTR_OS_VERSION = "os_version" ATTR_PUSH_TOKEN = "push_token" diff --git a/homeassistant/components/mobile_app/http_api.py b/homeassistant/components/mobile_app/http_api.py index 717413f889a..7dbe7cb069c 100644 --- a/homeassistant/components/mobile_app/http_api.py +++ b/homeassistant/components/mobile_app/http_api.py @@ -21,6 +21,7 @@ from .const import ( ATTR_DEVICE_NAME, ATTR_MANUFACTURER, ATTR_MODEL, + ATTR_MODEL_ID, ATTR_OS_NAME, ATTR_OS_VERSION, ATTR_SUPPORTS_ENCRYPTION, @@ -40,18 +41,23 @@ class RegistrationsView(HomeAssistantView): name = "api:mobile_app:register" @RequestDataValidator( - { - vol.Optional(ATTR_APP_DATA, default={}): dict, - vol.Required(ATTR_APP_ID): cv.string, - vol.Required(ATTR_APP_NAME): cv.string, - vol.Required(ATTR_APP_VERSION): cv.string, - vol.Required(ATTR_DEVICE_NAME): cv.string, - vol.Required(ATTR_MANUFACTURER): cv.string, - vol.Required(ATTR_MODEL): cv.string, - vol.Required(ATTR_OS_NAME): cv.string, - vol.Optional(ATTR_OS_VERSION): cv.string, - vol.Required(ATTR_SUPPORTS_ENCRYPTION, default=False): cv.boolean, - } + vol.Schema( + { + vol.Optional(ATTR_APP_DATA, default={}): dict, + vol.Required(ATTR_APP_ID): cv.string, + vol.Required(ATTR_APP_NAME): cv.string, + vol.Required(ATTR_APP_VERSION): cv.string, + vol.Required(ATTR_DEVICE_NAME): cv.string, + vol.Required(ATTR_MANUFACTURER): cv.string, + vol.Required(ATTR_MODEL): cv.string, + vol.Optional(ATTR_MODEL_ID): cv.string, # Added in 0.104 + vol.Required(ATTR_OS_NAME): cv.string, + vol.Optional(ATTR_OS_VERSION): cv.string, + vol.Required(ATTR_SUPPORTS_ENCRYPTION, default=False): cv.boolean, + }, + # To allow future apps to send more data + extra=vol.REMOVE_EXTRA, + ) ) async def post(self, request: Request, data: Dict) -> Response: """Handle the POST request for registration.""" @@ -64,7 +70,13 @@ class RegistrationsView(HomeAssistantView): CONF_CLOUDHOOK_URL ] = await hass.components.cloud.async_create_cloudhook(webhook_id) - data[ATTR_DEVICE_ID] = str(uuid.uuid4()).replace("-", "") + model_id = data.get(ATTR_MODEL_ID) + + if model_id is None: + data[ATTR_DEVICE_ID] = str(uuid.uuid4()).replace("-", "") + + else: + data[ATTR_DEVICE_ID] = f"{data[ATTR_APP_ID]}-{model_id}" data[CONF_WEBHOOK_ID] = webhook_id @@ -73,9 +85,10 @@ class RegistrationsView(HomeAssistantView): data[CONF_USER_ID] = request["hass_user"].id - ctx = {"source": "registration"} await hass.async_create_task( - hass.config_entries.flow.async_init(DOMAIN, context=ctx, data=data) + hass.config_entries.flow.async_init( + DOMAIN, data=data, context={"source": "registration"} + ) ) remote_ui_url = None diff --git a/tests/components/mobile_app/const.py b/tests/components/mobile_app/const.py index 1570406d8d5..f065f19f675 100644 --- a/tests/components/mobile_app/const.py +++ b/tests/components/mobile_app/const.py @@ -17,6 +17,7 @@ REGISTER = { "device_name": "Test 1", "manufacturer": "mobile_app", "model": "Test", + "model_id": "mock-model-id", "os_name": "Linux", "os_version": "1.0", "supports_encryption": True, diff --git a/tests/components/mobile_app/test_http_api.py b/tests/components/mobile_app/test_http_api.py index 158d3ffe213..491ea73223c 100644 --- a/tests/components/mobile_app/test_http_api.py +++ b/tests/components/mobile_app/test_http_api.py @@ -33,6 +33,7 @@ async def test_registration(hass, hass_client): entries = hass.config_entries.async_entries(DOMAIN) + assert entries[0].unique_id == "io.homeassistant.mobile_app_test-mock-model-id" assert entries[0].data["app_data"] == REGISTER["app_data"] assert entries[0].data["app_id"] == REGISTER["app_id"] assert entries[0].data["app_name"] == REGISTER["app_name"]