await store.async_save(config) _LOGGER.debug("Created cloudhook '%s'", cloudhook_url) # SmartAppManager uses a dispatcher to invoke callbacks when push events # occur. Use hass' implementation instead of the built-in one. dispatcher = Dispatcher( signal_prefix=SIGNAL_SMARTAPP_PREFIX, connect=functools.partial(async_dispatcher_connect, hass), send=functools.partial(async_dispatcher_send, hass), ) # Path is used in digital signature validation path = (urlparse(cloudhook_url).path if cloudhook_url else webhook.async_generate_path(config[CONF_WEBHOOK_ID])) manager = SmartAppManager(path, dispatcher=dispatcher) manager.connect_install(functools.partial(smartapp_install, hass)) manager.connect_update(functools.partial(smartapp_update, hass)) manager.connect_uninstall(functools.partial(smartapp_uninstall, hass)) hass.data[DOMAIN] = { DATA_MANAGER: manager, CONF_INSTANCE_ID: config[CONF_INSTANCE_ID], DATA_BROKERS: {}, CONF_WEBHOOK_ID: config[CONF_WEBHOOK_ID], # Will not be present if not enabled CONF_CLOUDHOOK_URL: config.get(CONF_CLOUDHOOK_URL), } _LOGGER.debug( "Setup endpoint for %s", cloudhook_url if cloudhook_url else webhook.async_generate_url( hass, config[CONF_WEBHOOK_ID]), )
async def setup_smartapp_endpoint(hass: HomeAssistant): """ Configure the SmartApp webhook in hass. SmartApps are an extension point within the SmartThings ecosystem and is used to receive push updates (i.e. device updates) from the cloud. """ data = hass.data.get(DOMAIN) if data: # already setup return # Get/create config to store a unique id for this hass instance. store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) config = await store.async_load() if not config: # Create config config = { CONF_INSTANCE_ID: str(uuid4()), CONF_WEBHOOK_ID: secrets.token_hex(), CONF_CLOUDHOOK_URL: None, } await store.async_save(config) # Register webhook webhook.async_register(hass, DOMAIN, "SmartApp", config[CONF_WEBHOOK_ID], smartapp_webhook) # Create webhook if eligible cloudhook_url = config.get(CONF_CLOUDHOOK_URL) if (cloudhook_url is None and hass.components.cloud.async_active_subscription() and not hass.config_entries.async_entries(DOMAIN)): cloudhook_url = await hass.components.cloud.async_create_cloudhook( config[CONF_WEBHOOK_ID]) config[CONF_CLOUDHOOK_URL] = cloudhook_url await store.async_save(config) _LOGGER.debug("Created cloudhook '%s'", cloudhook_url) # SmartAppManager uses a dispatcher to invoke callbacks when push events # occur. Use hass' implementation instead of the built-in one. dispatcher = Dispatcher( signal_prefix=SIGNAL_SMARTAPP_PREFIX, connect=functools.partial(async_dispatcher_connect, hass), send=functools.partial(async_dispatcher_send, hass), ) # Path is used in digital signature validation path = (urlparse(cloudhook_url).path if cloudhook_url else webhook.async_generate_path(config[CONF_WEBHOOK_ID])) manager = SmartAppManager(path, dispatcher=dispatcher) manager.connect_install(functools.partial(smartapp_install, hass)) manager.connect_update(functools.partial(smartapp_update, hass)) manager.connect_uninstall(functools.partial(smartapp_uninstall, hass)) hass.data[DOMAIN] = { DATA_MANAGER: manager, CONF_INSTANCE_ID: config[CONF_INSTANCE_ID], DATA_BROKERS: {}, CONF_WEBHOOK_ID: config[CONF_WEBHOOK_ID], # Will not be present if not enabled CONF_CLOUDHOOK_URL: config.get(CONF_CLOUDHOOK_URL), } _LOGGER.debug( "Setup endpoint for %s", cloudhook_url if cloudhook_url else webhook.async_generate_url( hass, config[CONF_WEBHOOK_ID]), )
async def setup_smartapp_endpoint(hass: HomeAssistantType): """ Configure the SmartApp webhook in hass. SmartApps are an extension point within the SmartThings ecosystem and is used to receive push updates (i.e. device updates) from the cloud. """ from pysmartapp import Dispatcher, SmartAppManager data = hass.data.get(DOMAIN) if data: # already setup return # Get/create config to store a unique id for this hass instance. store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) config = await store.async_load() if not config: # Create config config = { CONF_INSTANCE_ID: str(uuid4()), CONF_WEBHOOK_ID: webhook.generate_secret(), CONF_CLOUDHOOK_URL: None } await store.async_save(config) # Register webhook webhook.async_register(hass, DOMAIN, 'SmartApp', config[CONF_WEBHOOK_ID], smartapp_webhook) # Create webhook if eligible cloudhook_url = config.get(CONF_CLOUDHOOK_URL) if cloudhook_url is None \ and cloud.async_active_subscription(hass) \ and not hass.config_entries.async_entries(DOMAIN): cloudhook_url = await cloud.async_create_cloudhook( hass, config[CONF_WEBHOOK_ID]) config[CONF_CLOUDHOOK_URL] = cloudhook_url await store.async_save(config) _LOGGER.debug("Created cloudhook '%s'", cloudhook_url) # SmartAppManager uses a dispatcher to invoke callbacks when push events # occur. Use hass' implementation instead of the built-in one. dispatcher = Dispatcher( signal_prefix=SIGNAL_SMARTAPP_PREFIX, connect=functools.partial(async_dispatcher_connect, hass), send=functools.partial(async_dispatcher_send, hass)) # Path is used in digital signature validation path = urlparse(cloudhook_url).path if cloudhook_url else \ webhook.async_generate_path(config[CONF_WEBHOOK_ID]) manager = SmartAppManager(path, dispatcher=dispatcher) manager.connect_install(functools.partial(smartapp_install, hass)) manager.connect_update(functools.partial(smartapp_update, hass)) manager.connect_uninstall(functools.partial(smartapp_uninstall, hass)) hass.data[DOMAIN] = { DATA_MANAGER: manager, CONF_INSTANCE_ID: config[CONF_INSTANCE_ID], DATA_BROKERS: {}, CONF_WEBHOOK_ID: config[CONF_WEBHOOK_ID], # Will not be present if not enabled CONF_CLOUDHOOK_URL: config.get(CONF_CLOUDHOOK_URL), CONF_INSTALLED_APPS: [] } _LOGGER.debug("Setup endpoint for %s", cloudhook_url if cloudhook_url else webhook.async_generate_url(hass, config[CONF_WEBHOOK_ID]))