Remove unused SmartThings capability subscriptions (#38128)

This commit is contained in:
Andrew Sayre 2020-07-31 10:40:23 -05:00 committed by GitHub
parent 49cbc9735c
commit bb69aba051
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 3 deletions

View File

@ -24,6 +24,8 @@ SIGNAL_SMARTAPP_PREFIX = "smartthings_smartap_"
SETTINGS_INSTANCE_ID = "hassInstanceId" SETTINGS_INSTANCE_ID = "hassInstanceId"
SUBSCRIPTION_WARNING_LIMIT = 40
STORAGE_KEY = DOMAIN STORAGE_KEY = DOMAIN
STORAGE_VERSION = 1 STORAGE_VERSION = 1
@ -41,6 +43,12 @@ SUPPORTED_PLATFORMS = [
"scene", "scene",
] ]
IGNORED_CAPABILITIES = [
"execute",
"healthCheck",
"ocf",
]
TOKEN_REFRESH_INTERVAL = timedelta(days=14) TOKEN_REFRESH_INTERVAL = timedelta(days=14)
VAL_UID = "^(?:([0-9a-fA-F]{32})|([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}))$" VAL_UID = "^(?:([0-9a-fA-F]{32})|([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}))$"

View File

@ -44,10 +44,12 @@ from .const import (
DATA_BROKERS, DATA_BROKERS,
DATA_MANAGER, DATA_MANAGER,
DOMAIN, DOMAIN,
IGNORED_CAPABILITIES,
SETTINGS_INSTANCE_ID, SETTINGS_INSTANCE_ID,
SIGNAL_SMARTAPP_PREFIX, SIGNAL_SMARTAPP_PREFIX,
STORAGE_KEY, STORAGE_KEY,
STORAGE_VERSION, STORAGE_VERSION,
SUBSCRIPTION_WARNING_LIMIT,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -355,7 +357,26 @@ async def smartapp_sync_subscriptions(
capabilities = set() capabilities = set()
for device in devices: for device in devices:
capabilities.update(device.capabilities) capabilities.update(device.capabilities)
# Remove items not defined in the library
capabilities.intersection_update(CAPABILITIES) capabilities.intersection_update(CAPABILITIES)
# Remove unused capabilities
capabilities.difference_update(IGNORED_CAPABILITIES)
capability_count = len(capabilities)
if capability_count > SUBSCRIPTION_WARNING_LIMIT:
_LOGGER.warning(
"Some device attributes may not receive push updates and there may be subscription "
"creation failures under app '%s' because %s subscriptions are required but "
"there is a limit of %s per app",
installed_app_id,
capability_count,
SUBSCRIPTION_WARNING_LIMIT,
)
_LOGGER.debug(
"Synchronizing subscriptions for %s capabilities under app '%s': %s",
capability_count,
installed_app_id,
capabilities,
)
# Get current subscriptions and find differences # Get current subscriptions and find differences
subscriptions = await api.subscriptions(installed_app_id) subscriptions = await api.subscriptions(installed_app_id)

View File

@ -1,7 +1,7 @@
"""Tests for the smartapp module.""" """Tests for the smartapp module."""
from uuid import uuid4 from uuid import uuid4
from pysmartthings import AppEntity, Capability from pysmartthings import CAPABILITIES, AppEntity, Capability
from homeassistant.components.smartthings import smartapp from homeassistant.components.smartthings import smartapp
from homeassistant.components.smartthings.const import ( from homeassistant.components.smartthings.const import (
@ -89,7 +89,7 @@ async def test_smartapp_webhook(hass):
async def test_smartapp_sync_subscriptions( async def test_smartapp_sync_subscriptions(
hass, smartthings_mock, device_factory, subscription_factory hass, smartthings_mock, device_factory, subscription_factory
): ):
"""Test synchronization adds and removes.""" """Test synchronization adds and removes and ignores unused."""
smartthings_mock.subscriptions.return_value = [ smartthings_mock.subscriptions.return_value = [
subscription_factory(Capability.thermostat), subscription_factory(Capability.thermostat),
subscription_factory(Capability.switch), subscription_factory(Capability.switch),
@ -98,7 +98,7 @@ async def test_smartapp_sync_subscriptions(
devices = [ devices = [
device_factory("", [Capability.battery, "ping"]), device_factory("", [Capability.battery, "ping"]),
device_factory("", [Capability.switch, Capability.switch_level]), device_factory("", [Capability.switch, Capability.switch_level]),
device_factory("", [Capability.switch]), device_factory("", [Capability.switch, Capability.execute]),
] ]
await smartapp.smartapp_sync_subscriptions( await smartapp.smartapp_sync_subscriptions(
@ -134,6 +134,25 @@ async def test_smartapp_sync_subscriptions_up_to_date(
assert smartthings_mock.create_subscription.call_count == 0 assert smartthings_mock.create_subscription.call_count == 0
async def test_smartapp_sync_subscriptions_limit_warning(
hass, smartthings_mock, device_factory, subscription_factory, caplog
):
"""Test synchronization over the limit logs a warning."""
smartthings_mock.subscriptions.return_value = []
devices = [
device_factory("", CAPABILITIES),
]
await smartapp.smartapp_sync_subscriptions(
hass, str(uuid4()), str(uuid4()), str(uuid4()), devices
)
assert (
"Some device attributes may not receive push updates and there may be "
"subscription creation failures" in caplog.text
)
async def test_smartapp_sync_subscriptions_handles_exceptions( async def test_smartapp_sync_subscriptions_handles_exceptions(
hass, smartthings_mock, device_factory, subscription_factory hass, smartthings_mock, device_factory, subscription_factory
): ):