mirror of
https://github.com/home-assistant/core.git
synced 2025-06-25 01:21:51 +02:00
Refactor SmartThings (#137940)
This commit is contained in:
committed by
GitHub
parent
bb9aba2a7d
commit
bb120020a8
2
CODEOWNERS
generated
2
CODEOWNERS
generated
@ -1401,6 +1401,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/smappee/ @bsmappee
|
||||
/homeassistant/components/smart_meter_texas/ @grahamwetzler
|
||||
/tests/components/smart_meter_texas/ @grahamwetzler
|
||||
/homeassistant/components/smartthings/ @joostlek
|
||||
/tests/components/smartthings/ @joostlek
|
||||
/homeassistant/components/smarttub/ @mdz
|
||||
/tests/components/smarttub/ @mdz
|
||||
/homeassistant/components/smarty/ @z0mbieprocess
|
||||
|
@ -2,416 +2,144 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Iterable
|
||||
from http import HTTPStatus
|
||||
import importlib
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from aiohttp.client_exceptions import ClientConnectionError, ClientResponseError
|
||||
from pysmartapp.event import EVENT_TYPE_DEVICE
|
||||
from pysmartthings import APIInvalidGrant, Attribute, Capability, SmartThings
|
||||
from aiohttp import ClientError
|
||||
from pysmartthings import (
|
||||
Attribute,
|
||||
Capability,
|
||||
Device,
|
||||
Scene,
|
||||
SmartThings,
|
||||
SmartThingsAuthenticationFailedError,
|
||||
Status,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_CLIENT_ID, CONF_CLIENT_SECRET
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_TOKEN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import (
|
||||
ConfigEntryAuthFailed,
|
||||
ConfigEntryError,
|
||||
ConfigEntryNotReady,
|
||||
)
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.loader import async_get_loaded_integration
|
||||
from homeassistant.setup import SetupPhases, async_pause_setup
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import (
|
||||
OAuth2Session,
|
||||
async_get_config_entry_implementation,
|
||||
)
|
||||
|
||||
from .config_flow import SmartThingsFlowHandler # noqa: F401
|
||||
from .const import (
|
||||
CONF_APP_ID,
|
||||
CONF_INSTALLED_APP_ID,
|
||||
CONF_LOCATION_ID,
|
||||
CONF_REFRESH_TOKEN,
|
||||
DATA_BROKERS,
|
||||
DATA_MANAGER,
|
||||
DOMAIN,
|
||||
EVENT_BUTTON,
|
||||
PLATFORMS,
|
||||
SIGNAL_SMARTTHINGS_UPDATE,
|
||||
TOKEN_REFRESH_INTERVAL,
|
||||
)
|
||||
from .smartapp import (
|
||||
format_unique_id,
|
||||
setup_smartapp,
|
||||
setup_smartapp_endpoint,
|
||||
smartapp_sync_subscriptions,
|
||||
unload_smartapp_endpoint,
|
||||
validate_installed_app,
|
||||
validate_webhook_requirements,
|
||||
)
|
||||
from .const import CONF_INSTALLED_APP_ID, CONF_LOCATION_ID, MAIN, OLD_DATA
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
||||
|
||||
@dataclass
|
||||
class SmartThingsData:
|
||||
"""Define an object to hold SmartThings data."""
|
||||
|
||||
devices: dict[str, FullDevice]
|
||||
scenes: dict[str, Scene]
|
||||
client: SmartThings
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Initialize the SmartThings platform."""
|
||||
await setup_smartapp_endpoint(hass, False)
|
||||
return True
|
||||
@dataclass
|
||||
class FullDevice:
|
||||
"""Define an object to hold device data."""
|
||||
|
||||
device: Device
|
||||
status: dict[str, dict[Capability, dict[Attribute, Status]]]
|
||||
|
||||
|
||||
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Handle migration of a previous version config entry.
|
||||
type SmartThingsConfigEntry = ConfigEntry[SmartThingsData]
|
||||
|
||||
A config entry created under a previous version must go through the
|
||||
integration setup again so we can properly retrieve the needed data
|
||||
elements. Force this by removing the entry and triggering a new flow.
|
||||
"""
|
||||
# Remove the entry which will invoke the callback to delete the app.
|
||||
hass.async_create_task(hass.config_entries.async_remove(entry.entry_id))
|
||||
# only create new flow if there isn't a pending one for SmartThings.
|
||||
if not hass.config_entries.flow.async_progress_by_handler(DOMAIN):
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_IMPORT}
|
||||
)
|
||||
)
|
||||
|
||||
# Return False because it could not be migrated.
|
||||
return False
|
||||
PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.CLIMATE,
|
||||
Platform.COVER,
|
||||
Platform.FAN,
|
||||
Platform.LIGHT,
|
||||
Platform.LOCK,
|
||||
Platform.SCENE,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: SmartThingsConfigEntry) -> bool:
|
||||
"""Initialize config entry which represents an installed SmartApp."""
|
||||
# For backwards compat
|
||||
if entry.unique_id is None:
|
||||
hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
unique_id=format_unique_id(
|
||||
entry.data[CONF_APP_ID], entry.data[CONF_LOCATION_ID]
|
||||
),
|
||||
)
|
||||
|
||||
if not validate_webhook_requirements(hass):
|
||||
_LOGGER.warning(
|
||||
"The 'base_url' of the 'http' integration must be configured and start with"
|
||||
" 'https://'"
|
||||
)
|
||||
return False
|
||||
|
||||
api = SmartThings(async_get_clientsession(hass), entry.data[CONF_ACCESS_TOKEN])
|
||||
|
||||
# Ensure platform modules are loaded since the DeviceBroker will
|
||||
# import them below and we want them to be cached ahead of time
|
||||
# so the integration does not do blocking I/O in the event loop
|
||||
# to import the modules.
|
||||
await async_get_loaded_integration(hass, DOMAIN).async_get_platforms(PLATFORMS)
|
||||
# The oauth smartthings entry will have a token, older ones are version 3
|
||||
# after migration but still require reauthentication
|
||||
if CONF_TOKEN not in entry.data:
|
||||
raise ConfigEntryAuthFailed("Config entry missing token")
|
||||
implementation = await async_get_config_entry_implementation(hass, entry)
|
||||
session = OAuth2Session(hass, entry, implementation)
|
||||
|
||||
try:
|
||||
# See if the app is already setup. This occurs when there are
|
||||
# installs in multiple SmartThings locations (valid use-case)
|
||||
manager = hass.data[DOMAIN][DATA_MANAGER]
|
||||
smart_app = manager.smartapps.get(entry.data[CONF_APP_ID])
|
||||
if not smart_app:
|
||||
# Validate and setup the app.
|
||||
app = await api.app(entry.data[CONF_APP_ID])
|
||||
smart_app = setup_smartapp(hass, app)
|
||||
await session.async_ensure_token_valid()
|
||||
except ClientError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
# Validate and retrieve the installed app.
|
||||
installed_app = await validate_installed_app(
|
||||
api, entry.data[CONF_INSTALLED_APP_ID]
|
||||
)
|
||||
client = SmartThings(session=async_get_clientsession(hass))
|
||||
|
||||
# Get scenes
|
||||
scenes = await async_get_entry_scenes(entry, api)
|
||||
async def _refresh_token() -> str:
|
||||
await session.async_ensure_token_valid()
|
||||
token = session.token[CONF_ACCESS_TOKEN]
|
||||
if TYPE_CHECKING:
|
||||
assert isinstance(token, str)
|
||||
return token
|
||||
|
||||
# Get SmartApp token to sync subscriptions
|
||||
token = await api.generate_tokens(
|
||||
entry.data[CONF_CLIENT_ID],
|
||||
entry.data[CONF_CLIENT_SECRET],
|
||||
entry.data[CONF_REFRESH_TOKEN],
|
||||
)
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, data={**entry.data, CONF_REFRESH_TOKEN: token.refresh_token}
|
||||
)
|
||||
client.refresh_token_function = _refresh_token
|
||||
|
||||
# Get devices and their current status
|
||||
devices = await api.devices(location_ids=[installed_app.location_id])
|
||||
device_status: dict[str, FullDevice] = {}
|
||||
try:
|
||||
devices = await client.get_devices()
|
||||
for device in devices:
|
||||
status = await client.get_device_status(device.device_id)
|
||||
device_status[device.device_id] = FullDevice(device=device, status=status)
|
||||
except SmartThingsAuthenticationFailedError as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
|
||||
async def retrieve_device_status(device):
|
||||
try:
|
||||
await device.status.refresh()
|
||||
except ClientResponseError:
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"Unable to update status for device: %s (%s), the device will"
|
||||
" be excluded"
|
||||
),
|
||||
device.label,
|
||||
device.device_id,
|
||||
exc_info=True,
|
||||
)
|
||||
devices.remove(device)
|
||||
scenes = {
|
||||
scene.scene_id: scene
|
||||
for scene in await client.get_scenes(location_id=entry.data[CONF_LOCATION_ID])
|
||||
}
|
||||
|
||||
await asyncio.gather(*(retrieve_device_status(d) for d in devices.copy()))
|
||||
entry.runtime_data = SmartThingsData(
|
||||
devices={
|
||||
device_id: device
|
||||
for device_id, device in device_status.items()
|
||||
if MAIN in device.status
|
||||
},
|
||||
client=client,
|
||||
scenes=scenes,
|
||||
)
|
||||
|
||||
# Sync device subscriptions
|
||||
await smartapp_sync_subscriptions(
|
||||
hass,
|
||||
token.access_token,
|
||||
installed_app.location_id,
|
||||
installed_app.installed_app_id,
|
||||
devices,
|
||||
)
|
||||
|
||||
# Setup device broker
|
||||
with async_pause_setup(hass, SetupPhases.WAIT_IMPORT_PLATFORMS):
|
||||
# DeviceBroker has a side effect of importing platform
|
||||
# modules when its created. In the future this should be
|
||||
# refactored to not do this.
|
||||
broker = await hass.async_add_import_executor_job(
|
||||
DeviceBroker, hass, entry, token, smart_app, devices, scenes
|
||||
)
|
||||
broker.connect()
|
||||
hass.data[DOMAIN][DATA_BROKERS][entry.entry_id] = broker
|
||||
|
||||
except APIInvalidGrant as ex:
|
||||
raise ConfigEntryAuthFailed from ex
|
||||
except ClientResponseError as ex:
|
||||
if ex.status in (HTTPStatus.UNAUTHORIZED, HTTPStatus.FORBIDDEN):
|
||||
raise ConfigEntryError(
|
||||
"The access token is no longer valid. Please remove the integration and set up again."
|
||||
) from ex
|
||||
_LOGGER.debug(ex, exc_info=True)
|
||||
raise ConfigEntryNotReady from ex
|
||||
except (ClientConnectionError, RuntimeWarning) as ex:
|
||||
_LOGGER.debug(ex, exc_info=True)
|
||||
raise ConfigEntryNotReady from ex
|
||||
entry.async_create_background_task(
|
||||
hass,
|
||||
client.subscribe(
|
||||
entry.data[CONF_LOCATION_ID], entry.data[CONF_TOKEN][CONF_INSTALLED_APP_ID]
|
||||
),
|
||||
"smartthings_webhook",
|
||||
)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_get_entry_scenes(entry: ConfigEntry, api):
|
||||
"""Get the scenes within an integration."""
|
||||
try:
|
||||
return await api.scenes(location_id=entry.data[CONF_LOCATION_ID])
|
||||
except ClientResponseError as ex:
|
||||
if ex.status == HTTPStatus.FORBIDDEN:
|
||||
_LOGGER.exception(
|
||||
(
|
||||
"Unable to load scenes for configuration entry '%s' because the"
|
||||
" access token does not have the required access"
|
||||
),
|
||||
entry.title,
|
||||
)
|
||||
else:
|
||||
raise
|
||||
return []
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_unload_entry(
|
||||
hass: HomeAssistant, entry: SmartThingsConfigEntry
|
||||
) -> bool:
|
||||
"""Unload a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS].pop(entry.entry_id, None)
|
||||
if broker:
|
||||
broker.disconnect()
|
||||
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
|
||||
async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||
"""Perform clean-up when entry is being removed."""
|
||||
api = SmartThings(async_get_clientsession(hass), entry.data[CONF_ACCESS_TOKEN])
|
||||
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Handle config entry migration."""
|
||||
|
||||
# Remove the installed_app, which if already removed raises a HTTPStatus.FORBIDDEN error.
|
||||
installed_app_id = entry.data[CONF_INSTALLED_APP_ID]
|
||||
try:
|
||||
await api.delete_installed_app(installed_app_id)
|
||||
except ClientResponseError as ex:
|
||||
if ex.status == HTTPStatus.FORBIDDEN:
|
||||
_LOGGER.debug(
|
||||
"Installed app %s has already been removed",
|
||||
installed_app_id,
|
||||
exc_info=True,
|
||||
)
|
||||
else:
|
||||
raise
|
||||
_LOGGER.debug("Removed installed app %s", installed_app_id)
|
||||
|
||||
# Remove the app if not referenced by other entries, which if already
|
||||
# removed raises a HTTPStatus.FORBIDDEN error.
|
||||
all_entries = hass.config_entries.async_entries(DOMAIN)
|
||||
app_id = entry.data[CONF_APP_ID]
|
||||
app_count = sum(1 for entry in all_entries if entry.data[CONF_APP_ID] == app_id)
|
||||
if app_count > 1:
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"App %s was not removed because it is in use by other configuration"
|
||||
" entries"
|
||||
),
|
||||
app_id,
|
||||
)
|
||||
return
|
||||
# Remove the app
|
||||
try:
|
||||
await api.delete_app(app_id)
|
||||
except ClientResponseError as ex:
|
||||
if ex.status == HTTPStatus.FORBIDDEN:
|
||||
_LOGGER.debug("App %s has already been removed", app_id, exc_info=True)
|
||||
else:
|
||||
raise
|
||||
_LOGGER.debug("Removed app %s", app_id)
|
||||
|
||||
if len(all_entries) == 1:
|
||||
await unload_smartapp_endpoint(hass)
|
||||
|
||||
|
||||
class DeviceBroker:
|
||||
"""Manages an individual SmartThings config entry."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
token,
|
||||
smart_app,
|
||||
devices: Iterable,
|
||||
scenes: Iterable,
|
||||
) -> None:
|
||||
"""Create a new instance of the DeviceBroker."""
|
||||
self._hass = hass
|
||||
self._entry = entry
|
||||
self._installed_app_id = entry.data[CONF_INSTALLED_APP_ID]
|
||||
self._smart_app = smart_app
|
||||
self._token = token
|
||||
self._event_disconnect = None
|
||||
self._regenerate_token_remove = None
|
||||
self._assignments = self._assign_capabilities(devices)
|
||||
self.devices = {device.device_id: device for device in devices}
|
||||
self.scenes = {scene.scene_id: scene for scene in scenes}
|
||||
|
||||
def _assign_capabilities(self, devices: Iterable):
|
||||
"""Assign platforms to capabilities."""
|
||||
assignments = {}
|
||||
for device in devices:
|
||||
capabilities = device.capabilities.copy()
|
||||
slots = {}
|
||||
for platform in PLATFORMS:
|
||||
platform_module = importlib.import_module(
|
||||
f".{platform}", self.__module__
|
||||
)
|
||||
if not hasattr(platform_module, "get_capabilities"):
|
||||
continue
|
||||
assigned = platform_module.get_capabilities(capabilities)
|
||||
if not assigned:
|
||||
continue
|
||||
# Draw-down capabilities and set slot assignment
|
||||
for capability in assigned:
|
||||
if capability not in capabilities:
|
||||
continue
|
||||
capabilities.remove(capability)
|
||||
slots[capability] = platform
|
||||
assignments[device.device_id] = slots
|
||||
return assignments
|
||||
|
||||
def connect(self):
|
||||
"""Connect handlers/listeners for device/lifecycle events."""
|
||||
|
||||
# Setup interval to regenerate the refresh token on a periodic basis.
|
||||
# Tokens expire in 30 days and once expired, cannot be recovered.
|
||||
async def regenerate_refresh_token(now):
|
||||
"""Generate a new refresh token and update the config entry."""
|
||||
await self._token.refresh(
|
||||
self._entry.data[CONF_CLIENT_ID],
|
||||
self._entry.data[CONF_CLIENT_SECRET],
|
||||
)
|
||||
self._hass.config_entries.async_update_entry(
|
||||
self._entry,
|
||||
data={
|
||||
**self._entry.data,
|
||||
CONF_REFRESH_TOKEN: self._token.refresh_token,
|
||||
},
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Regenerated refresh token for installed app: %s",
|
||||
self._installed_app_id,
|
||||
)
|
||||
|
||||
self._regenerate_token_remove = async_track_time_interval(
|
||||
self._hass, regenerate_refresh_token, TOKEN_REFRESH_INTERVAL
|
||||
if entry.version < 3:
|
||||
# We keep the old data around, so we can use that to clean up the webhook in the future
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, version=3, data={OLD_DATA: dict(entry.data)}
|
||||
)
|
||||
|
||||
# Connect handler to incoming device events
|
||||
self._event_disconnect = self._smart_app.connect_event(self._event_handler)
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnects handlers/listeners for device/lifecycle events."""
|
||||
if self._regenerate_token_remove:
|
||||
self._regenerate_token_remove()
|
||||
if self._event_disconnect:
|
||||
self._event_disconnect()
|
||||
|
||||
def get_assigned(self, device_id: str, platform: str):
|
||||
"""Get the capabilities assigned to the platform."""
|
||||
slots = self._assignments.get(device_id, {})
|
||||
return [key for key, value in slots.items() if value == platform]
|
||||
|
||||
def any_assigned(self, device_id: str, platform: str):
|
||||
"""Return True if the platform has any assigned capabilities."""
|
||||
slots = self._assignments.get(device_id, {})
|
||||
return any(value for value in slots.values() if value == platform)
|
||||
|
||||
async def _event_handler(self, req, resp, app):
|
||||
"""Broker for incoming events."""
|
||||
# Do not process events received from a different installed app
|
||||
# under the same parent SmartApp (valid use-scenario)
|
||||
if req.installed_app_id != self._installed_app_id:
|
||||
return
|
||||
|
||||
updated_devices = set()
|
||||
for evt in req.events:
|
||||
if evt.event_type != EVENT_TYPE_DEVICE:
|
||||
continue
|
||||
if not (device := self.devices.get(evt.device_id)):
|
||||
continue
|
||||
device.status.apply_attribute_update(
|
||||
evt.component_id,
|
||||
evt.capability,
|
||||
evt.attribute,
|
||||
evt.value,
|
||||
data=evt.data,
|
||||
)
|
||||
|
||||
# Fire events for buttons
|
||||
if (
|
||||
evt.capability == Capability.button
|
||||
and evt.attribute == Attribute.button
|
||||
):
|
||||
data = {
|
||||
"component_id": evt.component_id,
|
||||
"device_id": evt.device_id,
|
||||
"location_id": evt.location_id,
|
||||
"value": evt.value,
|
||||
"name": device.label,
|
||||
"data": evt.data,
|
||||
}
|
||||
self._hass.bus.async_fire(EVENT_BUTTON, data)
|
||||
_LOGGER.debug("Fired button event: %s", data)
|
||||
else:
|
||||
data = {
|
||||
"location_id": evt.location_id,
|
||||
"device_id": evt.device_id,
|
||||
"component_id": evt.component_id,
|
||||
"capability": evt.capability,
|
||||
"attribute": evt.attribute,
|
||||
"value": evt.value,
|
||||
"data": evt.data,
|
||||
}
|
||||
_LOGGER.debug("Push update received: %s", data)
|
||||
|
||||
updated_devices.add(device.device_id)
|
||||
|
||||
async_dispatcher_send(self._hass, SIGNAL_SMARTTHINGS_UPDATE, updated_devices)
|
||||
return True
|
||||
|
@ -0,0 +1,64 @@
|
||||
"""Application credentials platform for SmartThings."""
|
||||
|
||||
from json import JSONDecodeError
|
||||
import logging
|
||||
from typing import cast
|
||||
|
||||
from aiohttp import BasicAuth, ClientError
|
||||
|
||||
from homeassistant.components.application_credentials import (
|
||||
AuthImplementation,
|
||||
AuthorizationServer,
|
||||
ClientCredential,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import AbstractOAuth2Implementation
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_get_auth_implementation(
|
||||
hass: HomeAssistant, auth_domain: str, credential: ClientCredential
|
||||
) -> AbstractOAuth2Implementation:
|
||||
"""Return auth implementation."""
|
||||
return SmartThingsOAuth2Implementation(
|
||||
hass,
|
||||
DOMAIN,
|
||||
credential,
|
||||
authorization_server=AuthorizationServer(
|
||||
authorize_url="https://api.smartthings.com/oauth/authorize",
|
||||
token_url="https://auth-global.api.smartthings.com/oauth/token",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SmartThingsOAuth2Implementation(AuthImplementation):
|
||||
"""Oauth2 implementation that only uses the external url."""
|
||||
|
||||
async def _token_request(self, data: dict) -> dict:
|
||||
"""Make a token request."""
|
||||
session = async_get_clientsession(self.hass)
|
||||
|
||||
resp = await session.post(
|
||||
self.token_url,
|
||||
data=data,
|
||||
auth=BasicAuth(self.client_id, self.client_secret),
|
||||
)
|
||||
if resp.status >= 400:
|
||||
try:
|
||||
error_response = await resp.json()
|
||||
except (ClientError, JSONDecodeError):
|
||||
error_response = {}
|
||||
error_code = error_response.get("error", "unknown")
|
||||
error_description = error_response.get("error_description", "unknown error")
|
||||
_LOGGER.error(
|
||||
"Token request for %s failed (%s): %s",
|
||||
self.domain,
|
||||
error_code,
|
||||
error_description,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
return cast(dict, await resp.json())
|
@ -2,84 +2,144 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pysmartthings import Attribute, Capability
|
||||
from pysmartthings import Attribute, Capability, SmartThings
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
CAPABILITY_TO_ATTRIB = {
|
||||
Capability.acceleration_sensor: Attribute.acceleration,
|
||||
Capability.contact_sensor: Attribute.contact,
|
||||
Capability.filter_status: Attribute.filter_status,
|
||||
Capability.motion_sensor: Attribute.motion,
|
||||
Capability.presence_sensor: Attribute.presence,
|
||||
Capability.sound_sensor: Attribute.sound,
|
||||
Capability.tamper_alert: Attribute.tamper,
|
||||
Capability.valve: Attribute.valve,
|
||||
Capability.water_sensor: Attribute.water,
|
||||
}
|
||||
ATTRIB_TO_CLASS = {
|
||||
Attribute.acceleration: BinarySensorDeviceClass.MOVING,
|
||||
Attribute.contact: BinarySensorDeviceClass.OPENING,
|
||||
Attribute.filter_status: BinarySensorDeviceClass.PROBLEM,
|
||||
Attribute.motion: BinarySensorDeviceClass.MOTION,
|
||||
Attribute.presence: BinarySensorDeviceClass.PRESENCE,
|
||||
Attribute.sound: BinarySensorDeviceClass.SOUND,
|
||||
Attribute.tamper: BinarySensorDeviceClass.PROBLEM,
|
||||
Attribute.valve: BinarySensorDeviceClass.OPENING,
|
||||
Attribute.water: BinarySensorDeviceClass.MOISTURE,
|
||||
}
|
||||
ATTRIB_TO_ENTTIY_CATEGORY = {
|
||||
Attribute.tamper: EntityCategory.DIAGNOSTIC,
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class SmartThingsBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Describe a SmartThings binary sensor entity."""
|
||||
|
||||
is_on_key: str
|
||||
|
||||
|
||||
CAPABILITY_TO_SENSORS: dict[
|
||||
Capability, dict[Attribute, SmartThingsBinarySensorEntityDescription]
|
||||
] = {
|
||||
Capability.ACCELERATION_SENSOR: {
|
||||
Attribute.ACCELERATION: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.ACCELERATION,
|
||||
device_class=BinarySensorDeviceClass.MOVING,
|
||||
is_on_key="active",
|
||||
)
|
||||
},
|
||||
Capability.CONTACT_SENSOR: {
|
||||
Attribute.CONTACT: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.CONTACT,
|
||||
device_class=BinarySensorDeviceClass.DOOR,
|
||||
is_on_key="open",
|
||||
)
|
||||
},
|
||||
Capability.FILTER_STATUS: {
|
||||
Attribute.FILTER_STATUS: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.FILTER_STATUS,
|
||||
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||
is_on_key="replace",
|
||||
)
|
||||
},
|
||||
Capability.MOTION_SENSOR: {
|
||||
Attribute.MOTION: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.MOTION,
|
||||
device_class=BinarySensorDeviceClass.MOTION,
|
||||
is_on_key="active",
|
||||
)
|
||||
},
|
||||
Capability.PRESENCE_SENSOR: {
|
||||
Attribute.PRESENCE: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.PRESENCE,
|
||||
device_class=BinarySensorDeviceClass.PRESENCE,
|
||||
is_on_key="present",
|
||||
)
|
||||
},
|
||||
Capability.SOUND_SENSOR: {
|
||||
Attribute.SOUND: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.SOUND,
|
||||
device_class=BinarySensorDeviceClass.SOUND,
|
||||
is_on_key="detected",
|
||||
)
|
||||
},
|
||||
Capability.TAMPER_ALERT: {
|
||||
Attribute.TAMPER: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.TAMPER,
|
||||
device_class=BinarySensorDeviceClass.PROBLEM,
|
||||
is_on_key="detected",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
)
|
||||
},
|
||||
Capability.VALVE: {
|
||||
Attribute.VALVE: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.VALVE,
|
||||
device_class=BinarySensorDeviceClass.OPENING,
|
||||
is_on_key="open",
|
||||
)
|
||||
},
|
||||
Capability.WATER_SENSOR: {
|
||||
Attribute.WATER: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.WATER,
|
||||
device_class=BinarySensorDeviceClass.MOISTURE,
|
||||
is_on_key="wet",
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add binary sensors for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
sensors = []
|
||||
for device in broker.devices.values():
|
||||
for capability in broker.get_assigned(device.device_id, "binary_sensor"):
|
||||
attrib = CAPABILITY_TO_ATTRIB[capability]
|
||||
sensors.append(SmartThingsBinarySensor(device, attrib))
|
||||
async_add_entities(sensors)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
return [
|
||||
capability for capability in CAPABILITY_TO_ATTRIB if capability in capabilities
|
||||
]
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
SmartThingsBinarySensor(
|
||||
entry_data.client, device, description, capability, attribute
|
||||
)
|
||||
for device in entry_data.devices.values()
|
||||
for capability, attribute_map in CAPABILITY_TO_SENSORS.items()
|
||||
if capability in device.status[MAIN]
|
||||
for attribute, description in attribute_map.items()
|
||||
)
|
||||
|
||||
|
||||
class SmartThingsBinarySensor(SmartThingsEntity, BinarySensorEntity):
|
||||
"""Define a SmartThings Binary Sensor."""
|
||||
|
||||
def __init__(self, device, attribute):
|
||||
entity_description: SmartThingsBinarySensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
client: SmartThings,
|
||||
device: FullDevice,
|
||||
entity_description: SmartThingsBinarySensorEntityDescription,
|
||||
capability: Capability,
|
||||
attribute: Attribute,
|
||||
) -> None:
|
||||
"""Init the class."""
|
||||
super().__init__(device)
|
||||
super().__init__(client, device, {capability})
|
||||
self._attribute = attribute
|
||||
self._attr_name = f"{device.label} {attribute}"
|
||||
self._attr_unique_id = f"{device.device_id}.{attribute}"
|
||||
self._attr_device_class = ATTRIB_TO_CLASS[attribute]
|
||||
self._attr_entity_category = ATTRIB_TO_ENTTIY_CATEGORY.get(attribute)
|
||||
self.capability = capability
|
||||
self.entity_description = entity_description
|
||||
self._attr_name = f"{device.device.label} {attribute}"
|
||||
self._attr_unique_id = f"{device.device.device_id}.{attribute}"
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self._device.status.is_on(self._attribute)
|
||||
return (
|
||||
self.get_attribute_value(self.capability, self._attribute)
|
||||
== self.entity_description.is_on_key
|
||||
)
|
||||
|
@ -3,17 +3,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Iterable, Sequence
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Attribute, Capability
|
||||
from pysmartthings import Attribute, Capability, Command, SmartThings
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_TARGET_TEMP_HIGH,
|
||||
ATTR_TARGET_TEMP_LOW,
|
||||
DOMAIN as CLIMATE_DOMAIN,
|
||||
SWING_BOTH,
|
||||
SWING_HORIZONTAL,
|
||||
SWING_OFF,
|
||||
@ -23,12 +21,12 @@ from homeassistant.components.climate import (
|
||||
HVACAction,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
ATTR_OPERATION_STATE = "operation_state"
|
||||
@ -97,124 +95,106 @@ UNIT_MAP = {"C": UnitOfTemperature.CELSIUS, "F": UnitOfTemperature.FAHRENHEIT}
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
AC_CAPABILITIES = [
|
||||
Capability.AIR_CONDITIONER_MODE,
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
Capability.SWITCH,
|
||||
Capability.TEMPERATURE_MEASUREMENT,
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT,
|
||||
]
|
||||
|
||||
THERMOSTAT_CAPABILITIES = [
|
||||
Capability.TEMPERATURE_MEASUREMENT,
|
||||
Capability.THERMOSTAT_HEATING_SETPOINT,
|
||||
Capability.THERMOSTAT_MODE,
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add climate entities for a config entry."""
|
||||
ac_capabilities = [
|
||||
Capability.air_conditioner_mode,
|
||||
Capability.air_conditioner_fan_mode,
|
||||
Capability.switch,
|
||||
Capability.temperature_measurement,
|
||||
Capability.thermostat_cooling_setpoint,
|
||||
entry_data = entry.runtime_data
|
||||
entities: list[ClimateEntity] = [
|
||||
SmartThingsAirConditioner(entry_data.client, device)
|
||||
for device in entry_data.devices.values()
|
||||
if all(capability in device.status[MAIN] for capability in AC_CAPABILITIES)
|
||||
]
|
||||
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
entities: list[ClimateEntity] = []
|
||||
for device in broker.devices.values():
|
||||
if not broker.any_assigned(device.device_id, CLIMATE_DOMAIN):
|
||||
continue
|
||||
if all(capability in device.capabilities for capability in ac_capabilities):
|
||||
entities.append(SmartThingsAirConditioner(device))
|
||||
else:
|
||||
entities.append(SmartThingsThermostat(device))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
supported = [
|
||||
Capability.air_conditioner_mode,
|
||||
Capability.demand_response_load_control,
|
||||
Capability.air_conditioner_fan_mode,
|
||||
Capability.switch,
|
||||
Capability.thermostat,
|
||||
Capability.thermostat_cooling_setpoint,
|
||||
Capability.thermostat_fan_mode,
|
||||
Capability.thermostat_heating_setpoint,
|
||||
Capability.thermostat_mode,
|
||||
Capability.thermostat_operating_state,
|
||||
]
|
||||
# Can have this legacy/deprecated capability
|
||||
if Capability.thermostat in capabilities:
|
||||
return supported
|
||||
# Or must have all of these thermostat capabilities
|
||||
thermostat_capabilities = [
|
||||
Capability.temperature_measurement,
|
||||
Capability.thermostat_heating_setpoint,
|
||||
Capability.thermostat_mode,
|
||||
]
|
||||
if all(capability in capabilities for capability in thermostat_capabilities):
|
||||
return supported
|
||||
# Or must have all of these A/C capabilities
|
||||
ac_capabilities = [
|
||||
Capability.air_conditioner_mode,
|
||||
Capability.air_conditioner_fan_mode,
|
||||
Capability.switch,
|
||||
Capability.temperature_measurement,
|
||||
Capability.thermostat_cooling_setpoint,
|
||||
]
|
||||
if all(capability in capabilities for capability in ac_capabilities):
|
||||
return supported
|
||||
return None
|
||||
entities.extend(
|
||||
SmartThingsThermostat(entry_data.client, device)
|
||||
for device in entry_data.devices.values()
|
||||
if all(
|
||||
capability in device.status[MAIN] for capability in THERMOSTAT_CAPABILITIES
|
||||
)
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SmartThingsThermostat(SmartThingsEntity, ClimateEntity):
|
||||
"""Define a SmartThings climate entities."""
|
||||
|
||||
def __init__(self, device):
|
||||
def __init__(self, client: SmartThings, device: FullDevice) -> None:
|
||||
"""Init the class."""
|
||||
super().__init__(device)
|
||||
super().__init__(
|
||||
client,
|
||||
device,
|
||||
{
|
||||
Capability.THERMOSTAT_FAN_MODE,
|
||||
Capability.THERMOSTAT_MODE,
|
||||
Capability.TEMPERATURE_MEASUREMENT,
|
||||
Capability.THERMOSTAT_HEATING_SETPOINT,
|
||||
Capability.THERMOSTAT_OPERATING_STATE,
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT,
|
||||
Capability.RELATIVE_HUMIDITY_MEASUREMENT,
|
||||
},
|
||||
)
|
||||
self._attr_supported_features = self._determine_features()
|
||||
self._hvac_mode = None
|
||||
self._hvac_modes = None
|
||||
|
||||
def _determine_features(self):
|
||||
def _determine_features(self) -> ClimateEntityFeature:
|
||||
flags = (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
|
||||
| ClimateEntityFeature.TURN_OFF
|
||||
| ClimateEntityFeature.TURN_ON
|
||||
)
|
||||
if self._device.get_capability(
|
||||
Capability.thermostat_fan_mode, Capability.thermostat
|
||||
if self.get_attribute_value(
|
||||
Capability.THERMOSTAT_FAN_MODE, Attribute.THERMOSTAT_FAN_MODE
|
||||
):
|
||||
flags |= ClimateEntityFeature.FAN_MODE
|
||||
return flags
|
||||
|
||||
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||
"""Set new target fan mode."""
|
||||
await self._device.set_thermostat_fan_mode(fan_mode, set_status=True)
|
||||
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
await self.execute_device_command(
|
||||
Capability.THERMOSTAT_FAN_MODE,
|
||||
Command.SET_THERMOSTAT_FAN_MODE,
|
||||
argument=fan_mode,
|
||||
)
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set new target operation mode."""
|
||||
mode = STATE_TO_MODE[hvac_mode]
|
||||
await self._device.set_thermostat_mode(mode, set_status=True)
|
||||
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
await self.execute_device_command(
|
||||
Capability.THERMOSTAT_MODE,
|
||||
Command.SET_THERMOSTAT_MODE,
|
||||
argument=STATE_TO_MODE[hvac_mode],
|
||||
)
|
||||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new operation mode and target temperatures."""
|
||||
hvac_mode = self.hvac_mode
|
||||
# Operation state
|
||||
if operation_state := kwargs.get(ATTR_HVAC_MODE):
|
||||
mode = STATE_TO_MODE[operation_state]
|
||||
await self._device.set_thermostat_mode(mode, set_status=True)
|
||||
await self.async_update()
|
||||
await self.async_set_hvac_mode(operation_state)
|
||||
hvac_mode = operation_state
|
||||
|
||||
# Heat/cool setpoint
|
||||
heating_setpoint = None
|
||||
cooling_setpoint = None
|
||||
if self.hvac_mode == HVACMode.HEAT:
|
||||
if hvac_mode == HVACMode.HEAT:
|
||||
heating_setpoint = kwargs.get(ATTR_TEMPERATURE)
|
||||
elif self.hvac_mode == HVACMode.COOL:
|
||||
elif hvac_mode == HVACMode.COOL:
|
||||
cooling_setpoint = kwargs.get(ATTR_TEMPERATURE)
|
||||
else:
|
||||
heating_setpoint = kwargs.get(ATTR_TARGET_TEMP_LOW)
|
||||
@ -222,135 +202,145 @@ class SmartThingsThermostat(SmartThingsEntity, ClimateEntity):
|
||||
tasks = []
|
||||
if heating_setpoint is not None:
|
||||
tasks.append(
|
||||
self._device.set_heating_setpoint(
|
||||
round(heating_setpoint, 3), set_status=True
|
||||
self.execute_device_command(
|
||||
Capability.THERMOSTAT_HEATING_SETPOINT,
|
||||
Command.SET_HEATING_SETPOINT,
|
||||
argument=round(heating_setpoint, 3),
|
||||
)
|
||||
)
|
||||
if cooling_setpoint is not None:
|
||||
tasks.append(
|
||||
self._device.set_cooling_setpoint(
|
||||
round(cooling_setpoint, 3), set_status=True
|
||||
self.execute_device_command(
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT,
|
||||
Command.SET_COOLING_SETPOINT,
|
||||
argument=round(cooling_setpoint, 3),
|
||||
)
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
# State is set optimistically in the commands above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Update the attributes of the climate device."""
|
||||
thermostat_mode = self._device.status.thermostat_mode
|
||||
self._hvac_mode = MODE_TO_STATE.get(thermostat_mode)
|
||||
if self._hvac_mode is None:
|
||||
_LOGGER.debug(
|
||||
"Device %s (%s) returned an invalid hvac mode: %s",
|
||||
self._device.label,
|
||||
self._device.device_id,
|
||||
thermostat_mode,
|
||||
)
|
||||
|
||||
modes = set()
|
||||
supported_modes = self._device.status.supported_thermostat_modes
|
||||
if isinstance(supported_modes, Iterable):
|
||||
for mode in supported_modes:
|
||||
if (state := MODE_TO_STATE.get(mode)) is not None:
|
||||
modes.add(state)
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"Device %s (%s) returned an invalid supported thermostat"
|
||||
" mode: %s"
|
||||
),
|
||||
self._device.label,
|
||||
self._device.device_id,
|
||||
mode,
|
||||
)
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Device %s (%s) returned invalid supported thermostat modes: %s",
|
||||
self._device.label,
|
||||
self._device.device_id,
|
||||
supported_modes,
|
||||
)
|
||||
self._hvac_modes = list(modes)
|
||||
|
||||
@property
|
||||
def current_humidity(self):
|
||||
def current_humidity(self) -> float | None:
|
||||
"""Return the current humidity."""
|
||||
return self._device.status.humidity
|
||||
if self.supports_capability(Capability.RELATIVE_HUMIDITY_MEASUREMENT):
|
||||
return self.get_attribute_value(
|
||||
Capability.RELATIVE_HUMIDITY_MEASUREMENT, Attribute.HUMIDITY
|
||||
)
|
||||
return None
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the current temperature."""
|
||||
return self._device.status.temperature
|
||||
return self.get_attribute_value(
|
||||
Capability.TEMPERATURE_MEASUREMENT, Attribute.TEMPERATURE
|
||||
)
|
||||
|
||||
@property
|
||||
def fan_mode(self):
|
||||
def fan_mode(self) -> str | None:
|
||||
"""Return the fan setting."""
|
||||
return self._device.status.thermostat_fan_mode
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_FAN_MODE, Attribute.THERMOSTAT_FAN_MODE
|
||||
)
|
||||
|
||||
@property
|
||||
def fan_modes(self):
|
||||
def fan_modes(self) -> list[str]:
|
||||
"""Return the list of available fan modes."""
|
||||
return self._device.status.supported_thermostat_fan_modes
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_FAN_MODE, Attribute.SUPPORTED_THERMOSTAT_FAN_MODES
|
||||
)
|
||||
|
||||
@property
|
||||
def hvac_action(self) -> HVACAction | None:
|
||||
"""Return the current running hvac operation if supported."""
|
||||
return OPERATING_STATE_TO_ACTION.get(
|
||||
self._device.status.thermostat_operating_state
|
||||
self.get_attribute_value(
|
||||
Capability.THERMOSTAT_OPERATING_STATE,
|
||||
Attribute.THERMOSTAT_OPERATING_STATE,
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode:
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return current operation ie. heat, cool, idle."""
|
||||
return self._hvac_mode
|
||||
return MODE_TO_STATE.get(
|
||||
self.get_attribute_value(
|
||||
Capability.THERMOSTAT_MODE, Attribute.THERMOSTAT_MODE
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""Return the list of available operation modes."""
|
||||
return self._hvac_modes
|
||||
return [
|
||||
state
|
||||
for mode in self.get_attribute_value(
|
||||
Capability.THERMOSTAT_MODE, Attribute.SUPPORTED_THERMOSTAT_MODES
|
||||
)
|
||||
if (state := AC_MODE_TO_STATE.get(mode)) is not None
|
||||
]
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the temperature we try to reach."""
|
||||
if self.hvac_mode == HVACMode.COOL:
|
||||
return self._device.status.cooling_setpoint
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT, Attribute.COOLING_SETPOINT
|
||||
)
|
||||
if self.hvac_mode == HVACMode.HEAT:
|
||||
return self._device.status.heating_setpoint
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_HEATING_SETPOINT, Attribute.HEATING_SETPOINT
|
||||
)
|
||||
return None
|
||||
|
||||
@property
|
||||
def target_temperature_high(self):
|
||||
def target_temperature_high(self) -> float | None:
|
||||
"""Return the highbound target temperature we try to reach."""
|
||||
if self.hvac_mode == HVACMode.HEAT_COOL:
|
||||
return self._device.status.cooling_setpoint
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT, Attribute.COOLING_SETPOINT
|
||||
)
|
||||
return None
|
||||
|
||||
@property
|
||||
def target_temperature_low(self):
|
||||
"""Return the lowbound target temperature we try to reach."""
|
||||
if self.hvac_mode == HVACMode.HEAT_COOL:
|
||||
return self._device.status.heating_setpoint
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_HEATING_SETPOINT, Attribute.HEATING_SETPOINT
|
||||
)
|
||||
return None
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
def temperature_unit(self) -> str:
|
||||
"""Return the unit of measurement."""
|
||||
return UNIT_MAP.get(self._device.status.attributes[Attribute.temperature].unit)
|
||||
unit = self._internal_state[Capability.TEMPERATURE_MEASUREMENT][
|
||||
Attribute.TEMPERATURE
|
||||
].unit
|
||||
assert unit
|
||||
return UNIT_MAP[unit]
|
||||
|
||||
|
||||
class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
"""Define a SmartThings Air Conditioner."""
|
||||
|
||||
_hvac_modes: list[HVACMode]
|
||||
_attr_preset_mode = None
|
||||
|
||||
def __init__(self, device) -> None:
|
||||
def __init__(self, client: SmartThings, device: FullDevice) -> None:
|
||||
"""Init the class."""
|
||||
super().__init__(device)
|
||||
self._hvac_modes = []
|
||||
self._attr_preset_mode = None
|
||||
super().__init__(
|
||||
client,
|
||||
device,
|
||||
{
|
||||
Capability.AIR_CONDITIONER_MODE,
|
||||
Capability.SWITCH,
|
||||
Capability.FAN_OSCILLATION_MODE,
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT,
|
||||
Capability.TEMPERATURE_MEASUREMENT,
|
||||
Capability.CUSTOM_AIR_CONDITIONER_OPTIONAL_MODE,
|
||||
Capability.DEMAND_RESPONSE_LOAD_CONTROL,
|
||||
},
|
||||
)
|
||||
self._attr_hvac_modes = self._determine_hvac_modes()
|
||||
self._attr_preset_modes = self._determine_preset_modes()
|
||||
self._attr_swing_modes = self._determine_swing_modes()
|
||||
self._attr_supported_features = self._determine_supported_features()
|
||||
@ -362,7 +352,7 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
| ClimateEntityFeature.TURN_OFF
|
||||
| ClimateEntityFeature.TURN_ON
|
||||
)
|
||||
if self._device.get_capability(Capability.fan_oscillation_mode):
|
||||
if self.supports_capability(Capability.FAN_OSCILLATION_MODE):
|
||||
features |= ClimateEntityFeature.SWING_MODE
|
||||
if (self._attr_preset_modes is not None) and len(self._attr_preset_modes) > 0:
|
||||
features |= ClimateEntityFeature.PRESET_MODE
|
||||
@ -370,14 +360,11 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
|
||||
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||
"""Set new target fan mode."""
|
||||
await self._device.set_fan_mode(fan_mode, set_status=True)
|
||||
|
||||
# setting the fan must reset the preset mode (it deactivates the windFree function)
|
||||
self._attr_preset_mode = None
|
||||
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
Command.SET_FAN_MODE,
|
||||
argument=fan_mode,
|
||||
)
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set new target operation mode."""
|
||||
@ -386,23 +373,27 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
return
|
||||
tasks = []
|
||||
# Turn on the device if it's off before setting mode.
|
||||
if not self._device.status.switch:
|
||||
tasks.append(self._device.switch_on(set_status=True))
|
||||
if self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH) == "off":
|
||||
tasks.append(self.async_turn_on())
|
||||
|
||||
mode = STATE_TO_AC_MODE[hvac_mode]
|
||||
# If new hvac_mode is HVAC_MODE_FAN_ONLY and AirConditioner support "wind" mode the AirConditioner new mode has to be "wind"
|
||||
# The conversion make the mode change working
|
||||
# The conversion is made only for device that wrongly has capability "wind" instead "fan_only"
|
||||
if hvac_mode == HVACMode.FAN_ONLY:
|
||||
supported_modes = self._device.status.supported_ac_modes
|
||||
if WIND in supported_modes:
|
||||
if WIND in self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_MODE, Attribute.SUPPORTED_AC_MODES
|
||||
):
|
||||
mode = WIND
|
||||
|
||||
tasks.append(self._device.set_air_conditioner_mode(mode, set_status=True))
|
||||
tasks.append(
|
||||
self.execute_device_command(
|
||||
Capability.AIR_CONDITIONER_MODE,
|
||||
Command.SET_AIR_CONDITIONER_MODE,
|
||||
argument=mode,
|
||||
)
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
@ -410,53 +401,44 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
# operation mode
|
||||
if operation_mode := kwargs.get(ATTR_HVAC_MODE):
|
||||
if operation_mode == HVACMode.OFF:
|
||||
tasks.append(self._device.switch_off(set_status=True))
|
||||
tasks.append(self.async_turn_off())
|
||||
else:
|
||||
if not self._device.status.switch:
|
||||
tasks.append(self._device.switch_on(set_status=True))
|
||||
if (
|
||||
self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH)
|
||||
== "off"
|
||||
):
|
||||
tasks.append(self.async_turn_on())
|
||||
tasks.append(self.async_set_hvac_mode(operation_mode))
|
||||
# temperature
|
||||
tasks.append(
|
||||
self._device.set_cooling_setpoint(kwargs[ATTR_TEMPERATURE], set_status=True)
|
||||
self.execute_device_command(
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT,
|
||||
Command.SET_COOLING_SETPOINT,
|
||||
argument=kwargs[ATTR_TEMPERATURE],
|
||||
)
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_turn_on(self) -> None:
|
||||
"""Turn device on."""
|
||||
await self._device.switch_on(set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
Command.ON,
|
||||
)
|
||||
|
||||
async def async_turn_off(self) -> None:
|
||||
"""Turn device off."""
|
||||
await self._device.switch_off(set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Update the calculated fields of the AC."""
|
||||
modes = {HVACMode.OFF}
|
||||
for mode in self._device.status.supported_ac_modes:
|
||||
if (state := AC_MODE_TO_STATE.get(mode)) is not None:
|
||||
modes.add(state)
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Device %s (%s) returned an invalid supported AC mode: %s",
|
||||
self._device.label,
|
||||
self._device.device_id,
|
||||
mode,
|
||||
)
|
||||
self._hvac_modes = list(modes)
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
Command.OFF,
|
||||
)
|
||||
|
||||
@property
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the current temperature."""
|
||||
return self._device.status.temperature
|
||||
return self.get_attribute_value(
|
||||
Capability.TEMPERATURE_MEASUREMENT, Attribute.TEMPERATURE
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
@ -465,100 +447,114 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
Include attributes from the Demand Response Load Control (drlc)
|
||||
and Power Consumption capabilities.
|
||||
"""
|
||||
attributes = [
|
||||
"drlc_status_duration",
|
||||
"drlc_status_level",
|
||||
"drlc_status_start",
|
||||
"drlc_status_override",
|
||||
]
|
||||
state_attributes = {}
|
||||
for attribute in attributes:
|
||||
value = getattr(self._device.status, attribute)
|
||||
if value is not None:
|
||||
state_attributes[attribute] = value
|
||||
return state_attributes
|
||||
drlc_status = self.get_attribute_value(
|
||||
Capability.DEMAND_RESPONSE_LOAD_CONTROL,
|
||||
Attribute.DEMAND_RESPONSE_LOAD_CONTROL_STATUS,
|
||||
)
|
||||
return {
|
||||
"drlc_status_duration": drlc_status["duration"],
|
||||
"drlc_status_level": drlc_status["drlcLevel"],
|
||||
"drlc_status_start": drlc_status["start"],
|
||||
"drlc_status_override": drlc_status["override"],
|
||||
}
|
||||
|
||||
@property
|
||||
def fan_mode(self) -> str:
|
||||
"""Return the fan setting."""
|
||||
return self._device.status.fan_mode
|
||||
return self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE, Attribute.FAN_MODE
|
||||
)
|
||||
|
||||
@property
|
||||
def fan_modes(self) -> list[str]:
|
||||
"""Return the list of available fan modes."""
|
||||
return self._device.status.supported_ac_fan_modes
|
||||
return self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE, Attribute.SUPPORTED_AC_FAN_MODES
|
||||
)
|
||||
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return current operation ie. heat, cool, idle."""
|
||||
if not self._device.status.switch:
|
||||
if self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH) == "off":
|
||||
return HVACMode.OFF
|
||||
return AC_MODE_TO_STATE.get(self._device.status.air_conditioner_mode)
|
||||
|
||||
@property
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""Return the list of available operation modes."""
|
||||
return self._hvac_modes
|
||||
return AC_MODE_TO_STATE.get(
|
||||
self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_MODE, Attribute.AIR_CONDITIONER_MODE
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def target_temperature(self) -> float:
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._device.status.cooling_setpoint
|
||||
return self.get_attribute_value(
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT, Attribute.COOLING_SETPOINT
|
||||
)
|
||||
|
||||
@property
|
||||
def temperature_unit(self) -> str:
|
||||
"""Return the unit of measurement."""
|
||||
return UNIT_MAP[self._device.status.attributes[Attribute.temperature].unit]
|
||||
unit = self._internal_state[Capability.TEMPERATURE_MEASUREMENT][
|
||||
Attribute.TEMPERATURE
|
||||
].unit
|
||||
assert unit
|
||||
return UNIT_MAP[unit]
|
||||
|
||||
def _determine_swing_modes(self) -> list[str] | None:
|
||||
"""Return the list of available swing modes."""
|
||||
supported_swings = None
|
||||
supported_modes = self._device.status.attributes[
|
||||
Attribute.supported_fan_oscillation_modes
|
||||
][0]
|
||||
if supported_modes is not None:
|
||||
supported_swings = [
|
||||
FAN_OSCILLATION_TO_SWING.get(m, SWING_OFF) for m in supported_modes
|
||||
]
|
||||
return supported_swings
|
||||
if (
|
||||
supported_modes := self.get_attribute_value(
|
||||
Capability.FAN_OSCILLATION_MODE,
|
||||
Attribute.SUPPORTED_FAN_OSCILLATION_MODES,
|
||||
)
|
||||
) is None:
|
||||
return None
|
||||
return [FAN_OSCILLATION_TO_SWING.get(m, SWING_OFF) for m in supported_modes]
|
||||
|
||||
async def async_set_swing_mode(self, swing_mode: str) -> None:
|
||||
"""Set swing mode."""
|
||||
fan_oscillation_mode = SWING_TO_FAN_OSCILLATION[swing_mode]
|
||||
await self._device.set_fan_oscillation_mode(fan_oscillation_mode)
|
||||
|
||||
# setting the fan must reset the preset mode (it deactivates the windFree function)
|
||||
self._attr_preset_mode = None
|
||||
|
||||
self.async_schedule_update_ha_state(True)
|
||||
await self.execute_device_command(
|
||||
Capability.FAN_OSCILLATION_MODE,
|
||||
Command.SET_FAN_OSCILLATION_MODE,
|
||||
argument=SWING_TO_FAN_OSCILLATION[swing_mode],
|
||||
)
|
||||
|
||||
@property
|
||||
def swing_mode(self) -> str:
|
||||
"""Return the swing setting."""
|
||||
return FAN_OSCILLATION_TO_SWING.get(
|
||||
self._device.status.fan_oscillation_mode, SWING_OFF
|
||||
self.get_attribute_value(
|
||||
Capability.FAN_OSCILLATION_MODE, Attribute.FAN_OSCILLATION_MODE
|
||||
),
|
||||
SWING_OFF,
|
||||
)
|
||||
|
||||
def _determine_preset_modes(self) -> list[str] | None:
|
||||
"""Return a list of available preset modes."""
|
||||
supported_modes: list | None = self._device.status.attributes[
|
||||
"supportedAcOptionalMode"
|
||||
].value
|
||||
if supported_modes and WINDFREE in supported_modes:
|
||||
return [WINDFREE]
|
||||
if self.supports_capability(Capability.CUSTOM_AIR_CONDITIONER_OPTIONAL_MODE):
|
||||
supported_modes = self.get_attribute_value(
|
||||
Capability.CUSTOM_AIR_CONDITIONER_OPTIONAL_MODE,
|
||||
Attribute.SUPPORTED_AC_OPTIONAL_MODE,
|
||||
)
|
||||
if supported_modes and WINDFREE in supported_modes:
|
||||
return [WINDFREE]
|
||||
return None
|
||||
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set special modes (currently only windFree is supported)."""
|
||||
result = await self._device.command(
|
||||
"main",
|
||||
"custom.airConditionerOptionalMode",
|
||||
"setAcOptionalMode",
|
||||
[preset_mode],
|
||||
await self.execute_device_command(
|
||||
Capability.CUSTOM_AIR_CONDITIONER_OPTIONAL_MODE,
|
||||
Command.SET_AC_OPTIONAL_MODE,
|
||||
argument=preset_mode,
|
||||
)
|
||||
if result:
|
||||
self._device.status.update_attribute_value("acOptionalMode", preset_mode)
|
||||
|
||||
self._attr_preset_mode = preset_mode
|
||||
|
||||
self.async_write_ha_state()
|
||||
def _determine_hvac_modes(self) -> list[HVACMode]:
|
||||
"""Determine the supported HVAC modes."""
|
||||
modes = [HVACMode.OFF]
|
||||
modes.extend(
|
||||
state
|
||||
for mode in self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_MODE, Attribute.SUPPORTED_AC_MODES
|
||||
)
|
||||
if (state := AC_MODE_TO_STATE.get(mode)) is not None
|
||||
)
|
||||
return modes
|
||||
|
@ -1,298 +1,83 @@
|
||||
"""Config flow to configure SmartThings."""
|
||||
|
||||
from collections.abc import Mapping
|
||||
from http import HTTPStatus
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from aiohttp import ClientResponseError
|
||||
from pysmartthings import APIResponseError, AppOAuth, SmartThings
|
||||
from pysmartthings.installedapp import format_install_url
|
||||
import voluptuous as vol
|
||||
from pysmartthings import SmartThings
|
||||
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_CLIENT_ID, CONF_CLIENT_SECRET
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlowResult
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_TOKEN
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import AbstractOAuth2FlowHandler
|
||||
|
||||
from .const import (
|
||||
APP_OAUTH_CLIENT_NAME,
|
||||
APP_OAUTH_SCOPES,
|
||||
CONF_APP_ID,
|
||||
CONF_INSTALLED_APP_ID,
|
||||
CONF_LOCATION_ID,
|
||||
CONF_REFRESH_TOKEN,
|
||||
DOMAIN,
|
||||
VAL_UID_MATCHER,
|
||||
)
|
||||
from .smartapp import (
|
||||
create_app,
|
||||
find_app,
|
||||
format_unique_id,
|
||||
get_webhook_url,
|
||||
setup_smartapp,
|
||||
setup_smartapp_endpoint,
|
||||
update_app,
|
||||
validate_webhook_requirements,
|
||||
)
|
||||
from .const import CONF_LOCATION_ID, DOMAIN, OLD_DATA, SCOPES
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SmartThingsFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
class SmartThingsConfigFlow(AbstractOAuth2FlowHandler, domain=DOMAIN):
|
||||
"""Handle configuration of SmartThings integrations."""
|
||||
|
||||
VERSION = 2
|
||||
VERSION = 3
|
||||
DOMAIN = DOMAIN
|
||||
|
||||
api: SmartThings
|
||||
app_id: str
|
||||
location_id: str
|
||||
@property
|
||||
def logger(self) -> logging.Logger:
|
||||
"""Return logger."""
|
||||
return logging.getLogger(__name__)
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Create a new instance of the flow handler."""
|
||||
self.access_token: str | None = None
|
||||
self.oauth_client_secret = None
|
||||
self.oauth_client_id = None
|
||||
self.installed_app_id = None
|
||||
self.refresh_token = None
|
||||
self.endpoints_initialized = False
|
||||
@property
|
||||
def extra_authorize_data(self) -> dict[str, Any]:
|
||||
"""Extra data that needs to be appended to the authorize url."""
|
||||
return {"scope": " ".join(SCOPES)}
|
||||
|
||||
async def async_step_import(self, import_data: None) -> ConfigFlowResult:
|
||||
"""Occurs when a previously entry setup fails and is re-initiated."""
|
||||
return await self.async_step_user(import_data)
|
||||
async def async_oauth_create_entry(self, data: dict[str, Any]) -> ConfigFlowResult:
|
||||
"""Create an entry for SmartThings."""
|
||||
client = SmartThings(session=async_get_clientsession(self.hass))
|
||||
client.authenticate(data[CONF_TOKEN][CONF_ACCESS_TOKEN])
|
||||
locations = await client.get_locations()
|
||||
location = locations[0]
|
||||
# We pick to use the location id as unique id rather than the installed app id
|
||||
# as the installed app id could change with the right settings in the SmartApp
|
||||
# or the app used to sign in changed for any reason.
|
||||
await self.async_set_unique_id(location.location_id)
|
||||
if self.source != SOURCE_REAUTH:
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Validate and confirm webhook setup."""
|
||||
if not self.endpoints_initialized:
|
||||
self.endpoints_initialized = True
|
||||
await setup_smartapp_endpoint(
|
||||
self.hass, len(self._async_current_entries()) == 0
|
||||
return self.async_create_entry(
|
||||
title=location.name,
|
||||
data={**data, CONF_LOCATION_ID: location.location_id},
|
||||
)
|
||||
webhook_url = get_webhook_url(self.hass)
|
||||
|
||||
# Abort if the webhook is invalid
|
||||
if not validate_webhook_requirements(self.hass):
|
||||
return self.async_abort(
|
||||
reason="invalid_webhook_url",
|
||||
description_placeholders={
|
||||
"webhook_url": webhook_url,
|
||||
"component_url": (
|
||||
"https://www.home-assistant.io/integrations/smartthings/"
|
||||
),
|
||||
if (entry := self._get_reauth_entry()) and CONF_TOKEN not in entry.data:
|
||||
if entry.data[OLD_DATA][CONF_LOCATION_ID] != location.location_id:
|
||||
return self.async_abort(reason="reauth_location_mismatch")
|
||||
return self.async_update_reload_and_abort(
|
||||
self._get_reauth_entry(),
|
||||
data_updates={
|
||||
**data,
|
||||
CONF_LOCATION_ID: location.location_id,
|
||||
},
|
||||
unique_id=location.location_id,
|
||||
)
|
||||
|
||||
# Show the confirmation
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
description_placeholders={"webhook_url": webhook_url},
|
||||
)
|
||||
|
||||
# Show the next screen
|
||||
return await self.async_step_pat()
|
||||
|
||||
async def async_step_pat(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Get the Personal Access Token and validate it."""
|
||||
errors: dict[str, str] = {}
|
||||
if user_input is None or CONF_ACCESS_TOKEN not in user_input:
|
||||
return self._show_step_pat(errors)
|
||||
|
||||
self.access_token = user_input[CONF_ACCESS_TOKEN]
|
||||
|
||||
# Ensure token is a UUID
|
||||
if not VAL_UID_MATCHER.match(self.access_token):
|
||||
errors[CONF_ACCESS_TOKEN] = "token_invalid_format"
|
||||
return self._show_step_pat(errors)
|
||||
|
||||
# Setup end-point
|
||||
self.api = SmartThings(async_get_clientsession(self.hass), self.access_token)
|
||||
try:
|
||||
app = await find_app(self.hass, self.api)
|
||||
if app:
|
||||
await app.refresh() # load all attributes
|
||||
await update_app(self.hass, app)
|
||||
# Find an existing entry to copy the oauth client
|
||||
existing = next(
|
||||
(
|
||||
entry
|
||||
for entry in self._async_current_entries()
|
||||
if entry.data[CONF_APP_ID] == app.app_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if existing:
|
||||
self.oauth_client_id = existing.data[CONF_CLIENT_ID]
|
||||
self.oauth_client_secret = existing.data[CONF_CLIENT_SECRET]
|
||||
else:
|
||||
# Get oauth client id/secret by regenerating it
|
||||
app_oauth = AppOAuth(app.app_id)
|
||||
app_oauth.client_name = APP_OAUTH_CLIENT_NAME
|
||||
app_oauth.scope.extend(APP_OAUTH_SCOPES)
|
||||
client = await self.api.generate_app_oauth(app_oauth)
|
||||
self.oauth_client_secret = client.client_secret
|
||||
self.oauth_client_id = client.client_id
|
||||
else:
|
||||
app, client = await create_app(self.hass, self.api)
|
||||
self.oauth_client_secret = client.client_secret
|
||||
self.oauth_client_id = client.client_id
|
||||
setup_smartapp(self.hass, app)
|
||||
self.app_id = app.app_id
|
||||
|
||||
except APIResponseError as ex:
|
||||
if ex.is_target_error():
|
||||
errors["base"] = "webhook_error"
|
||||
else:
|
||||
errors["base"] = "app_setup_error"
|
||||
_LOGGER.exception(
|
||||
"API error setting up the SmartApp: %s", ex.raw_error_response
|
||||
)
|
||||
return self._show_step_pat(errors)
|
||||
except ClientResponseError as ex:
|
||||
if ex.status == HTTPStatus.UNAUTHORIZED:
|
||||
errors[CONF_ACCESS_TOKEN] = "token_unauthorized"
|
||||
_LOGGER.debug(
|
||||
"Unauthorized error received setting up SmartApp", exc_info=True
|
||||
)
|
||||
elif ex.status == HTTPStatus.FORBIDDEN:
|
||||
errors[CONF_ACCESS_TOKEN] = "token_forbidden"
|
||||
_LOGGER.debug(
|
||||
"Forbidden error received setting up SmartApp", exc_info=True
|
||||
)
|
||||
else:
|
||||
errors["base"] = "app_setup_error"
|
||||
_LOGGER.exception("Unexpected error setting up the SmartApp")
|
||||
return self._show_step_pat(errors)
|
||||
except Exception:
|
||||
errors["base"] = "app_setup_error"
|
||||
_LOGGER.exception("Unexpected error setting up the SmartApp")
|
||||
return self._show_step_pat(errors)
|
||||
|
||||
return await self.async_step_select_location()
|
||||
|
||||
async def async_step_select_location(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask user to select the location to setup."""
|
||||
if user_input is None or CONF_LOCATION_ID not in user_input:
|
||||
# Get available locations
|
||||
existing_locations = [
|
||||
entry.data[CONF_LOCATION_ID] for entry in self._async_current_entries()
|
||||
]
|
||||
locations = await self.api.locations()
|
||||
locations_options = {
|
||||
location.location_id: location.name
|
||||
for location in locations
|
||||
if location.location_id not in existing_locations
|
||||
}
|
||||
if not locations_options:
|
||||
return self.async_abort(reason="no_available_locations")
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="select_location",
|
||||
data_schema=vol.Schema(
|
||||
{vol.Required(CONF_LOCATION_ID): vol.In(locations_options)}
|
||||
),
|
||||
)
|
||||
|
||||
self.location_id = user_input[CONF_LOCATION_ID]
|
||||
await self.async_set_unique_id(format_unique_id(self.app_id, self.location_id))
|
||||
return await self.async_step_authorize()
|
||||
|
||||
async def async_step_authorize(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Wait for the user to authorize the app installation."""
|
||||
user_input = {} if user_input is None else user_input
|
||||
self.installed_app_id = user_input.get(CONF_INSTALLED_APP_ID)
|
||||
self.refresh_token = user_input.get(CONF_REFRESH_TOKEN)
|
||||
if self.installed_app_id is None:
|
||||
# Launch the external setup URL
|
||||
url = format_install_url(self.app_id, self.location_id)
|
||||
return self.async_external_step(step_id="authorize", url=url)
|
||||
|
||||
next_step_id = "install"
|
||||
if self.source == SOURCE_REAUTH:
|
||||
next_step_id = "update"
|
||||
return self.async_external_step_done(next_step_id=next_step_id)
|
||||
|
||||
def _show_step_pat(self, errors):
|
||||
if self.access_token is None:
|
||||
# Get the token from an existing entry to make it easier to setup multiple locations.
|
||||
self.access_token = next(
|
||||
(
|
||||
entry.data.get(CONF_ACCESS_TOKEN)
|
||||
for entry in self._async_current_entries()
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="pat",
|
||||
data_schema=vol.Schema(
|
||||
{vol.Required(CONF_ACCESS_TOKEN, default=self.access_token): str}
|
||||
),
|
||||
errors=errors,
|
||||
description_placeholders={
|
||||
"token_url": "https://account.smartthings.com/tokens",
|
||||
"component_url": (
|
||||
"https://www.home-assistant.io/integrations/smartthings/"
|
||||
),
|
||||
},
|
||||
self._abort_if_unique_id_mismatch(reason="reauth_account_mismatch")
|
||||
return self.async_update_reload_and_abort(
|
||||
self._get_reauth_entry(), data_updates=data
|
||||
)
|
||||
|
||||
async def async_step_reauth(
|
||||
self, entry_data: Mapping[str, Any]
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle re-authentication of an existing config entry."""
|
||||
"""Perform reauth upon migration of old entries."""
|
||||
return await self.async_step_reauth_confirm()
|
||||
|
||||
async def async_step_reauth_confirm(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle re-authentication of an existing config entry."""
|
||||
"""Confirm reauth dialog."""
|
||||
if user_input is None:
|
||||
return self.async_show_form(step_id="reauth_confirm")
|
||||
self.app_id = self._get_reauth_entry().data[CONF_APP_ID]
|
||||
self.location_id = self._get_reauth_entry().data[CONF_LOCATION_ID]
|
||||
self._set_confirm_only()
|
||||
return await self.async_step_authorize()
|
||||
|
||||
async def async_step_update(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle re-authentication of an existing config entry."""
|
||||
return await self.async_step_update_confirm()
|
||||
|
||||
async def async_step_update_confirm(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle re-authentication of an existing config entry."""
|
||||
if user_input is None:
|
||||
self._set_confirm_only()
|
||||
return self.async_show_form(step_id="update_confirm")
|
||||
entry = self._get_reauth_entry()
|
||||
return self.async_update_reload_and_abort(
|
||||
entry, data_updates={CONF_REFRESH_TOKEN: self.refresh_token}
|
||||
)
|
||||
|
||||
async def async_step_install(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Create a config entry at completion of a flow and authorization of the app."""
|
||||
data = {
|
||||
CONF_ACCESS_TOKEN: self.access_token,
|
||||
CONF_REFRESH_TOKEN: self.refresh_token,
|
||||
CONF_CLIENT_ID: self.oauth_client_id,
|
||||
CONF_CLIENT_SECRET: self.oauth_client_secret,
|
||||
CONF_LOCATION_ID: self.location_id,
|
||||
CONF_APP_ID: self.app_id,
|
||||
CONF_INSTALLED_APP_ID: self.installed_app_id,
|
||||
}
|
||||
|
||||
location = await self.api.location(data[CONF_LOCATION_ID])
|
||||
|
||||
return self.async_create_entry(title=location.name, data=data)
|
||||
return self.async_show_form(
|
||||
step_id="reauth_confirm",
|
||||
)
|
||||
return await self.async_step_user()
|
||||
|
@ -1,15 +1,23 @@
|
||||
"""Constants used by the SmartThings component and platforms."""
|
||||
|
||||
from datetime import timedelta
|
||||
import re
|
||||
|
||||
from homeassistant.const import Platform
|
||||
|
||||
DOMAIN = "smartthings"
|
||||
|
||||
APP_OAUTH_CLIENT_NAME = "Home Assistant"
|
||||
APP_OAUTH_SCOPES = ["r:devices:*"]
|
||||
APP_NAME_PREFIX = "homeassistant."
|
||||
SCOPES = [
|
||||
"r:devices:*",
|
||||
"w:devices:*",
|
||||
"x:devices:*",
|
||||
"r:hubs:*",
|
||||
"r:locations:*",
|
||||
"w:locations:*",
|
||||
"x:locations:*",
|
||||
"r:scenes:*",
|
||||
"x:scenes:*",
|
||||
"r:rules:*",
|
||||
"w:rules:*",
|
||||
"r:installedapps",
|
||||
"w:installedapps",
|
||||
"sse",
|
||||
]
|
||||
|
||||
CONF_APP_ID = "app_id"
|
||||
CONF_CLOUDHOOK_URL = "cloudhook_url"
|
||||
@ -18,41 +26,5 @@ CONF_INSTANCE_ID = "instance_id"
|
||||
CONF_LOCATION_ID = "location_id"
|
||||
CONF_REFRESH_TOKEN = "refresh_token"
|
||||
|
||||
DATA_MANAGER = "manager"
|
||||
DATA_BROKERS = "brokers"
|
||||
EVENT_BUTTON = "smartthings.button"
|
||||
|
||||
SIGNAL_SMARTTHINGS_UPDATE = "smartthings_update"
|
||||
SIGNAL_SMARTAPP_PREFIX = "smartthings_smartap_"
|
||||
|
||||
SETTINGS_INSTANCE_ID = "hassInstanceId"
|
||||
|
||||
SUBSCRIPTION_WARNING_LIMIT = 40
|
||||
|
||||
STORAGE_KEY = DOMAIN
|
||||
STORAGE_VERSION = 1
|
||||
|
||||
# Ordered 'specific to least-specific platform' in order for capabilities
|
||||
# to be drawn-down and represented by the most appropriate platform.
|
||||
PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.CLIMATE,
|
||||
Platform.COVER,
|
||||
Platform.FAN,
|
||||
Platform.LIGHT,
|
||||
Platform.LOCK,
|
||||
Platform.SCENE,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
]
|
||||
|
||||
IGNORED_CAPABILITIES = [
|
||||
"execute",
|
||||
"healthCheck",
|
||||
"ocf",
|
||||
]
|
||||
|
||||
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_MATCHER = re.compile(VAL_UID)
|
||||
MAIN = "main"
|
||||
OLD_DATA = "old_data"
|
||||
|
@ -2,25 +2,23 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Attribute, Capability
|
||||
from pysmartthings import Attribute, Capability, Command, SmartThings
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
DOMAIN as COVER_DOMAIN,
|
||||
CoverDeviceClass,
|
||||
CoverEntity,
|
||||
CoverEntityFeature,
|
||||
CoverState,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
VALUE_TO_STATE = {
|
||||
@ -32,114 +30,99 @@ VALUE_TO_STATE = {
|
||||
"unknown": None,
|
||||
}
|
||||
|
||||
CAPABILITIES = (Capability.WINDOW_SHADE, Capability.DOOR_CONTROL)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add covers for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
[
|
||||
SmartThingsCover(device)
|
||||
for device in broker.devices.values()
|
||||
if broker.any_assigned(device.device_id, COVER_DOMAIN)
|
||||
],
|
||||
True,
|
||||
SmartThingsCover(entry_data.client, device, capability)
|
||||
for device in entry_data.devices.values()
|
||||
for capability in device.status[MAIN]
|
||||
if capability in CAPABILITIES
|
||||
)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
min_required = [
|
||||
Capability.door_control,
|
||||
Capability.garage_door_control,
|
||||
Capability.window_shade,
|
||||
]
|
||||
# Must have one of the min_required
|
||||
if any(capability in capabilities for capability in min_required):
|
||||
# Return all capabilities supported/consumed
|
||||
return [
|
||||
*min_required,
|
||||
Capability.battery,
|
||||
Capability.switch_level,
|
||||
Capability.window_shade_level,
|
||||
]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class SmartThingsCover(SmartThingsEntity, CoverEntity):
|
||||
"""Define a SmartThings cover."""
|
||||
|
||||
def __init__(self, device):
|
||||
_state: CoverState | None = None
|
||||
|
||||
def __init__(
|
||||
self, client: SmartThings, device: FullDevice, capability: Capability
|
||||
) -> None:
|
||||
"""Initialize the cover class."""
|
||||
super().__init__(device)
|
||||
self._current_cover_position = None
|
||||
self._state = None
|
||||
super().__init__(
|
||||
client,
|
||||
device,
|
||||
{
|
||||
capability,
|
||||
Capability.BATTERY,
|
||||
Capability.WINDOW_SHADE_LEVEL,
|
||||
Capability.SWITCH_LEVEL,
|
||||
},
|
||||
)
|
||||
self.capability = capability
|
||||
self._attr_supported_features = (
|
||||
CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
||||
)
|
||||
if (
|
||||
Capability.switch_level in device.capabilities
|
||||
or Capability.window_shade_level in device.capabilities
|
||||
):
|
||||
if self.supports_capability(Capability.WINDOW_SHADE_LEVEL):
|
||||
self.level_capability = Capability.WINDOW_SHADE_LEVEL
|
||||
self.level_command = Command.SET_SHADE_LEVEL
|
||||
else:
|
||||
self.level_capability = Capability.SWITCH_LEVEL
|
||||
self.level_command = Command.SET_LEVEL
|
||||
if self.supports_capability(
|
||||
Capability.SWITCH_LEVEL
|
||||
) or self.supports_capability(Capability.WINDOW_SHADE_LEVEL):
|
||||
self._attr_supported_features |= CoverEntityFeature.SET_POSITION
|
||||
|
||||
if Capability.door_control in device.capabilities:
|
||||
if self.supports_capability(Capability.DOOR_CONTROL):
|
||||
self._attr_device_class = CoverDeviceClass.DOOR
|
||||
elif Capability.window_shade in device.capabilities:
|
||||
elif self.supports_capability(Capability.WINDOW_SHADE):
|
||||
self._attr_device_class = CoverDeviceClass.SHADE
|
||||
elif Capability.garage_door_control in device.capabilities:
|
||||
self._attr_device_class = CoverDeviceClass.GARAGE
|
||||
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Close cover."""
|
||||
# Same command for all 3 supported capabilities
|
||||
await self._device.close(set_status=True)
|
||||
# State is set optimistically in the commands above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
await self.execute_device_command(self.capability, Command.CLOSE)
|
||||
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Open the cover."""
|
||||
# Same for all capability types
|
||||
await self._device.open(set_status=True)
|
||||
# State is set optimistically in the commands above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
await self.execute_device_command(self.capability, Command.OPEN)
|
||||
|
||||
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
||||
"""Move the cover to a specific position."""
|
||||
if not self.supported_features & CoverEntityFeature.SET_POSITION:
|
||||
return
|
||||
# Do not set_status=True as device will report progress.
|
||||
if Capability.window_shade_level in self._device.capabilities:
|
||||
await self._device.set_window_shade_level(
|
||||
kwargs[ATTR_POSITION], set_status=False
|
||||
)
|
||||
else:
|
||||
await self._device.set_level(kwargs[ATTR_POSITION], set_status=False)
|
||||
await self.execute_device_command(
|
||||
self.level_capability,
|
||||
self.level_command,
|
||||
argument=kwargs[ATTR_POSITION],
|
||||
)
|
||||
|
||||
async def async_update(self) -> None:
|
||||
def _update_attr(self) -> None:
|
||||
"""Update the attrs of the cover."""
|
||||
if Capability.door_control in self._device.capabilities:
|
||||
self._state = VALUE_TO_STATE.get(self._device.status.door)
|
||||
elif Capability.window_shade in self._device.capabilities:
|
||||
self._state = VALUE_TO_STATE.get(self._device.status.window_shade)
|
||||
elif Capability.garage_door_control in self._device.capabilities:
|
||||
self._state = VALUE_TO_STATE.get(self._device.status.door)
|
||||
attribute = {
|
||||
Capability.WINDOW_SHADE: Attribute.WINDOW_SHADE,
|
||||
Capability.DOOR_CONTROL: Attribute.DOOR,
|
||||
}[self.capability]
|
||||
self._state = VALUE_TO_STATE.get(
|
||||
self.get_attribute_value(self.capability, attribute)
|
||||
)
|
||||
|
||||
if Capability.window_shade_level in self._device.capabilities:
|
||||
self._attr_current_cover_position = self._device.status.shade_level
|
||||
elif Capability.switch_level in self._device.capabilities:
|
||||
self._attr_current_cover_position = self._device.status.level
|
||||
if self.supports_capability(Capability.SWITCH_LEVEL):
|
||||
self._attr_current_cover_position = self.get_attribute_value(
|
||||
Capability.SWITCH_LEVEL, Attribute.LEVEL
|
||||
)
|
||||
|
||||
self._attr_extra_state_attributes = {}
|
||||
battery = self._device.status.attributes[Attribute.battery].value
|
||||
if battery is not None:
|
||||
self._attr_extra_state_attributes[ATTR_BATTERY_LEVEL] = battery
|
||||
if self.supports_capability(Capability.BATTERY):
|
||||
self._attr_extra_state_attributes[ATTR_BATTERY_LEVEL] = (
|
||||
self.get_attribute_value(Capability.BATTERY, Attribute.BATTERY)
|
||||
)
|
||||
|
||||
@property
|
||||
def is_opening(self) -> bool:
|
||||
|
@ -2,13 +2,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pysmartthings.device import DeviceEntity
|
||||
from typing import Any, cast
|
||||
|
||||
from pysmartthings import Attribute, Capability, Command, DeviceEvent, SmartThings
|
||||
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import DOMAIN, SIGNAL_SMARTTHINGS_UPDATE
|
||||
from . import FullDevice
|
||||
from .const import DOMAIN, MAIN
|
||||
|
||||
|
||||
class SmartThingsEntity(Entity):
|
||||
@ -16,35 +18,86 @@ class SmartThingsEntity(Entity):
|
||||
|
||||
_attr_should_poll = False
|
||||
|
||||
def __init__(self, device: DeviceEntity) -> None:
|
||||
def __init__(
|
||||
self, client: SmartThings, device: FullDevice, capabilities: set[Capability]
|
||||
) -> None:
|
||||
"""Initialize the instance."""
|
||||
self._device = device
|
||||
self._dispatcher_remove = None
|
||||
self._attr_name = device.label
|
||||
self._attr_unique_id = device.device_id
|
||||
self.client = client
|
||||
self.capabilities = capabilities
|
||||
self._internal_state = {
|
||||
capability: device.status[MAIN][capability]
|
||||
for capability in capabilities
|
||||
if capability in device.status[MAIN]
|
||||
}
|
||||
self.device = device
|
||||
self._attr_name = device.device.label
|
||||
self._attr_unique_id = device.device.device_id
|
||||
self._attr_device_info = DeviceInfo(
|
||||
configuration_url="https://account.smartthings.com",
|
||||
identifiers={(DOMAIN, device.device_id)},
|
||||
manufacturer=device.status.ocf_manufacturer_name,
|
||||
model=device.status.ocf_model_number,
|
||||
name=device.label,
|
||||
hw_version=device.status.ocf_hardware_version,
|
||||
sw_version=device.status.ocf_firmware_version,
|
||||
identifiers={(DOMAIN, device.device.device_id)},
|
||||
name=device.device.label,
|
||||
)
|
||||
if (ocf := device.status[MAIN].get(Capability.OCF)) is not None:
|
||||
self._attr_device_info.update(
|
||||
{
|
||||
"manufacturer": cast(
|
||||
str | None, ocf[Attribute.MANUFACTURER_NAME].value
|
||||
),
|
||||
"model": cast(str | None, ocf[Attribute.MODEL_NUMBER].value),
|
||||
"hw_version": cast(
|
||||
str | None, ocf[Attribute.HARDWARE_VERSION].value
|
||||
),
|
||||
"sw_version": cast(
|
||||
str | None, ocf[Attribute.OCF_FIRMWARE_VERSION].value
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Device added to hass."""
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe to updates."""
|
||||
await super().async_added_to_hass()
|
||||
for capability in self._internal_state:
|
||||
self.async_on_remove(
|
||||
self.client.add_device_event_listener(
|
||||
self.device.device.device_id,
|
||||
MAIN,
|
||||
capability,
|
||||
self._update_handler,
|
||||
)
|
||||
)
|
||||
self._update_attr()
|
||||
|
||||
async def async_update_state(devices):
|
||||
"""Update device state."""
|
||||
if self._device.device_id in devices:
|
||||
await self.async_update_ha_state(True)
|
||||
def _update_handler(self, event: DeviceEvent) -> None:
|
||||
self._internal_state[event.capability][event.attribute].value = event.value
|
||||
self._internal_state[event.capability][event.attribute].data = event.data
|
||||
self._handle_update()
|
||||
|
||||
self._dispatcher_remove = async_dispatcher_connect(
|
||||
self.hass, SIGNAL_SMARTTHINGS_UPDATE, async_update_state
|
||||
def supports_capability(self, capability: Capability) -> bool:
|
||||
"""Test if device supports a capability."""
|
||||
return capability in self.device.status[MAIN]
|
||||
|
||||
def get_attribute_value(self, capability: Capability, attribute: Attribute) -> Any:
|
||||
"""Get the value of a device attribute."""
|
||||
return self._internal_state[capability][attribute].value
|
||||
|
||||
def _update_attr(self) -> None:
|
||||
"""Update the attributes."""
|
||||
|
||||
def _handle_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._update_attr()
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def execute_device_command(
|
||||
self,
|
||||
capability: Capability,
|
||||
command: Command,
|
||||
argument: int | str | list[Any] | dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Execute a command on the device."""
|
||||
kwargs = {}
|
||||
if argument is not None:
|
||||
kwargs["argument"] = argument
|
||||
await self.client.execute_device_command(
|
||||
self.device.device.device_id, capability, command, MAIN, **kwargs
|
||||
)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect the device when removed."""
|
||||
if self._dispatcher_remove:
|
||||
self._dispatcher_remove()
|
||||
|
@ -2,14 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Capability
|
||||
from pysmartthings import Attribute, Capability, Command, SmartThings
|
||||
|
||||
from homeassistant.components.fan import FanEntity, FanEntityFeature
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util.percentage import (
|
||||
@ -18,7 +16,8 @@ from homeassistant.util.percentage import (
|
||||
)
|
||||
from homeassistant.util.scaling import int_states_in_range
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
SPEED_RANGE = (1, 3) # off is not included
|
||||
@ -26,86 +25,73 @@ SPEED_RANGE = (1, 3) # off is not included
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add fans for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
SmartThingsFan(device)
|
||||
for device in broker.devices.values()
|
||||
if broker.any_assigned(device.device_id, "fan")
|
||||
SmartThingsFan(entry_data.client, device)
|
||||
for device in entry_data.devices.values()
|
||||
if Capability.SWITCH in device.status[MAIN]
|
||||
and any(
|
||||
capability in device.status[MAIN]
|
||||
for capability in (
|
||||
Capability.FAN_SPEED,
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
)
|
||||
)
|
||||
and Capability.THERMOSTAT_COOLING_SETPOINT not in device.status[MAIN]
|
||||
)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
|
||||
# MUST support switch as we need a way to turn it on and off
|
||||
if Capability.switch not in capabilities:
|
||||
return None
|
||||
|
||||
# These are all optional but at least one must be supported
|
||||
optional = [
|
||||
Capability.air_conditioner_fan_mode,
|
||||
Capability.fan_speed,
|
||||
]
|
||||
|
||||
# At least one of the optional capabilities must be supported
|
||||
# to classify this entity as a fan.
|
||||
# If they are not then return None and don't setup the platform.
|
||||
if not any(capability in capabilities for capability in optional):
|
||||
return None
|
||||
|
||||
supported = [Capability.switch]
|
||||
|
||||
supported.extend(
|
||||
capability for capability in optional if capability in capabilities
|
||||
)
|
||||
|
||||
return supported
|
||||
|
||||
|
||||
class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
"""Define a SmartThings Fan."""
|
||||
|
||||
_attr_speed_count = int_states_in_range(SPEED_RANGE)
|
||||
|
||||
def __init__(self, device):
|
||||
def __init__(self, client: SmartThings, device: FullDevice) -> None:
|
||||
"""Init the class."""
|
||||
super().__init__(device)
|
||||
super().__init__(
|
||||
client,
|
||||
device,
|
||||
{
|
||||
Capability.SWITCH,
|
||||
Capability.FAN_SPEED,
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
},
|
||||
)
|
||||
self._attr_supported_features = self._determine_features()
|
||||
|
||||
def _determine_features(self):
|
||||
flags = FanEntityFeature.TURN_OFF | FanEntityFeature.TURN_ON
|
||||
|
||||
if self._device.get_capability(Capability.fan_speed):
|
||||
if self.supports_capability(Capability.FAN_SPEED):
|
||||
flags |= FanEntityFeature.SET_SPEED
|
||||
if self._device.get_capability(Capability.air_conditioner_fan_mode):
|
||||
if self.supports_capability(Capability.AIR_CONDITIONER_FAN_MODE):
|
||||
flags |= FanEntityFeature.PRESET_MODE
|
||||
|
||||
return flags
|
||||
|
||||
async def async_set_percentage(self, percentage: int) -> None:
|
||||
"""Set the speed percentage of the fan."""
|
||||
await self._async_set_percentage(percentage)
|
||||
|
||||
async def _async_set_percentage(self, percentage: int | None) -> None:
|
||||
if percentage is None:
|
||||
await self._device.switch_on(set_status=True)
|
||||
elif percentage == 0:
|
||||
await self._device.switch_off(set_status=True)
|
||||
if percentage == 0:
|
||||
await self.execute_device_command(Capability.SWITCH, Command.OFF)
|
||||
else:
|
||||
value = math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
|
||||
await self._device.set_fan_speed(value, set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.FAN_SPEED,
|
||||
Command.SET_FAN_SPEED,
|
||||
argument=value,
|
||||
)
|
||||
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set the preset_mode of the fan."""
|
||||
await self._device.set_fan_mode(preset_mode, set_status=True)
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
Command.SET_FAN_MODE,
|
||||
argument=preset_mode,
|
||||
)
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
@ -114,32 +100,30 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn the fan on."""
|
||||
if FanEntityFeature.SET_SPEED in self._attr_supported_features:
|
||||
# If speed is set in features then turn the fan on with the speed.
|
||||
await self._async_set_percentage(percentage)
|
||||
if (
|
||||
FanEntityFeature.SET_SPEED in self._attr_supported_features
|
||||
and percentage is not None
|
||||
):
|
||||
await self.async_set_percentage(percentage)
|
||||
else:
|
||||
# If speed is not valid then turn on the fan with the
|
||||
await self._device.switch_on(set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(Capability.SWITCH, Command.ON)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the fan off."""
|
||||
await self._device.switch_off(set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(Capability.SWITCH, Command.OFF)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if fan is on."""
|
||||
return self._device.status.switch
|
||||
return self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH)
|
||||
|
||||
@property
|
||||
def percentage(self) -> int | None:
|
||||
"""Return the current speed percentage."""
|
||||
return ranged_value_to_percentage(SPEED_RANGE, self._device.status.fan_speed)
|
||||
return ranged_value_to_percentage(
|
||||
SPEED_RANGE,
|
||||
self.get_attribute_value(Capability.FAN_SPEED, Attribute.FAN_SPEED),
|
||||
)
|
||||
|
||||
@property
|
||||
def preset_mode(self) -> str | None:
|
||||
@ -147,7 +131,9 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
|
||||
Requires FanEntityFeature.PRESET_MODE.
|
||||
"""
|
||||
return self._device.status.fan_mode
|
||||
return self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE, Attribute.FAN_MODE
|
||||
)
|
||||
|
||||
@property
|
||||
def preset_modes(self) -> list[str] | None:
|
||||
@ -155,4 +141,6 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
|
||||
Requires FanEntityFeature.PRESET_MODE.
|
||||
"""
|
||||
return self._device.status.supported_ac_fan_modes
|
||||
return self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE, Attribute.SUPPORTED_AC_FAN_MODES
|
||||
)
|
||||
|
@ -3,10 +3,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Capability
|
||||
from pysmartthings import Attribute, Capability, Command, SmartThings
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
@ -18,54 +17,38 @@ from homeassistant.components.light import (
|
||||
LightEntityFeature,
|
||||
brightness_supported,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
CAPABILITIES = (
|
||||
Capability.SWITCH_LEVEL,
|
||||
Capability.COLOR_CONTROL,
|
||||
Capability.COLOR_TEMPERATURE,
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add lights for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
[
|
||||
SmartThingsLight(device)
|
||||
for device in broker.devices.values()
|
||||
if broker.any_assigned(device.device_id, "light")
|
||||
],
|
||||
True,
|
||||
SmartThingsLight(entry_data.client, device)
|
||||
for device in entry_data.devices.values()
|
||||
if Capability.SWITCH in device.status[MAIN]
|
||||
and any(capability in device.status[MAIN] for capability in CAPABILITIES)
|
||||
)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
supported = [
|
||||
Capability.switch,
|
||||
Capability.switch_level,
|
||||
Capability.color_control,
|
||||
Capability.color_temperature,
|
||||
]
|
||||
# Must be able to be turned on/off.
|
||||
if Capability.switch not in capabilities:
|
||||
return None
|
||||
# Must have one of these
|
||||
light_capabilities = [
|
||||
Capability.color_control,
|
||||
Capability.color_temperature,
|
||||
Capability.switch_level,
|
||||
]
|
||||
if any(capability in capabilities for capability in light_capabilities):
|
||||
return supported
|
||||
return None
|
||||
|
||||
|
||||
def convert_scale(value, value_scale, target_scale, round_digits=4):
|
||||
def convert_scale(
|
||||
value: float, value_scale: int, target_scale: int, round_digits: int = 4
|
||||
) -> float:
|
||||
"""Convert a value to a different scale."""
|
||||
return round(value * target_scale / value_scale, round_digits)
|
||||
|
||||
@ -76,46 +59,41 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
_attr_supported_color_modes: set[ColorMode]
|
||||
|
||||
# SmartThings does not expose this attribute, instead it's
|
||||
# implemented within each device-type handler. This value is the
|
||||
# implemented within each device-type handler. This value is the
|
||||
# lowest kelvin found supported across 20+ handlers.
|
||||
_attr_min_color_temp_kelvin = 2000 # 500 mireds
|
||||
|
||||
# SmartThings does not expose this attribute, instead it's
|
||||
# implemented within each device-type handler. This value is the
|
||||
# implemented within each device-type handler. This value is the
|
||||
# highest kelvin found supported across 20+ handlers.
|
||||
_attr_max_color_temp_kelvin = 9000 # 111 mireds
|
||||
|
||||
def __init__(self, device):
|
||||
def __init__(self, client: SmartThings, device: FullDevice) -> None:
|
||||
"""Initialize a SmartThingsLight."""
|
||||
super().__init__(device)
|
||||
self._attr_supported_color_modes = self._determine_color_modes()
|
||||
self._attr_supported_features = self._determine_features()
|
||||
|
||||
def _determine_color_modes(self):
|
||||
"""Get features supported by the device."""
|
||||
super().__init__(
|
||||
client,
|
||||
device,
|
||||
{
|
||||
Capability.COLOR_CONTROL,
|
||||
Capability.COLOR_TEMPERATURE,
|
||||
Capability.SWITCH_LEVEL,
|
||||
Capability.SWITCH,
|
||||
},
|
||||
)
|
||||
color_modes = set()
|
||||
# Color Temperature
|
||||
if Capability.color_temperature in self._device.capabilities:
|
||||
if self.supports_capability(Capability.COLOR_TEMPERATURE):
|
||||
color_modes.add(ColorMode.COLOR_TEMP)
|
||||
# Color
|
||||
if Capability.color_control in self._device.capabilities:
|
||||
if self.supports_capability(Capability.COLOR_CONTROL):
|
||||
color_modes.add(ColorMode.HS)
|
||||
# Brightness
|
||||
if not color_modes and Capability.switch_level in self._device.capabilities:
|
||||
if not color_modes and self.supports_capability(Capability.SWITCH_LEVEL):
|
||||
color_modes.add(ColorMode.BRIGHTNESS)
|
||||
if not color_modes:
|
||||
color_modes.add(ColorMode.ONOFF)
|
||||
|
||||
return color_modes
|
||||
|
||||
def _determine_features(self) -> LightEntityFeature:
|
||||
"""Get features supported by the device."""
|
||||
self._attr_supported_color_modes = color_modes
|
||||
features = LightEntityFeature(0)
|
||||
# Transition
|
||||
if Capability.switch_level in self._device.capabilities:
|
||||
if self.supports_capability(Capability.SWITCH_LEVEL):
|
||||
features |= LightEntityFeature.TRANSITION
|
||||
|
||||
return features
|
||||
self._attr_supported_features = features
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on."""
|
||||
@ -136,11 +114,10 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
kwargs[ATTR_BRIGHTNESS], kwargs.get(ATTR_TRANSITION, 0)
|
||||
)
|
||||
else:
|
||||
await self._device.switch_on(set_status=True)
|
||||
|
||||
# State is set optimistically in the commands above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
Command.ON,
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the light off."""
|
||||
@ -148,27 +125,39 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
if ATTR_TRANSITION in kwargs:
|
||||
await self.async_set_level(0, int(kwargs[ATTR_TRANSITION]))
|
||||
else:
|
||||
await self._device.switch_off(set_status=True)
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
Command.OFF,
|
||||
)
|
||||
|
||||
# State is set optimistically in the commands above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
async def async_update(self) -> None:
|
||||
def _update_attr(self) -> None:
|
||||
"""Update entity attributes when the device status has changed."""
|
||||
# Brightness and transition
|
||||
if brightness_supported(self._attr_supported_color_modes):
|
||||
self._attr_brightness = int(
|
||||
convert_scale(self._device.status.level, 100, 255, 0)
|
||||
convert_scale(
|
||||
self.get_attribute_value(Capability.SWITCH_LEVEL, Attribute.LEVEL),
|
||||
100,
|
||||
255,
|
||||
0,
|
||||
)
|
||||
)
|
||||
# Color Temperature
|
||||
if ColorMode.COLOR_TEMP in self._attr_supported_color_modes:
|
||||
self._attr_color_temp_kelvin = self._device.status.color_temperature
|
||||
self._attr_color_temp_kelvin = self.get_attribute_value(
|
||||
Capability.COLOR_TEMPERATURE, Attribute.COLOR_TEMPERATURE
|
||||
)
|
||||
# Color
|
||||
if ColorMode.HS in self._attr_supported_color_modes:
|
||||
self._attr_hs_color = (
|
||||
convert_scale(self._device.status.hue, 100, 360),
|
||||
self._device.status.saturation,
|
||||
convert_scale(
|
||||
self.get_attribute_value(Capability.COLOR_CONTROL, Attribute.HUE),
|
||||
100,
|
||||
360,
|
||||
),
|
||||
self.get_attribute_value(
|
||||
Capability.COLOR_CONTROL, Attribute.SATURATION
|
||||
),
|
||||
)
|
||||
|
||||
async def async_set_color(self, hs_color):
|
||||
@ -176,14 +165,22 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
hue = convert_scale(float(hs_color[0]), 360, 100)
|
||||
hue = max(min(hue, 100.0), 0.0)
|
||||
saturation = max(min(float(hs_color[1]), 100.0), 0.0)
|
||||
await self._device.set_color(hue, saturation, set_status=True)
|
||||
await self.execute_device_command(
|
||||
Capability.COLOR_CONTROL,
|
||||
Command.SET_COLOR,
|
||||
argument={"hue": hue, "saturation": saturation},
|
||||
)
|
||||
|
||||
async def async_set_color_temp(self, value: int):
|
||||
"""Set the color temperature of the device."""
|
||||
kelvin = max(min(value, 30000), 1)
|
||||
await self._device.set_color_temperature(kelvin, set_status=True)
|
||||
await self.execute_device_command(
|
||||
Capability.COLOR_TEMPERATURE,
|
||||
Command.SET_COLOR_TEMPERATURE,
|
||||
argument=kelvin,
|
||||
)
|
||||
|
||||
async def async_set_level(self, brightness: int, transition: int):
|
||||
async def async_set_level(self, brightness: int, transition: int) -> None:
|
||||
"""Set the brightness of the light over transition."""
|
||||
level = int(convert_scale(brightness, 255, 100, 0))
|
||||
# Due to rounding, set level to 1 (one) so we don't inadvertently
|
||||
@ -191,7 +188,11 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
level = 1 if level == 0 and brightness > 0 else level
|
||||
level = max(min(level, 100), 0)
|
||||
duration = int(transition)
|
||||
await self._device.set_level(level, duration, set_status=True)
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH_LEVEL,
|
||||
Command.SET_LEVEL,
|
||||
argument=[level, duration],
|
||||
)
|
||||
|
||||
@property
|
||||
def color_mode(self) -> ColorMode:
|
||||
@ -208,4 +209,4 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if light is on."""
|
||||
return self._device.status.switch
|
||||
return self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH) == "on"
|
||||
|
@ -2,17 +2,16 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Attribute, Capability
|
||||
from pysmartthings import Attribute, Capability, Command
|
||||
|
||||
from homeassistant.components.lock import LockEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
ST_STATE_LOCKED = "locked"
|
||||
@ -28,48 +27,47 @@ ST_LOCK_ATTR_MAP = {
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add locks for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
SmartThingsLock(device)
|
||||
for device in broker.devices.values()
|
||||
if broker.any_assigned(device.device_id, "lock")
|
||||
SmartThingsLock(entry_data.client, device, {Capability.LOCK})
|
||||
for device in entry_data.devices.values()
|
||||
if Capability.LOCK in device.status[MAIN]
|
||||
)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
if Capability.lock in capabilities:
|
||||
return [Capability.lock]
|
||||
return None
|
||||
|
||||
|
||||
class SmartThingsLock(SmartThingsEntity, LockEntity):
|
||||
"""Define a SmartThings lock."""
|
||||
|
||||
async def async_lock(self, **kwargs: Any) -> None:
|
||||
"""Lock the device."""
|
||||
await self._device.lock(set_status=True)
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.LOCK,
|
||||
Command.LOCK,
|
||||
)
|
||||
|
||||
async def async_unlock(self, **kwargs: Any) -> None:
|
||||
"""Unlock the device."""
|
||||
await self._device.unlock(set_status=True)
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.LOCK,
|
||||
Command.UNLOCK,
|
||||
)
|
||||
|
||||
@property
|
||||
def is_locked(self) -> bool:
|
||||
"""Return true if lock is locked."""
|
||||
return self._device.status.lock == ST_STATE_LOCKED
|
||||
return (
|
||||
self.get_attribute_value(Capability.LOCK, Attribute.LOCK) == ST_STATE_LOCKED
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return device specific state attributes."""
|
||||
state_attrs = {}
|
||||
status = self._device.status.attributes[Attribute.lock]
|
||||
status = self._internal_state[Capability.LOCK][Attribute.LOCK]
|
||||
if status.value:
|
||||
state_attrs["lock_state"] = status.value
|
||||
if isinstance(status.data, dict):
|
||||
|
@ -1,10 +1,9 @@
|
||||
{
|
||||
"domain": "smartthings",
|
||||
"name": "SmartThings",
|
||||
"after_dependencies": ["cloud"],
|
||||
"codeowners": [],
|
||||
"codeowners": ["@joostlek"],
|
||||
"config_flow": true,
|
||||
"dependencies": ["webhook"],
|
||||
"dependencies": ["application_credentials"],
|
||||
"dhcp": [
|
||||
{
|
||||
"hostname": "st*",
|
||||
@ -29,6 +28,6 @@
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/smartthings",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["httpsig", "pysmartapp", "pysmartthings"],
|
||||
"requirements": ["pysmartapp==0.3.5", "pysmartthings==0.7.8"]
|
||||
"loggers": ["pysmartthings"],
|
||||
"requirements": ["pysmartthings==1.2.0"]
|
||||
}
|
||||
|
@ -2,39 +2,42 @@
|
||||
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Scene as STScene, SmartThings
|
||||
|
||||
from homeassistant.components.scene import Scene
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import SmartThingsConfigEntry
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add switches for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
async_add_entities(SmartThingsScene(scene) for scene in broker.scenes.values())
|
||||
"""Add lights for a config entry."""
|
||||
client = entry.runtime_data.client
|
||||
scenes = entry.runtime_data.scenes
|
||||
async_add_entities(SmartThingsScene(scene, client) for scene in scenes.values())
|
||||
|
||||
|
||||
class SmartThingsScene(Scene):
|
||||
"""Define a SmartThings scene."""
|
||||
|
||||
def __init__(self, scene):
|
||||
def __init__(self, scene: STScene, client: SmartThings) -> None:
|
||||
"""Init the scene class."""
|
||||
self.client = client
|
||||
self._scene = scene
|
||||
self._attr_name = scene.name
|
||||
self._attr_unique_id = scene.scene_id
|
||||
|
||||
async def async_activate(self, **kwargs: Any) -> None:
|
||||
"""Activate scene."""
|
||||
await self._scene.execute()
|
||||
await self.client.execute_scene(self._scene.scene_id)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Get attributes about the state."""
|
||||
return {
|
||||
"icon": self._scene.icon,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,545 +0,0 @@
|
||||
"""SmartApp functionality to receive cloud-push notifications."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import functools
|
||||
import logging
|
||||
import secrets
|
||||
from typing import Any
|
||||
from urllib.parse import urlparse
|
||||
from uuid import uuid4
|
||||
|
||||
from aiohttp import web
|
||||
from pysmartapp import Dispatcher, SmartAppManager
|
||||
from pysmartapp.const import SETTINGS_APP_ID
|
||||
from pysmartthings import (
|
||||
APP_TYPE_WEBHOOK,
|
||||
CAPABILITIES,
|
||||
CLASSIFICATION_AUTOMATION,
|
||||
App,
|
||||
AppEntity,
|
||||
AppOAuth,
|
||||
AppSettings,
|
||||
InstalledAppStatus,
|
||||
SmartThings,
|
||||
SourceType,
|
||||
Subscription,
|
||||
SubscriptionEntity,
|
||||
)
|
||||
|
||||
from homeassistant.components import cloud, webhook
|
||||
from homeassistant.config_entries import ConfigFlowResult
|
||||
from homeassistant.const import CONF_WEBHOOK_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_connect,
|
||||
async_dispatcher_send,
|
||||
)
|
||||
from homeassistant.helpers.network import NoURLAvailableError, get_url
|
||||
from homeassistant.helpers.storage import Store
|
||||
|
||||
from .const import (
|
||||
APP_NAME_PREFIX,
|
||||
APP_OAUTH_CLIENT_NAME,
|
||||
APP_OAUTH_SCOPES,
|
||||
CONF_CLOUDHOOK_URL,
|
||||
CONF_INSTALLED_APP_ID,
|
||||
CONF_INSTANCE_ID,
|
||||
CONF_REFRESH_TOKEN,
|
||||
DATA_BROKERS,
|
||||
DATA_MANAGER,
|
||||
DOMAIN,
|
||||
IGNORED_CAPABILITIES,
|
||||
SETTINGS_INSTANCE_ID,
|
||||
SIGNAL_SMARTAPP_PREFIX,
|
||||
STORAGE_KEY,
|
||||
STORAGE_VERSION,
|
||||
SUBSCRIPTION_WARNING_LIMIT,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def format_unique_id(app_id: str, location_id: str) -> str:
|
||||
"""Format the unique id for a config entry."""
|
||||
return f"{app_id}_{location_id}"
|
||||
|
||||
|
||||
async def find_app(hass: HomeAssistant, api: SmartThings) -> AppEntity | None:
|
||||
"""Find an existing SmartApp for this installation of hass."""
|
||||
apps = await api.apps()
|
||||
for app in [app for app in apps if app.app_name.startswith(APP_NAME_PREFIX)]:
|
||||
# Load settings to compare instance id
|
||||
settings = await app.settings()
|
||||
if (
|
||||
settings.settings.get(SETTINGS_INSTANCE_ID)
|
||||
== hass.data[DOMAIN][CONF_INSTANCE_ID]
|
||||
):
|
||||
return app
|
||||
return None
|
||||
|
||||
|
||||
async def validate_installed_app(api, installed_app_id: str):
|
||||
"""Ensure the specified installed SmartApp is valid and functioning.
|
||||
|
||||
Query the API for the installed SmartApp and validate that it is tied to
|
||||
the specified app_id and is in an authorized state.
|
||||
"""
|
||||
installed_app = await api.installed_app(installed_app_id)
|
||||
if installed_app.installed_app_status != InstalledAppStatus.AUTHORIZED:
|
||||
raise RuntimeWarning(
|
||||
f"Installed SmartApp instance '{installed_app.display_name}' "
|
||||
f"({installed_app.installed_app_id}) is not AUTHORIZED "
|
||||
f"but instead {installed_app.installed_app_status}"
|
||||
)
|
||||
return installed_app
|
||||
|
||||
|
||||
def validate_webhook_requirements(hass: HomeAssistant) -> bool:
|
||||
"""Ensure Home Assistant is setup properly to receive webhooks."""
|
||||
if cloud.async_active_subscription(hass):
|
||||
return True
|
||||
if hass.data[DOMAIN][CONF_CLOUDHOOK_URL] is not None:
|
||||
return True
|
||||
return get_webhook_url(hass).lower().startswith("https://")
|
||||
|
||||
|
||||
def get_webhook_url(hass: HomeAssistant) -> str:
|
||||
"""Get the URL of the webhook.
|
||||
|
||||
Return the cloudhook if available, otherwise local webhook.
|
||||
"""
|
||||
cloudhook_url = hass.data[DOMAIN][CONF_CLOUDHOOK_URL]
|
||||
if cloud.async_active_subscription(hass) and cloudhook_url is not None:
|
||||
return cloudhook_url
|
||||
return webhook.async_generate_url(hass, hass.data[DOMAIN][CONF_WEBHOOK_ID])
|
||||
|
||||
|
||||
def _get_app_template(hass: HomeAssistant):
|
||||
try:
|
||||
endpoint = f"at {get_url(hass, allow_cloud=False, prefer_external=True)}"
|
||||
except NoURLAvailableError:
|
||||
endpoint = ""
|
||||
|
||||
cloudhook_url = hass.data[DOMAIN][CONF_CLOUDHOOK_URL]
|
||||
if cloudhook_url is not None:
|
||||
endpoint = "via Nabu Casa"
|
||||
description = f"{hass.config.location_name} {endpoint}"
|
||||
|
||||
return {
|
||||
"app_name": APP_NAME_PREFIX + str(uuid4()),
|
||||
"display_name": "Home Assistant",
|
||||
"description": description,
|
||||
"webhook_target_url": get_webhook_url(hass),
|
||||
"app_type": APP_TYPE_WEBHOOK,
|
||||
"single_instance": True,
|
||||
"classifications": [CLASSIFICATION_AUTOMATION],
|
||||
}
|
||||
|
||||
|
||||
async def create_app(hass: HomeAssistant, api):
|
||||
"""Create a SmartApp for this instance of hass."""
|
||||
# Create app from template attributes
|
||||
template = _get_app_template(hass)
|
||||
app = App()
|
||||
for key, value in template.items():
|
||||
setattr(app, key, value)
|
||||
app, client = await api.create_app(app)
|
||||
_LOGGER.debug("Created SmartApp '%s' (%s)", app.app_name, app.app_id)
|
||||
|
||||
# Set unique hass id in settings
|
||||
settings = AppSettings(app.app_id)
|
||||
settings.settings[SETTINGS_APP_ID] = app.app_id
|
||||
settings.settings[SETTINGS_INSTANCE_ID] = hass.data[DOMAIN][CONF_INSTANCE_ID]
|
||||
await api.update_app_settings(settings)
|
||||
_LOGGER.debug(
|
||||
"Updated App Settings for SmartApp '%s' (%s)", app.app_name, app.app_id
|
||||
)
|
||||
|
||||
# Set oauth scopes
|
||||
oauth = AppOAuth(app.app_id)
|
||||
oauth.client_name = APP_OAUTH_CLIENT_NAME
|
||||
oauth.scope.extend(APP_OAUTH_SCOPES)
|
||||
await api.update_app_oauth(oauth)
|
||||
_LOGGER.debug("Updated App OAuth for SmartApp '%s' (%s)", app.app_name, app.app_id)
|
||||
return app, client
|
||||
|
||||
|
||||
async def update_app(hass: HomeAssistant, app):
|
||||
"""Ensure the SmartApp is up-to-date and update if necessary."""
|
||||
template = _get_app_template(hass)
|
||||
template.pop("app_name") # don't update this
|
||||
update_required = False
|
||||
for key, value in template.items():
|
||||
if getattr(app, key) != value:
|
||||
update_required = True
|
||||
setattr(app, key, value)
|
||||
if update_required:
|
||||
await app.save()
|
||||
_LOGGER.debug(
|
||||
"SmartApp '%s' (%s) updated with latest settings", app.app_name, app.app_id
|
||||
)
|
||||
|
||||
|
||||
def setup_smartapp(hass, app):
|
||||
"""Configure an individual SmartApp in hass.
|
||||
|
||||
Register the SmartApp with the SmartAppManager so that hass will service
|
||||
lifecycle events (install, event, etc...). A unique SmartApp is created
|
||||
for each SmartThings account that is configured in hass.
|
||||
"""
|
||||
manager = hass.data[DOMAIN][DATA_MANAGER]
|
||||
if smartapp := manager.smartapps.get(app.app_id):
|
||||
# already setup
|
||||
return smartapp
|
||||
smartapp = manager.register(app.app_id, app.webhook_public_key)
|
||||
smartapp.name = app.display_name
|
||||
smartapp.description = app.description
|
||||
smartapp.permissions.extend(APP_OAUTH_SCOPES)
|
||||
return smartapp
|
||||
|
||||
|
||||
async def setup_smartapp_endpoint(hass: HomeAssistant, fresh_install: bool):
|
||||
"""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.
|
||||
"""
|
||||
if hass.data.get(DOMAIN):
|
||||
# already setup
|
||||
if not fresh_install:
|
||||
return
|
||||
|
||||
# We're doing a fresh install, clean up
|
||||
await unload_smartapp_endpoint(hass)
|
||||
|
||||
# Get/create config to store a unique id for this hass instance.
|
||||
store = Store[dict[str, Any]](hass, STORAGE_VERSION, STORAGE_KEY)
|
||||
|
||||
if fresh_install or not (config := await store.async_load()):
|
||||
# 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 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),
|
||||
}
|
||||
_LOGGER.debug(
|
||||
"Setup endpoint for %s",
|
||||
cloudhook_url
|
||||
if cloudhook_url
|
||||
else webhook.async_generate_url(hass, config[CONF_WEBHOOK_ID]),
|
||||
)
|
||||
|
||||
|
||||
async def unload_smartapp_endpoint(hass: HomeAssistant):
|
||||
"""Tear down the component configuration."""
|
||||
if DOMAIN not in hass.data:
|
||||
return
|
||||
# Remove the cloudhook if it was created
|
||||
cloudhook_url = hass.data[DOMAIN][CONF_CLOUDHOOK_URL]
|
||||
if cloudhook_url and cloud.async_is_logged_in(hass):
|
||||
await cloud.async_delete_cloudhook(hass, hass.data[DOMAIN][CONF_WEBHOOK_ID])
|
||||
# Remove cloudhook from storage
|
||||
store = Store[dict[str, Any]](hass, STORAGE_VERSION, STORAGE_KEY)
|
||||
await store.async_save(
|
||||
{
|
||||
CONF_INSTANCE_ID: hass.data[DOMAIN][CONF_INSTANCE_ID],
|
||||
CONF_WEBHOOK_ID: hass.data[DOMAIN][CONF_WEBHOOK_ID],
|
||||
CONF_CLOUDHOOK_URL: None,
|
||||
}
|
||||
)
|
||||
_LOGGER.debug("Cloudhook '%s' was removed", cloudhook_url)
|
||||
# Remove the webhook
|
||||
webhook.async_unregister(hass, hass.data[DOMAIN][CONF_WEBHOOK_ID])
|
||||
# Disconnect all brokers
|
||||
for broker in hass.data[DOMAIN][DATA_BROKERS].values():
|
||||
broker.disconnect()
|
||||
# Remove all handlers from manager
|
||||
hass.data[DOMAIN][DATA_MANAGER].dispatcher.disconnect_all()
|
||||
# Remove the component data
|
||||
hass.data.pop(DOMAIN)
|
||||
|
||||
|
||||
async def smartapp_sync_subscriptions(
|
||||
hass: HomeAssistant,
|
||||
auth_token: str,
|
||||
location_id: str,
|
||||
installed_app_id: str,
|
||||
devices,
|
||||
):
|
||||
"""Synchronize subscriptions of an installed up."""
|
||||
api = SmartThings(async_get_clientsession(hass), auth_token)
|
||||
tasks = []
|
||||
|
||||
async def create_subscription(target: str):
|
||||
sub = Subscription()
|
||||
sub.installed_app_id = installed_app_id
|
||||
sub.location_id = location_id
|
||||
sub.source_type = SourceType.CAPABILITY
|
||||
sub.capability = target
|
||||
try:
|
||||
await api.create_subscription(sub)
|
||||
_LOGGER.debug(
|
||||
"Created subscription for '%s' under app '%s'", target, installed_app_id
|
||||
)
|
||||
except Exception as error: # noqa: BLE001
|
||||
_LOGGER.error(
|
||||
"Failed to create subscription for '%s' under app '%s': %s",
|
||||
target,
|
||||
installed_app_id,
|
||||
error,
|
||||
)
|
||||
|
||||
async def delete_subscription(sub: SubscriptionEntity):
|
||||
try:
|
||||
await api.delete_subscription(installed_app_id, sub.subscription_id)
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"Removed subscription for '%s' under app '%s' because it was no"
|
||||
" longer needed"
|
||||
),
|
||||
sub.capability,
|
||||
installed_app_id,
|
||||
)
|
||||
except Exception as error: # noqa: BLE001
|
||||
_LOGGER.error(
|
||||
"Failed to remove subscription for '%s' under app '%s': %s",
|
||||
sub.capability,
|
||||
installed_app_id,
|
||||
error,
|
||||
)
|
||||
|
||||
# Build set of capabilities and prune unsupported ones
|
||||
capabilities = set()
|
||||
for device in devices:
|
||||
capabilities.update(device.capabilities)
|
||||
# Remove items not defined in the library
|
||||
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
|
||||
subscriptions = await api.subscriptions(installed_app_id)
|
||||
for subscription in subscriptions:
|
||||
if subscription.capability in capabilities:
|
||||
capabilities.remove(subscription.capability)
|
||||
else:
|
||||
# Delete the subscription
|
||||
tasks.append(delete_subscription(subscription))
|
||||
|
||||
# Remaining capabilities need subscriptions created
|
||||
tasks.extend([create_subscription(c) for c in capabilities])
|
||||
|
||||
if tasks:
|
||||
await asyncio.gather(*tasks)
|
||||
else:
|
||||
_LOGGER.debug("Subscriptions for app '%s' are up-to-date", installed_app_id)
|
||||
|
||||
|
||||
async def _find_and_continue_flow(
|
||||
hass: HomeAssistant,
|
||||
app_id: str,
|
||||
location_id: str,
|
||||
installed_app_id: str,
|
||||
refresh_token: str,
|
||||
):
|
||||
"""Continue a config flow if one is in progress for the specific installed app."""
|
||||
unique_id = format_unique_id(app_id, location_id)
|
||||
flow = next(
|
||||
(
|
||||
flow
|
||||
for flow in hass.config_entries.flow.async_progress_by_handler(DOMAIN)
|
||||
if flow["context"].get("unique_id") == unique_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if flow is not None:
|
||||
await _continue_flow(hass, app_id, installed_app_id, refresh_token, flow)
|
||||
|
||||
|
||||
async def _continue_flow(
|
||||
hass: HomeAssistant,
|
||||
app_id: str,
|
||||
installed_app_id: str,
|
||||
refresh_token: str,
|
||||
flow: ConfigFlowResult,
|
||||
) -> None:
|
||||
await hass.config_entries.flow.async_configure(
|
||||
flow["flow_id"],
|
||||
{
|
||||
CONF_INSTALLED_APP_ID: installed_app_id,
|
||||
CONF_REFRESH_TOKEN: refresh_token,
|
||||
},
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Continued config flow '%s' for SmartApp '%s' under parent app '%s'",
|
||||
flow["flow_id"],
|
||||
installed_app_id,
|
||||
app_id,
|
||||
)
|
||||
|
||||
|
||||
async def smartapp_install(hass: HomeAssistant, req, resp, app):
|
||||
"""Handle a SmartApp installation and continue the config flow."""
|
||||
await _find_and_continue_flow(
|
||||
hass, app.app_id, req.location_id, req.installed_app_id, req.refresh_token
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Installed SmartApp '%s' under parent app '%s'",
|
||||
req.installed_app_id,
|
||||
app.app_id,
|
||||
)
|
||||
|
||||
|
||||
async def smartapp_update(hass: HomeAssistant, req, resp, app):
|
||||
"""Handle a SmartApp update and either update the entry or continue the flow."""
|
||||
unique_id = format_unique_id(app.app_id, req.location_id)
|
||||
flow = next(
|
||||
(
|
||||
flow
|
||||
for flow in hass.config_entries.flow.async_progress_by_handler(DOMAIN)
|
||||
if flow["context"].get("unique_id") == unique_id
|
||||
and flow["step_id"] == "authorize"
|
||||
),
|
||||
None,
|
||||
)
|
||||
if flow is not None:
|
||||
await _continue_flow(
|
||||
hass, app.app_id, req.installed_app_id, req.refresh_token, flow
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Continued reauth flow '%s' for SmartApp '%s' under parent app '%s'",
|
||||
flow["flow_id"],
|
||||
req.installed_app_id,
|
||||
app.app_id,
|
||||
)
|
||||
return
|
||||
entry = next(
|
||||
(
|
||||
entry
|
||||
for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.data.get(CONF_INSTALLED_APP_ID) == req.installed_app_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if entry:
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, data={**entry.data, CONF_REFRESH_TOKEN: req.refresh_token}
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Updated config entry '%s' for SmartApp '%s' under parent app '%s'",
|
||||
entry.entry_id,
|
||||
req.installed_app_id,
|
||||
app.app_id,
|
||||
)
|
||||
|
||||
await _find_and_continue_flow(
|
||||
hass, app.app_id, req.location_id, req.installed_app_id, req.refresh_token
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Updated SmartApp '%s' under parent app '%s'", req.installed_app_id, app.app_id
|
||||
)
|
||||
|
||||
|
||||
async def smartapp_uninstall(hass: HomeAssistant, req, resp, app):
|
||||
"""Handle when a SmartApp is removed from a location by the user.
|
||||
|
||||
Find and delete the config entry representing the integration.
|
||||
"""
|
||||
entry = next(
|
||||
(
|
||||
entry
|
||||
for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.data.get(CONF_INSTALLED_APP_ID) == req.installed_app_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
if entry:
|
||||
# Add as job not needed because the current coroutine was invoked
|
||||
# from the dispatcher and is not being awaited.
|
||||
await hass.config_entries.async_remove(entry.entry_id)
|
||||
|
||||
_LOGGER.debug(
|
||||
"Uninstalled SmartApp '%s' under parent app '%s'",
|
||||
req.installed_app_id,
|
||||
app.app_id,
|
||||
)
|
||||
|
||||
|
||||
async def smartapp_webhook(hass: HomeAssistant, webhook_id: str, request):
|
||||
"""Handle a smartapp lifecycle event callback from SmartThings.
|
||||
|
||||
Requests from SmartThings are digitally signed and the SmartAppManager
|
||||
validates the signature for authenticity.
|
||||
"""
|
||||
manager = hass.data[DOMAIN][DATA_MANAGER]
|
||||
data = await request.json()
|
||||
result = await manager.handle_request(data, request.headers)
|
||||
return web.json_response(result)
|
@ -1,43 +1,29 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "Confirm Callback URL",
|
||||
"description": "SmartThings will be configured to send push updates to Home Assistant at:\n> {webhook_url}\n\nIf this is not correct, please update your configuration, restart Home Assistant, and try again."
|
||||
"pick_implementation": {
|
||||
"title": "[%key:common::config_flow::title::oauth2_pick_implementation%]"
|
||||
},
|
||||
"pat": {
|
||||
"title": "Enter Personal Access Token",
|
||||
"description": "Please enter a SmartThings [Personal Access Token]({token_url}) that has been created per the [instructions]({component_url}). This will be used to create the Home Assistant integration within your SmartThings account.\n\n**Please note that all Personal Access Tokens created after 30 December 2024 are only valid for 24 hours, after which the integration will stop working. We are working on a fix.**",
|
||||
"data": {
|
||||
"access_token": "[%key:common::config_flow::data::access_token%]"
|
||||
}
|
||||
},
|
||||
"select_location": {
|
||||
"title": "Select Location",
|
||||
"description": "Please select the SmartThings Location you wish to add to Home Assistant. We will then open a new window and ask you to login and authorize installation of the Home Assistant integration into the selected location.",
|
||||
"data": { "location_id": "[%key:common::config_flow::data::location%]" }
|
||||
},
|
||||
"authorize": { "title": "Authorize Home Assistant" },
|
||||
"reauth_confirm": {
|
||||
"title": "Reauthorize Home Assistant",
|
||||
"description": "You are about to reauthorize Home Assistant with SmartThings. This will require you to log in and authorize the integration again."
|
||||
},
|
||||
"update_confirm": {
|
||||
"title": "Finish reauthentication",
|
||||
"description": "You have almost successfully reauthorized Home Assistant with SmartThings. Please press the button down below to finish the process."
|
||||
"title": "[%key:common::config_flow::title::reauth%]",
|
||||
"description": "The SmartThings integration needs to re-authenticate your account"
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"invalid_webhook_url": "Home Assistant is not configured correctly to receive updates from SmartThings. The webhook URL is invalid:\n> {webhook_url}\n\nPlease update your configuration per the [instructions]({component_url}), restart Home Assistant, and try again.",
|
||||
"no_available_locations": "There are no available SmartThings Locations to set up in Home Assistant.",
|
||||
"reauth_successful": "Home Assistant has been successfully reauthorized with SmartThings."
|
||||
},
|
||||
"error": {
|
||||
"token_invalid_format": "The token must be in the UID/GUID format",
|
||||
"token_unauthorized": "The token is invalid or no longer authorized.",
|
||||
"token_forbidden": "The token does not have the required OAuth scopes.",
|
||||
"app_setup_error": "Unable to set up the SmartApp. Please try again.",
|
||||
"webhook_error": "SmartThings could not validate the webhook URL. Please ensure the webhook URL is reachable from the internet and try again."
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
|
||||
},
|
||||
"abort": {
|
||||
"authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]",
|
||||
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
|
||||
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
|
||||
"oauth_error": "[%key:common::config_flow::abort::oauth2_error%]",
|
||||
"oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]",
|
||||
"oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]",
|
||||
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"reauth_account_mismatch": "Authenticated account does not match the account to be reauthenticated. Please log in with the correct account and pick the right location.",
|
||||
"reauth_location_mismatch": "Authenticated location does not match the location to be reauthenticated. Please log in with the correct account and pick the right location."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,60 +2,67 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Capability
|
||||
from pysmartthings import Attribute, Capability, Command
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DATA_BROKERS, DOMAIN
|
||||
from . import SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
CAPABILITIES = (
|
||||
Capability.SWITCH_LEVEL,
|
||||
Capability.COLOR_CONTROL,
|
||||
Capability.COLOR_TEMPERATURE,
|
||||
Capability.FAN_SPEED,
|
||||
)
|
||||
|
||||
AC_CAPABILITIES = (
|
||||
Capability.AIR_CONDITIONER_MODE,
|
||||
Capability.AIR_CONDITIONER_FAN_MODE,
|
||||
Capability.TEMPERATURE_MEASUREMENT,
|
||||
Capability.THERMOSTAT_COOLING_SETPOINT,
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entry: SmartThingsConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add switches for a config entry."""
|
||||
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
SmartThingsSwitch(device)
|
||||
for device in broker.devices.values()
|
||||
if broker.any_assigned(device.device_id, "switch")
|
||||
SmartThingsSwitch(entry_data.client, device, {Capability.SWITCH})
|
||||
for device in entry_data.devices.values()
|
||||
if Capability.SWITCH in device.status[MAIN]
|
||||
and not any(capability in device.status[MAIN] for capability in CAPABILITIES)
|
||||
and not all(capability in device.status[MAIN] for capability in AC_CAPABILITIES)
|
||||
)
|
||||
|
||||
|
||||
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
||||
"""Return all capabilities supported if minimum required are present."""
|
||||
# Must be able to be turned on/off.
|
||||
if Capability.switch in capabilities:
|
||||
return [Capability.switch, Capability.energy_meter, Capability.power_meter]
|
||||
return None
|
||||
|
||||
|
||||
class SmartThingsSwitch(SmartThingsEntity, SwitchEntity):
|
||||
"""Define a SmartThings switch."""
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
await self._device.switch_off(set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
Command.OFF,
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
await self._device.switch_on(set_status=True)
|
||||
# State is set optimistically in the command above, therefore update
|
||||
# the entity state ahead of receiving the confirming push updates
|
||||
self.async_write_ha_state()
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
Command.ON,
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if light is on."""
|
||||
return self._device.status.switch
|
||||
return self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH) == "on"
|
||||
|
@ -28,6 +28,7 @@ APPLICATION_CREDENTIALS = [
|
||||
"onedrive",
|
||||
"point",
|
||||
"senz",
|
||||
"smartthings",
|
||||
"spotify",
|
||||
"tesla_fleet",
|
||||
"twitch",
|
||||
|
5
requirements_all.txt
generated
5
requirements_all.txt
generated
@ -2310,10 +2310,7 @@ pysma==0.7.5
|
||||
pysmappee==0.2.29
|
||||
|
||||
# homeassistant.components.smartthings
|
||||
pysmartapp==0.3.5
|
||||
|
||||
# homeassistant.components.smartthings
|
||||
pysmartthings==0.7.8
|
||||
pysmartthings==1.2.0
|
||||
|
||||
# homeassistant.components.smarty
|
||||
pysmarty2==0.10.2
|
||||
|
5
requirements_test_all.txt
generated
5
requirements_test_all.txt
generated
@ -1882,10 +1882,7 @@ pysma==0.7.5
|
||||
pysmappee==0.2.29
|
||||
|
||||
# homeassistant.components.smartthings
|
||||
pysmartapp==0.3.5
|
||||
|
||||
# homeassistant.components.smartthings
|
||||
pysmartthings==0.7.8
|
||||
pysmartthings==1.2.0
|
||||
|
||||
# homeassistant.components.smarty
|
||||
pysmarty2==0.10.2
|
||||
|
@ -1 +1,75 @@
|
||||
"""Tests for the SmartThings component."""
|
||||
"""Tests for the SmartThings integration."""
|
||||
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from pysmartthings.models import Attribute, Capability, DeviceEvent
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.smartthings.const import MAIN
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
|
||||
"""Fixture for setting up the component."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
def snapshot_smartthings_entities(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
platform: Platform,
|
||||
) -> None:
|
||||
"""Snapshot SmartThings entities."""
|
||||
entities = hass.states.async_all(platform)
|
||||
for entity_state in entities:
|
||||
entity_entry = entity_registry.async_get(entity_state.entity_id)
|
||||
assert entity_entry == snapshot(name=f"{entity_entry.entity_id}-entry")
|
||||
assert entity_state == snapshot(name=f"{entity_entry.entity_id}-state")
|
||||
|
||||
|
||||
def set_attribute_value(
|
||||
mock: AsyncMock,
|
||||
capability: Capability,
|
||||
attribute: Attribute,
|
||||
value: Any,
|
||||
component: str = MAIN,
|
||||
) -> None:
|
||||
"""Set the value of an attribute."""
|
||||
mock.get_device_status.return_value[component][capability][attribute].value = value
|
||||
|
||||
|
||||
async def trigger_update(
|
||||
hass: HomeAssistant,
|
||||
mock: AsyncMock,
|
||||
device_id: str,
|
||||
capability: Capability,
|
||||
attribute: Attribute,
|
||||
value: str | float | dict[str, Any] | list[Any] | None,
|
||||
data: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Trigger an update."""
|
||||
for call in mock.add_device_event_listener.call_args_list:
|
||||
if call[0][0] == device_id and call[0][2] == capability:
|
||||
call[0][3](
|
||||
DeviceEvent(
|
||||
"abc",
|
||||
"abc",
|
||||
"abc",
|
||||
device_id,
|
||||
MAIN,
|
||||
capability,
|
||||
attribute,
|
||||
value,
|
||||
data,
|
||||
)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -1,358 +1,178 @@
|
||||
"""Test configuration and mocks for the SmartThings component."""
|
||||
|
||||
import secrets
|
||||
from typing import Any
|
||||
from unittest.mock import Mock, patch
|
||||
from uuid import uuid4
|
||||
from collections.abc import Generator
|
||||
import time
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from pysmartthings import (
|
||||
CLASSIFICATION_AUTOMATION,
|
||||
AppEntity,
|
||||
AppOAuthClient,
|
||||
AppSettings,
|
||||
DeviceEntity,
|
||||
from pysmartthings.models import (
|
||||
DeviceResponse,
|
||||
DeviceStatus,
|
||||
InstalledApp,
|
||||
InstalledAppStatus,
|
||||
InstalledAppType,
|
||||
Location,
|
||||
SceneEntity,
|
||||
SmartThings,
|
||||
Subscription,
|
||||
LocationResponse,
|
||||
SceneResponse,
|
||||
)
|
||||
from pysmartthings.api import Api
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import webhook
|
||||
from homeassistant.components.smartthings import DeviceBroker
|
||||
from homeassistant.components.application_credentials import (
|
||||
ClientCredential,
|
||||
async_import_client_credential,
|
||||
)
|
||||
from homeassistant.components.smartthings import CONF_INSTALLED_APP_ID
|
||||
from homeassistant.components.smartthings.const import (
|
||||
APP_NAME_PREFIX,
|
||||
CONF_APP_ID,
|
||||
CONF_INSTALLED_APP_ID,
|
||||
CONF_INSTANCE_ID,
|
||||
CONF_LOCATION_ID,
|
||||
CONF_REFRESH_TOKEN,
|
||||
DATA_BROKERS,
|
||||
DOMAIN,
|
||||
SETTINGS_INSTANCE_ID,
|
||||
STORAGE_KEY,
|
||||
STORAGE_VERSION,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
CONF_ACCESS_TOKEN,
|
||||
CONF_CLIENT_ID,
|
||||
CONF_CLIENT_SECRET,
|
||||
CONF_WEBHOOK_ID,
|
||||
SCOPES,
|
||||
)
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_CLIENT_ID, CONF_CLIENT_SECRET
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core_config import async_process_ha_core_config
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.light.conftest import mock_light_profiles # noqa: F401
|
||||
|
||||
COMPONENT_PREFIX = "homeassistant.components.smartthings."
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
||||
|
||||
async def setup_platform(
|
||||
hass: HomeAssistant, platform: str, *, devices=None, scenes=None
|
||||
):
|
||||
"""Set up the SmartThings platform and prerequisites."""
|
||||
hass.config.components.add(DOMAIN)
|
||||
config_entry = MockConfigEntry(
|
||||
version=2,
|
||||
domain=DOMAIN,
|
||||
title="Test",
|
||||
data={CONF_INSTALLED_APP_ID: str(uuid4())},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
broker = DeviceBroker(
|
||||
hass, config_entry, Mock(), Mock(), devices or [], scenes or []
|
||||
)
|
||||
@pytest.fixture
|
||||
def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
"""Override async_setup_entry."""
|
||||
with patch(
|
||||
"homeassistant.components.smartthings.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
yield mock_setup_entry
|
||||
|
||||
hass.data[DOMAIN] = {DATA_BROKERS: {config_entry.entry_id: broker}}
|
||||
config_entry.mock_state(hass, ConfigEntryState.LOADED)
|
||||
await hass.config_entries.async_forward_entry_setups(config_entry, [platform])
|
||||
await hass.async_block_till_done()
|
||||
return config_entry
|
||||
|
||||
@pytest.fixture(name="expires_at")
|
||||
def mock_expires_at() -> int:
|
||||
"""Fixture to set the oauth token expiration time."""
|
||||
return time.time() + 3600
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
async def setup_component(
|
||||
hass: HomeAssistant, config_file: dict[str, str], hass_storage: dict[str, Any]
|
||||
) -> None:
|
||||
"""Load the SmartThing component."""
|
||||
hass_storage[STORAGE_KEY] = {"data": config_file, "version": STORAGE_VERSION}
|
||||
await async_process_ha_core_config(
|
||||
async def setup_credentials(hass: HomeAssistant) -> None:
|
||||
"""Fixture to setup credentials."""
|
||||
assert await async_setup_component(hass, "application_credentials", {})
|
||||
await async_import_client_credential(
|
||||
hass,
|
||||
{"external_url": "https://test.local"},
|
||||
)
|
||||
await async_setup_component(hass, "smartthings", {})
|
||||
|
||||
|
||||
def _create_location() -> Mock:
|
||||
loc = Mock(Location)
|
||||
loc.name = "Test Location"
|
||||
loc.location_id = str(uuid4())
|
||||
return loc
|
||||
|
||||
|
||||
@pytest.fixture(name="location")
|
||||
def location_fixture() -> Mock:
|
||||
"""Fixture for a single location."""
|
||||
return _create_location()
|
||||
|
||||
|
||||
@pytest.fixture(name="locations")
|
||||
def locations_fixture(location: Mock) -> list[Mock]:
|
||||
"""Fixture for 2 locations."""
|
||||
return [location, _create_location()]
|
||||
|
||||
|
||||
@pytest.fixture(name="app")
|
||||
async def app_fixture(hass: HomeAssistant, config_file: dict[str, str]) -> Mock:
|
||||
"""Fixture for a single app."""
|
||||
app = Mock(AppEntity)
|
||||
app.app_name = APP_NAME_PREFIX + str(uuid4())
|
||||
app.app_id = str(uuid4())
|
||||
app.app_type = "WEBHOOK_SMART_APP"
|
||||
app.classifications = [CLASSIFICATION_AUTOMATION]
|
||||
app.display_name = "Home Assistant"
|
||||
app.description = f"{hass.config.location_name} at https://test.local"
|
||||
app.single_instance = True
|
||||
app.webhook_target_url = webhook.async_generate_url(
|
||||
hass, hass.data[DOMAIN][CONF_WEBHOOK_ID]
|
||||
DOMAIN,
|
||||
ClientCredential("CLIENT_ID", "CLIENT_SECRET"),
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
settings = Mock(AppSettings)
|
||||
settings.app_id = app.app_id
|
||||
settings.settings = {SETTINGS_INSTANCE_ID: config_file[CONF_INSTANCE_ID]}
|
||||
app.settings.return_value = settings
|
||||
return app
|
||||
|
||||
|
||||
@pytest.fixture(name="app_oauth_client")
|
||||
def app_oauth_client_fixture() -> Mock:
|
||||
"""Fixture for a single app's oauth."""
|
||||
client = Mock(AppOAuthClient)
|
||||
client.client_id = str(uuid4())
|
||||
client.client_secret = str(uuid4())
|
||||
return client
|
||||
|
||||
|
||||
@pytest.fixture(name="app_settings")
|
||||
def app_settings_fixture(app, config_file):
|
||||
"""Fixture for an app settings."""
|
||||
settings = Mock(AppSettings)
|
||||
settings.app_id = app.app_id
|
||||
settings.settings = {SETTINGS_INSTANCE_ID: config_file[CONF_INSTANCE_ID]}
|
||||
return settings
|
||||
|
||||
|
||||
def _create_installed_app(location_id: str, app_id: str) -> Mock:
|
||||
item = Mock(InstalledApp)
|
||||
item.installed_app_id = str(uuid4())
|
||||
item.installed_app_status = InstalledAppStatus.AUTHORIZED
|
||||
item.installed_app_type = InstalledAppType.WEBHOOK_SMART_APP
|
||||
item.app_id = app_id
|
||||
item.location_id = location_id
|
||||
return item
|
||||
|
||||
|
||||
@pytest.fixture(name="installed_app")
|
||||
def installed_app_fixture(location: Mock, app: Mock) -> Mock:
|
||||
"""Fixture for a single installed app."""
|
||||
return _create_installed_app(location.location_id, app.app_id)
|
||||
|
||||
|
||||
@pytest.fixture(name="installed_apps")
|
||||
def installed_apps_fixture(installed_app, locations, app):
|
||||
"""Fixture for 2 installed apps."""
|
||||
return [installed_app, _create_installed_app(locations[1].location_id, app.app_id)]
|
||||
|
||||
|
||||
@pytest.fixture(name="config_file")
|
||||
def config_file_fixture() -> dict[str, str]:
|
||||
"""Fixture representing the local config file contents."""
|
||||
return {CONF_INSTANCE_ID: str(uuid4()), CONF_WEBHOOK_ID: secrets.token_hex()}
|
||||
|
||||
|
||||
@pytest.fixture(name="smartthings_mock")
|
||||
def smartthings_mock_fixture(locations):
|
||||
"""Fixture to mock smartthings API calls."""
|
||||
|
||||
async def _location(location_id):
|
||||
return next(
|
||||
location for location in locations if location.location_id == location_id
|
||||
)
|
||||
|
||||
smartthings_mock = Mock(SmartThings)
|
||||
smartthings_mock.location.side_effect = _location
|
||||
mock = Mock(return_value=smartthings_mock)
|
||||
@pytest.fixture
|
||||
def mock_smartthings() -> Generator[AsyncMock]:
|
||||
"""Mock a SmartThings client."""
|
||||
with (
|
||||
patch(COMPONENT_PREFIX + "SmartThings", new=mock),
|
||||
patch(COMPONENT_PREFIX + "config_flow.SmartThings", new=mock),
|
||||
patch(COMPONENT_PREFIX + "smartapp.SmartThings", new=mock),
|
||||
patch(
|
||||
"homeassistant.components.smartthings.SmartThings",
|
||||
autospec=True,
|
||||
) as mock_client,
|
||||
patch(
|
||||
"homeassistant.components.smartthings.config_flow.SmartThings",
|
||||
new=mock_client,
|
||||
),
|
||||
):
|
||||
yield smartthings_mock
|
||||
client = mock_client.return_value
|
||||
client.get_scenes.return_value = SceneResponse.from_json(
|
||||
load_fixture("scenes.json", DOMAIN)
|
||||
).items
|
||||
client.get_locations.return_value = LocationResponse.from_json(
|
||||
load_fixture("locations.json", DOMAIN)
|
||||
).items
|
||||
yield client
|
||||
|
||||
|
||||
@pytest.fixture(name="device")
|
||||
def device_fixture(location):
|
||||
"""Fixture representing devices loaded."""
|
||||
item = Mock(DeviceEntity)
|
||||
item.device_id = "743de49f-036f-4e9c-839a-2f89d57607db"
|
||||
item.name = "GE In-Wall Smart Dimmer"
|
||||
item.label = "Front Porch Lights"
|
||||
item.location_id = location.location_id
|
||||
item.capabilities = [
|
||||
"switch",
|
||||
"switchLevel",
|
||||
"refresh",
|
||||
"indicator",
|
||||
"sensor",
|
||||
"actuator",
|
||||
"healthCheck",
|
||||
"light",
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
"da_ac_rac_000001",
|
||||
"da_ac_rac_01001",
|
||||
"multipurpose_sensor",
|
||||
"contact_sensor",
|
||||
"base_electric_meter",
|
||||
"smart_plug",
|
||||
"vd_stv_2017_k",
|
||||
"c2c_arlo_pro_3_switch",
|
||||
"yale_push_button_deadbolt_lock",
|
||||
"ge_in_wall_smart_dimmer",
|
||||
"centralite",
|
||||
"da_ref_normal_000001",
|
||||
"vd_network_audio_002s",
|
||||
"iphone",
|
||||
"da_wm_dw_000001",
|
||||
"da_wm_wd_000001",
|
||||
"da_wm_wm_000001",
|
||||
"da_rvc_normal_000001",
|
||||
"da_ks_microwave_0101x",
|
||||
"hue_color_temperature_bulb",
|
||||
"hue_rgbw_color_bulb",
|
||||
"c2c_shade",
|
||||
"sonos_player",
|
||||
"aeotec_home_energy_meter_gen5",
|
||||
"virtual_water_sensor",
|
||||
"virtual_thermostat",
|
||||
"virtual_valve",
|
||||
"sensibo_airconditioner_1",
|
||||
"ecobee_sensor",
|
||||
"ecobee_thermostat",
|
||||
"fake_fan",
|
||||
]
|
||||
item.components = {"main": item.capabilities}
|
||||
item.status = Mock(DeviceStatus)
|
||||
return item
|
||||
)
|
||||
def device_fixture(
|
||||
mock_smartthings: AsyncMock, request: pytest.FixtureRequest
|
||||
) -> Generator[str]:
|
||||
"""Return every device."""
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(name="config_entry")
|
||||
def config_entry_fixture(installed_app: Mock, location: Mock) -> MockConfigEntry:
|
||||
"""Fixture representing a config entry."""
|
||||
data = {
|
||||
CONF_ACCESS_TOKEN: str(uuid4()),
|
||||
CONF_INSTALLED_APP_ID: installed_app.installed_app_id,
|
||||
CONF_APP_ID: installed_app.app_id,
|
||||
CONF_LOCATION_ID: location.location_id,
|
||||
CONF_REFRESH_TOKEN: str(uuid4()),
|
||||
CONF_CLIENT_ID: str(uuid4()),
|
||||
CONF_CLIENT_SECRET: str(uuid4()),
|
||||
}
|
||||
@pytest.fixture
|
||||
def devices(mock_smartthings: AsyncMock, device_fixture: str) -> Generator[AsyncMock]:
|
||||
"""Return a specific device."""
|
||||
mock_smartthings.get_devices.return_value = DeviceResponse.from_json(
|
||||
load_fixture(f"devices/{device_fixture}.json", DOMAIN)
|
||||
).items
|
||||
mock_smartthings.get_device_status.return_value = DeviceStatus.from_json(
|
||||
load_fixture(f"device_status/{device_fixture}.json", DOMAIN)
|
||||
).components
|
||||
return mock_smartthings
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry(expires_at: int) -> MockConfigEntry:
|
||||
"""Mock a config entry."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data=data,
|
||||
title=location.name,
|
||||
version=2,
|
||||
source=SOURCE_USER,
|
||||
title="My home",
|
||||
unique_id="397678e5-9995-4a39-9d9f-ae6ba310236c",
|
||||
data={
|
||||
"auth_implementation": DOMAIN,
|
||||
"token": {
|
||||
"access_token": "mock-access-token",
|
||||
"refresh_token": "mock-refresh-token",
|
||||
"expires_at": expires_at,
|
||||
"scope": " ".join(SCOPES),
|
||||
"access_tier": 0,
|
||||
"installed_app_id": "5aaaa925-2be1-4e40-b257-e4ef59083324",
|
||||
},
|
||||
CONF_LOCATION_ID: "397678e5-9995-4a39-9d9f-ae6ba310236c",
|
||||
CONF_INSTALLED_APP_ID: "123",
|
||||
},
|
||||
version=3,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="subscription_factory")
|
||||
def subscription_factory_fixture():
|
||||
"""Fixture for creating mock subscriptions."""
|
||||
|
||||
def _factory(capability):
|
||||
sub = Subscription()
|
||||
sub.capability = capability
|
||||
return sub
|
||||
|
||||
return _factory
|
||||
|
||||
|
||||
@pytest.fixture(name="device_factory")
|
||||
def device_factory_fixture():
|
||||
"""Fixture for creating mock devices."""
|
||||
api = Mock(Api)
|
||||
api.post_device_command.return_value = {"results": [{"status": "ACCEPTED"}]}
|
||||
|
||||
def _factory(label, capabilities, status: dict | None = None):
|
||||
device_data = {
|
||||
"deviceId": str(uuid4()),
|
||||
"name": "Device Type Handler Name",
|
||||
"label": label,
|
||||
"deviceManufacturerCode": "9135fc86-0929-4436-bf73-5d75f523d9db",
|
||||
"locationId": "fcd829e9-82f4-45b9-acfd-62fda029af80",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"capabilities": [
|
||||
{"id": capability, "version": 1} for capability in capabilities
|
||||
],
|
||||
}
|
||||
],
|
||||
"dth": {
|
||||
"deviceTypeId": "b678b29d-2726-4e4f-9c3f-7aa05bd08964",
|
||||
"deviceTypeName": "Switch",
|
||||
"deviceNetworkType": "ZWAVE",
|
||||
},
|
||||
"type": "DTH",
|
||||
}
|
||||
device = DeviceEntity(api, data=device_data)
|
||||
if status:
|
||||
for attribute, value in status.items():
|
||||
device.status.apply_attribute_update("main", "", attribute, value)
|
||||
return device
|
||||
|
||||
return _factory
|
||||
|
||||
|
||||
@pytest.fixture(name="scene_factory")
|
||||
def scene_factory_fixture(location):
|
||||
"""Fixture for creating mock devices."""
|
||||
|
||||
def _factory(name):
|
||||
scene = Mock(SceneEntity)
|
||||
scene.scene_id = str(uuid4())
|
||||
scene.name = name
|
||||
scene.icon = None
|
||||
scene.color = None
|
||||
scene.location_id = location.location_id
|
||||
return scene
|
||||
|
||||
return _factory
|
||||
|
||||
|
||||
@pytest.fixture(name="scene")
|
||||
def scene_fixture(scene_factory):
|
||||
"""Fixture for an individual scene."""
|
||||
return scene_factory("Test Scene")
|
||||
|
||||
|
||||
@pytest.fixture(name="event_factory")
|
||||
def event_factory_fixture():
|
||||
"""Fixture for creating mock devices."""
|
||||
|
||||
def _factory(
|
||||
device_id,
|
||||
event_type="DEVICE_EVENT",
|
||||
capability="",
|
||||
attribute="Updated",
|
||||
value="Value",
|
||||
data=None,
|
||||
):
|
||||
event = Mock()
|
||||
event.event_type = event_type
|
||||
event.device_id = device_id
|
||||
event.component_id = "main"
|
||||
event.capability = capability
|
||||
event.attribute = attribute
|
||||
event.value = value
|
||||
event.data = data
|
||||
event.location_id = str(uuid4())
|
||||
return event
|
||||
|
||||
return _factory
|
||||
|
||||
|
||||
@pytest.fixture(name="event_request_factory")
|
||||
def event_request_factory_fixture(event_factory):
|
||||
"""Fixture for creating mock smartapp event requests."""
|
||||
|
||||
def _factory(device_ids=None, events=None):
|
||||
request = Mock()
|
||||
request.installed_app_id = uuid4()
|
||||
if events is None:
|
||||
events = []
|
||||
if device_ids:
|
||||
events.extend([event_factory(device_id) for device_id in device_ids])
|
||||
events.append(event_factory(uuid4()))
|
||||
events.append(event_factory(device_ids[0], event_type="OTHER"))
|
||||
request.events = events
|
||||
return request
|
||||
|
||||
return _factory
|
||||
@pytest.fixture
|
||||
def mock_old_config_entry() -> MockConfigEntry:
|
||||
"""Mock the old config entry."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="My home",
|
||||
unique_id="appid123-2be1-4e40-b257-e4ef59083324_397678e5-9995-4a39-9d9f-ae6ba310236c",
|
||||
data={
|
||||
CONF_ACCESS_TOKEN: "mock-access-token",
|
||||
CONF_REFRESH_TOKEN: "mock-refresh-token",
|
||||
CONF_CLIENT_ID: "CLIENT_ID",
|
||||
CONF_CLIENT_SECRET: "CLIENT_SECRET",
|
||||
CONF_LOCATION_ID: "397678e5-9995-4a39-9d9f-ae6ba310236c",
|
||||
CONF_INSTALLED_APP_ID: "123aa123-2be1-4e40-b257-e4ef59083324",
|
||||
},
|
||||
version=2,
|
||||
)
|
||||
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"powerMeter": {
|
||||
"power": {
|
||||
"value": 2859.743,
|
||||
"unit": "W",
|
||||
"timestamp": "2025-02-10T21:09:08.228Z"
|
||||
}
|
||||
},
|
||||
"voltageMeasurement": {
|
||||
"voltage": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"energyMeter": {
|
||||
"energy": {
|
||||
"value": 19978.536,
|
||||
"unit": "kWh",
|
||||
"timestamp": "2025-02-10T21:09:08.357Z"
|
||||
}
|
||||
},
|
||||
"refresh": {}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"powerMeter": {
|
||||
"power": {
|
||||
"value": 938.3,
|
||||
"unit": "W",
|
||||
"timestamp": "2025-02-09T17:56:21.748Z"
|
||||
}
|
||||
},
|
||||
"energyMeter": {
|
||||
"energy": {
|
||||
"value": 1930.362,
|
||||
"unit": "kWh",
|
||||
"timestamp": "2025-02-09T17:56:21.918Z"
|
||||
}
|
||||
},
|
||||
"refresh": {}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"videoCapture": {
|
||||
"stream": {
|
||||
"value": null
|
||||
},
|
||||
"clip": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"videoStream": {
|
||||
"supportedFeatures": {
|
||||
"value": null
|
||||
},
|
||||
"stream": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2025-02-03T21:55:57.991Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "online",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-08T21:56:09.761Z"
|
||||
}
|
||||
},
|
||||
"alarm": {
|
||||
"alarm": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T21:56:09.761Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"soundSensor": {
|
||||
"sound": {
|
||||
"value": "not detected",
|
||||
"timestamp": "2025-02-08T21:56:09.761Z"
|
||||
}
|
||||
},
|
||||
"motionSensor": {
|
||||
"motion": {
|
||||
"value": "inactive",
|
||||
"timestamp": "2025-02-08T21:56:09.761Z"
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": null
|
||||
},
|
||||
"battery": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-08T21:56:10.041Z"
|
||||
},
|
||||
"type": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-08T21:56:10.041Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2025-02-07T23:01:15.966Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "offline",
|
||||
"data": {
|
||||
"reason": "DEVICE-OFFLINE"
|
||||
},
|
||||
"timestamp": "2025-02-08T09:04:47.694Z"
|
||||
}
|
||||
},
|
||||
"switchLevel": {
|
||||
"levelRange": {
|
||||
"value": null
|
||||
},
|
||||
"level": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-08T09:04:47.694Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"windowShade": {
|
||||
"supportedWindowShadeCommands": {
|
||||
"value": null
|
||||
},
|
||||
"windowShade": {
|
||||
"value": "open",
|
||||
"timestamp": "2025-02-08T09:04:47.694Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"powerMeter": {
|
||||
"power": {
|
||||
"value": 0.0,
|
||||
"unit": "W",
|
||||
"timestamp": "2025-02-09T17:49:15.190Z"
|
||||
}
|
||||
},
|
||||
"switchLevel": {
|
||||
"levelRange": {
|
||||
"value": null
|
||||
},
|
||||
"level": {
|
||||
"value": 0,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T17:49:15.112Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"firmwareUpdate": {
|
||||
"lastUpdateStatusReason": {
|
||||
"value": null
|
||||
},
|
||||
"availableVersion": {
|
||||
"value": "16015010",
|
||||
"timestamp": "2025-01-26T10:19:54.783Z"
|
||||
},
|
||||
"lastUpdateStatus": {
|
||||
"value": null
|
||||
},
|
||||
"supportedCommands": {
|
||||
"value": null
|
||||
},
|
||||
"state": {
|
||||
"value": "normalOperation",
|
||||
"timestamp": "2025-01-26T10:19:54.788Z"
|
||||
},
|
||||
"updateAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-01-26T10:19:54.789Z"
|
||||
},
|
||||
"currentVersion": {
|
||||
"value": "16015010",
|
||||
"timestamp": "2025-01-26T10:19:54.775Z"
|
||||
},
|
||||
"lastUpdateTime": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T17:24:16.864Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-09T17:16:42.674Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 59.0,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-09T17:11:44.249Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": null
|
||||
},
|
||||
"battery": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T13:23:50.726Z"
|
||||
},
|
||||
"type": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"firmwareUpdate": {
|
||||
"lastUpdateStatusReason": {
|
||||
"value": null
|
||||
},
|
||||
"availableVersion": {
|
||||
"value": "00000103",
|
||||
"timestamp": "2025-02-09T13:59:19.101Z"
|
||||
},
|
||||
"lastUpdateStatus": {
|
||||
"value": null
|
||||
},
|
||||
"supportedCommands": {
|
||||
"value": null
|
||||
},
|
||||
"state": {
|
||||
"value": "normalOperation",
|
||||
"timestamp": "2025-02-09T13:59:19.101Z"
|
||||
},
|
||||
"updateAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-09T13:59:19.102Z"
|
||||
},
|
||||
"currentVersion": {
|
||||
"value": "00000103",
|
||||
"timestamp": "2025-02-09T13:59:19.102Z"
|
||||
},
|
||||
"lastUpdateTime": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,879 @@
|
||||
{
|
||||
"components": {
|
||||
"1": {
|
||||
"relativeHumidityMeasurement": {
|
||||
"humidity": {
|
||||
"value": 0,
|
||||
"unit": "%",
|
||||
"timestamp": "2021-04-06T16:43:35.291Z"
|
||||
}
|
||||
},
|
||||
"custom.airConditionerOdorController": {
|
||||
"airConditionerOdorControllerProgress": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-08T04:11:38.269Z"
|
||||
},
|
||||
"airConditionerOdorControllerState": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-08T04:11:38.269Z"
|
||||
}
|
||||
},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-08T04:04:19.901Z"
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-08T04:04:19.901Z"
|
||||
}
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"availableAcModes": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAcModes": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-08T03:50:50.930Z"
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-08T03:50:50.930Z"
|
||||
}
|
||||
},
|
||||
"custom.spiMode": {
|
||||
"spiMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:57:57.686Z"
|
||||
}
|
||||
},
|
||||
"airQualitySensor": {
|
||||
"airQuality": {
|
||||
"value": null,
|
||||
"unit": "CAQI",
|
||||
"timestamp": "2021-04-06T16:57:57.602Z"
|
||||
}
|
||||
},
|
||||
"custom.airConditionerOptionalMode": {
|
||||
"supportedAcOptionalMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:57:57.659Z"
|
||||
},
|
||||
"acOptionalMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:57:57.659Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.518Z"
|
||||
}
|
||||
},
|
||||
"custom.airConditionerTropicalNightMode": {
|
||||
"acTropicalNightModeLevel": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.498Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mndt": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnfv": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"di": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"n": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.472Z"
|
||||
}
|
||||
},
|
||||
"airConditionerFanMode": {
|
||||
"fanMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.381Z"
|
||||
},
|
||||
"supportedAcFanModes": {
|
||||
"value": ["auto", "low", "medium", "high", "turbo"],
|
||||
"timestamp": "2024-09-10T10:26:28.605Z"
|
||||
},
|
||||
"availableAcFanModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"remoteControlStatus",
|
||||
"airQualitySensor",
|
||||
"dustSensor",
|
||||
"odorSensor",
|
||||
"veryFineDustSensor",
|
||||
"custom.dustFilter",
|
||||
"custom.deodorFilter",
|
||||
"custom.deviceReportStateConfiguration",
|
||||
"audioVolume",
|
||||
"custom.autoCleaningMode",
|
||||
"custom.airConditionerTropicalNightMode",
|
||||
"custom.airConditionerOdorController",
|
||||
"demandResponseLoadControl",
|
||||
"relativeHumidityMeasurement"
|
||||
],
|
||||
"timestamp": "2024-09-10T10:26:28.605Z"
|
||||
}
|
||||
},
|
||||
"fanOscillationMode": {
|
||||
"supportedFanOscillationModes": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.325Z"
|
||||
},
|
||||
"availableFanOscillationModes": {
|
||||
"value": null
|
||||
},
|
||||
"fanOscillationMode": {
|
||||
"value": "fixed",
|
||||
"timestamp": "2025-02-08T00:44:53.247Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.373Z"
|
||||
}
|
||||
},
|
||||
"dustSensor": {
|
||||
"dustLevel": {
|
||||
"value": null,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2021-04-06T16:44:10.122Z"
|
||||
},
|
||||
"fineDustLevel": {
|
||||
"value": null,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2021-04-06T16:44:10.122Z"
|
||||
}
|
||||
},
|
||||
"custom.deviceReportStateConfiguration": {
|
||||
"reportStateRealtimePeriod": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:09.800Z"
|
||||
},
|
||||
"reportStateRealtime": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:09.800Z"
|
||||
},
|
||||
"reportStatePeriod": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:09.800Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:59.136Z"
|
||||
}
|
||||
},
|
||||
"demandResponseLoadControl": {
|
||||
"drlcStatus": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:54.748Z"
|
||||
}
|
||||
},
|
||||
"audioVolume": {
|
||||
"volume": {
|
||||
"value": null,
|
||||
"unit": "%",
|
||||
"timestamp": "2021-04-06T16:43:53.541Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:53.364Z"
|
||||
}
|
||||
},
|
||||
"custom.autoCleaningMode": {
|
||||
"supportedAutoCleaningModes": {
|
||||
"value": null
|
||||
},
|
||||
"timedCleanDuration": {
|
||||
"value": null
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"timedCleanDurationRange": {
|
||||
"value": null
|
||||
},
|
||||
"supportedOperatingStates": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
},
|
||||
"autoCleaningMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:53.344Z"
|
||||
}
|
||||
},
|
||||
"custom.dustFilter": {
|
||||
"dustFilterUsageStep": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.145Z"
|
||||
},
|
||||
"dustFilterUsage": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.145Z"
|
||||
},
|
||||
"dustFilterLastResetDate": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.145Z"
|
||||
},
|
||||
"dustFilterStatus": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.145Z"
|
||||
},
|
||||
"dustFilterCapacity": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.145Z"
|
||||
},
|
||||
"dustFilterResetType": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.145Z"
|
||||
}
|
||||
},
|
||||
"odorSensor": {
|
||||
"odorLevel": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:38.992Z"
|
||||
}
|
||||
},
|
||||
"remoteControlStatus": {
|
||||
"remoteControlEnabled": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.097Z"
|
||||
}
|
||||
},
|
||||
"custom.deodorFilter": {
|
||||
"deodorFilterCapacity": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.118Z"
|
||||
},
|
||||
"deodorFilterLastResetDate": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.118Z"
|
||||
},
|
||||
"deodorFilterStatus": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.118Z"
|
||||
},
|
||||
"deodorFilterResetType": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.118Z"
|
||||
},
|
||||
"deodorFilterUsage": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.118Z"
|
||||
},
|
||||
"deodorFilterUsageStep": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:39.118Z"
|
||||
}
|
||||
},
|
||||
"custom.energyType": {
|
||||
"energyType": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:38.843Z"
|
||||
},
|
||||
"energySavingSupport": {
|
||||
"value": null
|
||||
},
|
||||
"drMaxDuration": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingInfo": {
|
||||
"value": null
|
||||
},
|
||||
"supportedEnergySavingLevels": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperation": {
|
||||
"value": null
|
||||
},
|
||||
"notificationTemplateID": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperationSupport": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"veryFineDustSensor": {
|
||||
"veryFineDustLevel": {
|
||||
"value": null,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2021-04-06T16:43:38.529Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": {
|
||||
"relativeHumidityMeasurement": {
|
||||
"humidity": {
|
||||
"value": 60,
|
||||
"unit": "%",
|
||||
"timestamp": "2024-12-30T13:10:23.759Z"
|
||||
}
|
||||
},
|
||||
"custom.airConditionerOdorController": {
|
||||
"airConditionerOdorControllerProgress": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:37.555Z"
|
||||
},
|
||||
"airConditionerOdorControllerState": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:37.555Z"
|
||||
}
|
||||
},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": 16,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-01-08T06:30:58.307Z"
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": 30,
|
||||
"unit": "C",
|
||||
"timestamp": "2024-09-10T10:26:28.781Z"
|
||||
}
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"availableAcModes": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAcModes": {
|
||||
"value": ["cool", "dry", "wind", "auto", "heat"],
|
||||
"timestamp": "2024-09-10T10:26:28.781Z"
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"value": "heat",
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"custom.spiMode": {
|
||||
"spiMode": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dongleSoftwareInstallation": {
|
||||
"status": {
|
||||
"value": "completed",
|
||||
"timestamp": "2021-12-29T01:36:51.289Z"
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": null
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": null
|
||||
},
|
||||
"description": {
|
||||
"value": null
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": null
|
||||
},
|
||||
"binaryId": {
|
||||
"value": "ARTIK051_KRAC_18K",
|
||||
"timestamp": "2025-02-08T00:44:53.855Z"
|
||||
}
|
||||
},
|
||||
"airQualitySensor": {
|
||||
"airQuality": {
|
||||
"value": null,
|
||||
"unit": "CAQI",
|
||||
"timestamp": "2021-04-06T16:43:37.208Z"
|
||||
}
|
||||
},
|
||||
"custom.airConditionerOptionalMode": {
|
||||
"supportedAcOptionalMode": {
|
||||
"value": ["off", "windFree"],
|
||||
"timestamp": "2024-09-10T10:26:28.781Z"
|
||||
},
|
||||
"acOptionalMode": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T16:37:54.072Z"
|
||||
}
|
||||
},
|
||||
"custom.airConditionerTropicalNightMode": {
|
||||
"acTropicalNightModeLevel": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.933Z"
|
||||
},
|
||||
"mndt": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.912Z"
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "0.1.0",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "96a5ef74-5832-a84b-f1f7-ca799957065d",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.803Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "[room a/c] Samsung",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "ARTIK051_KRAC_18K|10193441|60010132001111110200000000000000",
|
||||
"timestamp": "2024-09-10T10:26:28.781Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-AC-RAC-000001",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "0G3MPDCKA00010E",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "TizenRT2.0",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "96a5ef74-5832-a84b-f1f7-ca799957065d",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2024-09-10T10:26:28.552Z"
|
||||
}
|
||||
},
|
||||
"airConditionerFanMode": {
|
||||
"fanMode": {
|
||||
"value": "low",
|
||||
"timestamp": "2025-02-09T09:14:39.249Z"
|
||||
},
|
||||
"supportedAcFanModes": {
|
||||
"value": ["auto", "low", "medium", "high", "turbo"],
|
||||
"timestamp": "2025-02-09T09:14:39.249Z"
|
||||
},
|
||||
"availableAcFanModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"remoteControlStatus",
|
||||
"airQualitySensor",
|
||||
"dustSensor",
|
||||
"veryFineDustSensor",
|
||||
"custom.dustFilter",
|
||||
"custom.deodorFilter",
|
||||
"custom.deviceReportStateConfiguration",
|
||||
"samsungce.dongleSoftwareInstallation",
|
||||
"demandResponseLoadControl",
|
||||
"custom.airConditionerOdorController"
|
||||
],
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 24070101,
|
||||
"timestamp": "2024-09-04T06:35:09.557Z"
|
||||
}
|
||||
},
|
||||
"fanOscillationMode": {
|
||||
"supportedFanOscillationModes": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.782Z"
|
||||
},
|
||||
"availableFanOscillationModes": {
|
||||
"value": null
|
||||
},
|
||||
"fanOscillationMode": {
|
||||
"value": "fixed",
|
||||
"timestamp": "2025-02-09T09:14:39.249Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 25,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T16:33:29.164Z"
|
||||
}
|
||||
},
|
||||
"dustSensor": {
|
||||
"dustLevel": {
|
||||
"value": null,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2021-04-06T16:43:35.665Z"
|
||||
},
|
||||
"fineDustLevel": {
|
||||
"value": null,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2021-04-06T16:43:35.665Z"
|
||||
}
|
||||
},
|
||||
"custom.deviceReportStateConfiguration": {
|
||||
"reportStateRealtimePeriod": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.643Z"
|
||||
},
|
||||
"reportStateRealtime": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.643Z"
|
||||
},
|
||||
"reportStatePeriod": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.643Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 25,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T09:15:11.608Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledComponents": {
|
||||
"disabledComponents": {
|
||||
"value": ["1"],
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"demandResponseLoadControl": {
|
||||
"drlcStatus": {
|
||||
"value": {
|
||||
"drlcType": 1,
|
||||
"drlcLevel": -1,
|
||||
"start": "1970-01-01T00:00:00Z",
|
||||
"duration": 0,
|
||||
"override": false
|
||||
},
|
||||
"timestamp": "2024-09-10T10:26:28.781Z"
|
||||
}
|
||||
},
|
||||
"audioVolume": {
|
||||
"volume": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": {
|
||||
"energy": 2247300,
|
||||
"deltaEnergy": 400,
|
||||
"power": 0,
|
||||
"powerEnergy": 0.0,
|
||||
"persistedEnergy": 2247300,
|
||||
"energySaved": 0,
|
||||
"start": "2025-02-09T15:45:29Z",
|
||||
"end": "2025-02-09T16:15:33Z"
|
||||
},
|
||||
"timestamp": "2025-02-09T16:15:33.639Z"
|
||||
}
|
||||
},
|
||||
"custom.autoCleaningMode": {
|
||||
"supportedAutoCleaningModes": {
|
||||
"value": null
|
||||
},
|
||||
"timedCleanDuration": {
|
||||
"value": null
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"timedCleanDurationRange": {
|
||||
"value": null
|
||||
},
|
||||
"supportedOperatingStates": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
},
|
||||
"autoCleaningMode": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T09:14:39.642Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["oic.r.temperature"],
|
||||
"if": ["oic.if.baseline", "oic.if.a"],
|
||||
"range": [16.0, 30.0],
|
||||
"units": "C",
|
||||
"temperature": 22.0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/temperature/desired/0"
|
||||
},
|
||||
"timestamp": "2023-07-19T03:07:43.270Z"
|
||||
}
|
||||
},
|
||||
"samsungce.selfCheck": {
|
||||
"result": {
|
||||
"value": null
|
||||
},
|
||||
"supportedActions": {
|
||||
"value": ["start"],
|
||||
"timestamp": "2024-09-04T06:35:09.557Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
},
|
||||
"errors": {
|
||||
"value": [],
|
||||
"timestamp": "2025-02-08T00:44:53.349Z"
|
||||
},
|
||||
"status": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T00:44:53.549Z"
|
||||
}
|
||||
},
|
||||
"custom.dustFilter": {
|
||||
"dustFilterUsageStep": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.527Z"
|
||||
},
|
||||
"dustFilterUsage": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.527Z"
|
||||
},
|
||||
"dustFilterLastResetDate": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.527Z"
|
||||
},
|
||||
"dustFilterStatus": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.527Z"
|
||||
},
|
||||
"dustFilterCapacity": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.527Z"
|
||||
},
|
||||
"dustFilterResetType": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.527Z"
|
||||
}
|
||||
},
|
||||
"remoteControlStatus": {
|
||||
"remoteControlEnabled": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.379Z"
|
||||
}
|
||||
},
|
||||
"custom.deodorFilter": {
|
||||
"deodorFilterCapacity": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.502Z"
|
||||
},
|
||||
"deodorFilterLastResetDate": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.502Z"
|
||||
},
|
||||
"deodorFilterStatus": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.502Z"
|
||||
},
|
||||
"deodorFilterResetType": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.502Z"
|
||||
},
|
||||
"deodorFilterUsage": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.502Z"
|
||||
},
|
||||
"deodorFilterUsageStep": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:43:35.502Z"
|
||||
}
|
||||
},
|
||||
"custom.energyType": {
|
||||
"energyType": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2024-09-10T10:26:28.781Z"
|
||||
},
|
||||
"energySavingSupport": {
|
||||
"value": false,
|
||||
"timestamp": "2021-12-29T07:29:17.526Z"
|
||||
},
|
||||
"drMaxDuration": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingInfo": {
|
||||
"value": null
|
||||
},
|
||||
"supportedEnergySavingLevels": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperation": {
|
||||
"value": null
|
||||
},
|
||||
"notificationTemplateID": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperationSupport": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": null
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": "43CEZFTFFL7Z2",
|
||||
"timestamp": "2025-02-08T00:44:53.855Z"
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": [],
|
||||
"timestamp": "2025-02-08T00:44:53.855Z"
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-08T00:44:53.855Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"veryFineDustSensor": {
|
||||
"veryFineDustLevel": {
|
||||
"value": null,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2021-04-06T16:43:35.363Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,731 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"samsungce.unavailableCapabilities": {
|
||||
"unavailableCommands": {
|
||||
"value": ["custom.spiMode.setSpiMode"],
|
||||
"timestamp": "2025-02-09T05:44:01.769Z"
|
||||
}
|
||||
},
|
||||
"relativeHumidityMeasurement": {
|
||||
"humidity": {
|
||||
"value": 42,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T17:02:45.042Z"
|
||||
}
|
||||
},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": 16,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": 30,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"availableAcModes": {
|
||||
"value": [],
|
||||
"timestamp": "2025-02-09T14:35:56.800Z"
|
||||
},
|
||||
"supportedAcModes": {
|
||||
"value": ["auto", "cool", "dry", "wind", "heat"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"value": "cool",
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
}
|
||||
},
|
||||
"custom.spiMode": {
|
||||
"spiMode": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.airConditionerOptionalMode": {
|
||||
"supportedAcOptionalMode": {
|
||||
"value": [
|
||||
"off",
|
||||
"sleep",
|
||||
"quiet",
|
||||
"smart",
|
||||
"speed",
|
||||
"windFree",
|
||||
"windFreeSleep"
|
||||
],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"acOptionalMode": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T05:44:01.853Z"
|
||||
}
|
||||
},
|
||||
"samsungce.airConditionerBeep": {
|
||||
"beep": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null
|
||||
},
|
||||
"mndt": {
|
||||
"value": null
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "ARA-WW-TP1-22-COMMON_11240702",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "Realtek",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "4ece486b-89db-f06a-d54d-748b676b4d8e",
|
||||
"timestamp": "2025-02-09T15:42:12.714Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2025-02-09T15:42:12.714Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "Samsung-Room-Air-Conditioner",
|
||||
"timestamp": "2025-02-09T15:42:12.714Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "ARA-WW-TP1-22-COMMON|10229641|60010523001511014600083200800000",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-AC-RAC-01001",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "DAWIT 2.0",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "TizenRT 3.1",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "4ece486b-89db-f06a-d54d-748b676b4d8e",
|
||||
"timestamp": "2025-02-09T15:42:12.723Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2025-02-09T15:42:12.714Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"custom.deodorFilter",
|
||||
"custom.electricHepaFilter",
|
||||
"custom.periodicSensing",
|
||||
"custom.doNotDisturbMode",
|
||||
"samsungce.deviceInfoPrivate",
|
||||
"samsungce.quickControl",
|
||||
"samsungce.welcomeCooling",
|
||||
"samsungce.airConditionerBeep",
|
||||
"samsungce.airConditionerLighting",
|
||||
"samsungce.individualControlLock",
|
||||
"samsungce.alwaysOnSensing",
|
||||
"samsungce.buttonDisplayCondition",
|
||||
"airQualitySensor",
|
||||
"dustSensor",
|
||||
"odorSensor",
|
||||
"veryFineDustSensor",
|
||||
"custom.spiMode",
|
||||
"audioNotification"
|
||||
],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 24100102,
|
||||
"timestamp": "2025-01-28T21:31:35.935Z"
|
||||
}
|
||||
},
|
||||
"sec.diagnosticsInformation": {
|
||||
"logType": {
|
||||
"value": ["errCode", "dump"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"endpoint": {
|
||||
"value": "SSM",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"minVersion": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"signinPermission": {
|
||||
"value": null
|
||||
},
|
||||
"setupId": {
|
||||
"value": "010",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"protocolType": {
|
||||
"value": "wifi_https",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"tsId": {
|
||||
"value": "DA01",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"mnId": {
|
||||
"value": "0AJT",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"dumpType": {
|
||||
"value": "file",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"fanOscillationMode": {
|
||||
"supportedFanOscillationModes": {
|
||||
"value": ["fixed", "vertical", "horizontal", "all"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"availableFanOscillationModes": {
|
||||
"value": null
|
||||
},
|
||||
"fanOscillationMode": {
|
||||
"value": "fixed",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"custom.periodicSensing": {
|
||||
"automaticExecutionSetting": {
|
||||
"value": null
|
||||
},
|
||||
"automaticExecutionMode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAutomaticExecutionSetting": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAutomaticExecutionMode": {
|
||||
"value": null
|
||||
},
|
||||
"periodicSensing": {
|
||||
"value": null
|
||||
},
|
||||
"periodicSensingInterval": {
|
||||
"value": null
|
||||
},
|
||||
"lastSensingTime": {
|
||||
"value": null
|
||||
},
|
||||
"lastSensingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"periodicSensingStatus": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"demandResponseLoadControl": {
|
||||
"drlcStatus": {
|
||||
"value": {
|
||||
"drlcType": 1,
|
||||
"drlcLevel": 0,
|
||||
"start": "1970-01-01T00:00:00Z",
|
||||
"duration": 0,
|
||||
"override": false
|
||||
},
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"audioVolume": {
|
||||
"volume": {
|
||||
"value": 0,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": {
|
||||
"energy": 13836,
|
||||
"deltaEnergy": 0,
|
||||
"power": 0,
|
||||
"powerEnergy": 0.0,
|
||||
"persistedEnergy": 13836,
|
||||
"energySaved": 0,
|
||||
"persistedSavedEnergy": 0,
|
||||
"start": "2025-02-09T16:08:15Z",
|
||||
"end": "2025-02-09T17:02:44Z"
|
||||
},
|
||||
"timestamp": "2025-02-09T17:02:44.883Z"
|
||||
}
|
||||
},
|
||||
"custom.autoCleaningMode": {
|
||||
"supportedAutoCleaningModes": {
|
||||
"value": null
|
||||
},
|
||||
"timedCleanDuration": {
|
||||
"value": null
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"timedCleanDurationRange": {
|
||||
"value": null
|
||||
},
|
||||
"supportedOperatingStates": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
},
|
||||
"autoCleaningMode": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-09T05:44:02.014Z"
|
||||
}
|
||||
},
|
||||
"samsungce.individualControlLock": {
|
||||
"lockState": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"audioNotification": {},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.welcomeCooling": {
|
||||
"latestRequestId": {
|
||||
"value": null
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"sec.wifiConfiguration": {
|
||||
"autoReconnection": {
|
||||
"value": true,
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"minVersion": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"supportedWiFiFreq": {
|
||||
"value": ["2.4G"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"supportedAuthType": {
|
||||
"value": ["OPEN", "WEP", "WPA-PSK", "WPA2-PSK", "SAE"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"protocolType": {
|
||||
"value": ["helper_hotspot", "ble_ocf"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"samsungce.selfCheck": {
|
||||
"result": {
|
||||
"value": null
|
||||
},
|
||||
"supportedActions": {
|
||||
"value": ["start", "cancel"],
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": 1,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
},
|
||||
"errors": {
|
||||
"value": [],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"status": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
}
|
||||
},
|
||||
"custom.dustFilter": {
|
||||
"dustFilterUsageStep": {
|
||||
"value": 1,
|
||||
"timestamp": "2025-02-09T12:00:10.310Z"
|
||||
},
|
||||
"dustFilterUsage": {
|
||||
"value": 12,
|
||||
"timestamp": "2025-02-09T12:00:10.310Z"
|
||||
},
|
||||
"dustFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"dustFilterStatus": {
|
||||
"value": "normal",
|
||||
"timestamp": "2025-02-09T12:00:10.310Z"
|
||||
},
|
||||
"dustFilterCapacity": {
|
||||
"value": 500,
|
||||
"unit": "Hour",
|
||||
"timestamp": "2025-02-09T12:00:10.310Z"
|
||||
},
|
||||
"dustFilterResetType": {
|
||||
"value": ["replaceable", "washable"],
|
||||
"timestamp": "2025-02-09T12:00:10.310Z"
|
||||
}
|
||||
},
|
||||
"custom.energyType": {
|
||||
"energyType": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2025-01-28T21:31:39.517Z"
|
||||
},
|
||||
"energySavingSupport": {
|
||||
"value": true,
|
||||
"timestamp": "2025-01-28T21:38:35.560Z"
|
||||
},
|
||||
"drMaxDuration": {
|
||||
"value": 99999999,
|
||||
"unit": "min",
|
||||
"timestamp": "2025-01-28T21:31:37.357Z"
|
||||
},
|
||||
"energySavingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingInfo": {
|
||||
"value": null
|
||||
},
|
||||
"supportedEnergySavingLevels": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperation": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"notificationTemplateID": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperationSupport": {
|
||||
"value": true,
|
||||
"timestamp": "2025-01-28T21:38:35.731Z"
|
||||
}
|
||||
},
|
||||
"bypassable": {
|
||||
"bypassStatus": {
|
||||
"value": "bypassed",
|
||||
"timestamp": "2025-01-28T21:31:35.935Z"
|
||||
}
|
||||
},
|
||||
"samsungce.airQualityHealthConcern": {
|
||||
"supportedAirQualityHealthConcerns": {
|
||||
"value": null
|
||||
},
|
||||
"airQualityHealthConcern": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": {},
|
||||
"timestamp": "2025-02-05T20:07:11.459Z"
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": "U7CB2ZD4QPDUC",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": [],
|
||||
"timestamp": "2025-01-28T21:31:38.089Z"
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": "none",
|
||||
"timestamp": "2025-02-05T20:07:11.459Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"veryFineDustSensor": {
|
||||
"veryFineDustLevel": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.veryFineDustFilter": {
|
||||
"veryFineDustFilterStatus": {
|
||||
"value": null
|
||||
},
|
||||
"veryFineDustFilterResetType": {
|
||||
"value": null
|
||||
},
|
||||
"veryFineDustFilterUsage": {
|
||||
"value": null
|
||||
},
|
||||
"veryFineDustFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"veryFineDustFilterUsageStep": {
|
||||
"value": null
|
||||
},
|
||||
"veryFineDustFilterCapacity": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.silentAction": {},
|
||||
"custom.airConditionerOdorController": {
|
||||
"airConditionerOdorControllerProgress": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
},
|
||||
"airConditionerOdorControllerState": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": null
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": null
|
||||
},
|
||||
"description": {
|
||||
"value": null
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": 21,
|
||||
"timestamp": "2025-01-28T21:31:35.935Z"
|
||||
},
|
||||
"binaryId": {
|
||||
"value": "ARA-WW-TP1-22-COMMON",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"airQualitySensor": {
|
||||
"airQuality": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"samsungce.quickControl": {
|
||||
"version": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.airConditionerTropicalNightMode": {
|
||||
"acTropicalNightModeLevel": {
|
||||
"value": 6,
|
||||
"timestamp": "2025-02-09T04:52:00.923Z"
|
||||
}
|
||||
},
|
||||
"airConditionerFanMode": {
|
||||
"fanMode": {
|
||||
"value": "high",
|
||||
"timestamp": "2025-02-09T14:07:45.816Z"
|
||||
},
|
||||
"supportedAcFanModes": {
|
||||
"value": ["auto", "low", "medium", "high", "turbo"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"availableAcFanModes": {
|
||||
"value": ["auto", "low", "medium", "high", "turbo"],
|
||||
"timestamp": "2025-02-09T05:44:01.769Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dustFilterAlarm": {
|
||||
"alarmThreshold": {
|
||||
"value": 500,
|
||||
"unit": "Hour",
|
||||
"timestamp": "2025-02-09T12:00:10.310Z"
|
||||
},
|
||||
"supportedAlarmThresholds": {
|
||||
"value": [180, 300, 500, 700],
|
||||
"unit": "Hour",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"custom.electricHepaFilter": {
|
||||
"electricHepaFilterCapacity": {
|
||||
"value": null
|
||||
},
|
||||
"electricHepaFilterUsageStep": {
|
||||
"value": null
|
||||
},
|
||||
"electricHepaFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"electricHepaFilterStatus": {
|
||||
"value": null
|
||||
},
|
||||
"electricHepaFilterUsage": {
|
||||
"value": null
|
||||
},
|
||||
"electricHepaFilterResetType": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.airConditionerLighting": {
|
||||
"supportedLightingLevels": {
|
||||
"value": ["on", "off"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"lighting": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-09T09:30:03.213Z"
|
||||
}
|
||||
},
|
||||
"samsungce.buttonDisplayCondition": {
|
||||
"switch": {
|
||||
"value": "enabled",
|
||||
"timestamp": "2025-02-09T05:17:41.282Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 27,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T16:38:17.028Z"
|
||||
}
|
||||
},
|
||||
"dustSensor": {
|
||||
"dustLevel": {
|
||||
"value": null
|
||||
},
|
||||
"fineDustLevel": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"sec.calmConnectionCare": {
|
||||
"role": {
|
||||
"value": ["things"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"protocols": {
|
||||
"value": null
|
||||
},
|
||||
"version": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"custom.deviceReportStateConfiguration": {
|
||||
"reportStateRealtimePeriod": {
|
||||
"value": "disabled",
|
||||
"timestamp": "2025-02-09T05:17:39.792Z"
|
||||
},
|
||||
"reportStateRealtime": {
|
||||
"value": {
|
||||
"state": "disabled"
|
||||
},
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"reportStatePeriod": {
|
||||
"value": "enabled",
|
||||
"timestamp": "2025-02-09T05:17:39.792Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": {
|
||||
"minimum": 16,
|
||||
"maximum": 30,
|
||||
"step": 1
|
||||
},
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T05:17:41.533Z"
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 23,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T14:07:45.643Z"
|
||||
}
|
||||
},
|
||||
"samsungce.alwaysOnSensing": {
|
||||
"origins": {
|
||||
"value": [],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"alwaysOn": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"odorSensor": {
|
||||
"odorLevel": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.deodorFilter": {
|
||||
"deodorFilterCapacity": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterStatus": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterResetType": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterUsage": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterUsageStep": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.doNotDisturbMode": {
|
||||
"doNotDisturb": {
|
||||
"value": null
|
||||
},
|
||||
"startTime": {
|
||||
"value": null
|
||||
},
|
||||
"endTime": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,600 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"doorControl": {
|
||||
"door": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.kitchenDeviceDefaults": {
|
||||
"defaultOperationTime": {
|
||||
"value": 30,
|
||||
"timestamp": "2022-03-23T15:59:12.609Z"
|
||||
},
|
||||
"defaultOvenMode": {
|
||||
"value": "MicroWave",
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
},
|
||||
"defaultOvenSetpoint": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": null
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": null
|
||||
},
|
||||
"description": {
|
||||
"value": null
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": null
|
||||
},
|
||||
"binaryId": {
|
||||
"value": "TP2X_DA-KS-MICROWAVE-0101X",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T00:11:12.010Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null
|
||||
},
|
||||
"mndt": {
|
||||
"value": null
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "AKS-WW-TP2-20-MICROWAVE-OTR_40230125",
|
||||
"timestamp": "2023-07-03T06:44:54.757Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "MediaTek",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "2bad3237-4886-e699-1b90-4a51a3d55c8a",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2023-07-03T22:00:58.832Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "Samsung Microwave",
|
||||
"timestamp": "2023-07-03T06:44:54.757Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "TP2X_DA-KS-MICROWAVE-0101X|40436241|50040100011411000200000000000000",
|
||||
"timestamp": "2023-07-03T06:44:54.757Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-KS-MICROWAVE-0101X",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "DAWIT 3.0",
|
||||
"timestamp": "2023-07-03T06:44:54.757Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "TizenRT 2.0 + IPv6",
|
||||
"timestamp": "2023-07-03T06:44:54.757Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "2bad3237-4886-e699-1b90-4a51a3d55c8a",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2022-03-23T15:59:12.742Z"
|
||||
}
|
||||
},
|
||||
"samsungce.kitchenDeviceIdentification": {
|
||||
"regionCode": {
|
||||
"value": "US",
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
},
|
||||
"modelCode": {
|
||||
"value": "ME8000T-/AA0",
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
},
|
||||
"fuel": {
|
||||
"value": null
|
||||
},
|
||||
"type": {
|
||||
"value": "microwave",
|
||||
"timestamp": "2022-03-23T15:59:10.971Z"
|
||||
},
|
||||
"representativeComponent": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.kitchenModeSpecification": {
|
||||
"specification": {
|
||||
"value": {
|
||||
"single": [
|
||||
{
|
||||
"mode": "MicroWave",
|
||||
"supportedOptions": {
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
},
|
||||
"powerLevel": {
|
||||
"default": "100%",
|
||||
"supportedValues": [
|
||||
"0%",
|
||||
"10%",
|
||||
"20%",
|
||||
"30%",
|
||||
"40%",
|
||||
"50%",
|
||||
"60%",
|
||||
"70%",
|
||||
"80%",
|
||||
"90%",
|
||||
"100%"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "ConvectionBake",
|
||||
"supportedOptions": {
|
||||
"temperature": {
|
||||
"F": {
|
||||
"min": 100,
|
||||
"max": 425,
|
||||
"default": 350,
|
||||
"supportedValues": [
|
||||
100, 200, 225, 250, 275, 300, 325, 350, 375, 400, 425
|
||||
]
|
||||
}
|
||||
},
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "ConvectionRoast",
|
||||
"supportedOptions": {
|
||||
"temperature": {
|
||||
"F": {
|
||||
"min": 200,
|
||||
"max": 425,
|
||||
"default": 325,
|
||||
"supportedValues": [
|
||||
200, 225, 250, 275, 300, 325, 350, 375, 400, 425
|
||||
]
|
||||
}
|
||||
},
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "Grill",
|
||||
"supportedOptions": {
|
||||
"temperature": {
|
||||
"F": {
|
||||
"min": 425,
|
||||
"max": 425,
|
||||
"default": 425,
|
||||
"resolution": 5
|
||||
}
|
||||
},
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "SpeedBake",
|
||||
"supportedOptions": {
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
},
|
||||
"powerLevel": {
|
||||
"default": "30%",
|
||||
"supportedValues": ["10%", "30%", "50%", "70%"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "SpeedRoast",
|
||||
"supportedOptions": {
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
},
|
||||
"powerLevel": {
|
||||
"default": "30%",
|
||||
"supportedValues": ["10%", "30%", "50%", "70%"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "KeepWarm",
|
||||
"supportedOptions": {
|
||||
"temperature": {
|
||||
"F": {
|
||||
"min": 175,
|
||||
"max": 175,
|
||||
"default": 175,
|
||||
"resolution": 5
|
||||
}
|
||||
},
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "Autocook",
|
||||
"supportedOptions": {}
|
||||
},
|
||||
{
|
||||
"mode": "Cookie",
|
||||
"supportedOptions": {
|
||||
"temperature": {
|
||||
"F": {
|
||||
"min": 325,
|
||||
"max": 325,
|
||||
"default": 325,
|
||||
"resolution": 5
|
||||
}
|
||||
},
|
||||
"operationTime": {
|
||||
"max": "01:40:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": "SteamClean",
|
||||
"supportedOptions": {
|
||||
"operationTime": {
|
||||
"max": "00:06:30"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"timestamp": "2025-02-08T10:21:03.790Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["doorControl", "samsungce.hoodFanSpeed"],
|
||||
"timestamp": "2025-02-08T21:13:36.152Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 22120101,
|
||||
"timestamp": "2023-07-03T09:36:13.282Z"
|
||||
}
|
||||
},
|
||||
"sec.diagnosticsInformation": {
|
||||
"logType": {
|
||||
"value": ["errCode", "dump"],
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"endpoint": {
|
||||
"value": "SSM",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"minVersion": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"signinPermission": {
|
||||
"value": null
|
||||
},
|
||||
"setupId": {
|
||||
"value": "621",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"protocolType": {
|
||||
"value": "wifi_https",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"tsId": {
|
||||
"value": null
|
||||
},
|
||||
"mnId": {
|
||||
"value": "0AJT",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"dumpType": {
|
||||
"value": "file",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 1,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-09T00:11:15.291Z"
|
||||
}
|
||||
},
|
||||
"samsungce.ovenOperatingState": {
|
||||
"completionTime": {
|
||||
"value": "2025-02-08T21:13:36.184Z",
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
},
|
||||
"ovenJobState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T21:13:36.160Z"
|
||||
},
|
||||
"operationTime": {
|
||||
"value": "00:00:00",
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
}
|
||||
},
|
||||
"ovenMode": {
|
||||
"supportedOvenModes": {
|
||||
"value": [
|
||||
"Microwave",
|
||||
"ConvectionBake",
|
||||
"ConvectionRoast",
|
||||
"grill",
|
||||
"Others",
|
||||
"warming"
|
||||
],
|
||||
"timestamp": "2025-02-08T10:21:03.790Z"
|
||||
},
|
||||
"ovenMode": {
|
||||
"value": "Others",
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
}
|
||||
},
|
||||
"samsungce.ovenMode": {
|
||||
"supportedOvenModes": {
|
||||
"value": [
|
||||
"MicroWave",
|
||||
"ConvectionBake",
|
||||
"ConvectionRoast",
|
||||
"Grill",
|
||||
"SpeedBake",
|
||||
"SpeedRoast",
|
||||
"KeepWarm",
|
||||
"Autocook",
|
||||
"Cookie",
|
||||
"SteamClean"
|
||||
],
|
||||
"timestamp": "2025-02-08T10:21:03.790Z"
|
||||
},
|
||||
"ovenMode": {
|
||||
"value": "NoOperation",
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
}
|
||||
},
|
||||
"samsungce.kidsLock": {
|
||||
"lockState": {
|
||||
"value": "unlocked",
|
||||
"timestamp": "2025-02-08T21:13:36.152Z"
|
||||
}
|
||||
},
|
||||
"ovenSetpoint": {
|
||||
"ovenSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"ovenSetpoint": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T00:01:09.108Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"samsungce.hoodFanSpeed": {
|
||||
"settableMaxFanSpeed": {
|
||||
"value": 3,
|
||||
"timestamp": "2025-02-09T00:01:06.959Z"
|
||||
},
|
||||
"hoodFanSpeed": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T00:01:07.813Z"
|
||||
},
|
||||
"supportedHoodFanSpeed": {
|
||||
"value": [0, 1, 2, 3, 4, 5],
|
||||
"timestamp": "2022-03-23T15:59:12.796Z"
|
||||
},
|
||||
"settableMinFanSpeed": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T00:01:06.959Z"
|
||||
}
|
||||
},
|
||||
"samsungce.doorState": {
|
||||
"doorState": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-08T21:13:36.227Z"
|
||||
}
|
||||
},
|
||||
"samsungce.microwavePower": {
|
||||
"supportedPowerLevels": {
|
||||
"value": [
|
||||
"0%",
|
||||
"10%",
|
||||
"20%",
|
||||
"30%",
|
||||
"40%",
|
||||
"50%",
|
||||
"60%",
|
||||
"70%",
|
||||
"80%",
|
||||
"90%",
|
||||
"100%"
|
||||
],
|
||||
"timestamp": "2025-02-08T21:13:36.160Z"
|
||||
},
|
||||
"powerLevel": {
|
||||
"value": "0%",
|
||||
"timestamp": "2025-02-08T21:13:36.160Z"
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["x.com.samsung.da.temperatures"],
|
||||
"if": ["oic.if.baseline", "oic.if.a"],
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "0",
|
||||
"x.com.samsung.da.description": "Temperature",
|
||||
"x.com.samsung.da.desired": "0",
|
||||
"x.com.samsung.da.current": "1",
|
||||
"x.com.samsung.da.increment": "5",
|
||||
"x.com.samsung.da.unit": "Fahrenheit"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/temperatures/vs/0"
|
||||
},
|
||||
"timestamp": "2023-07-19T05:50:12.609Z"
|
||||
}
|
||||
},
|
||||
"remoteControlStatus": {
|
||||
"remoteControlEnabled": {
|
||||
"value": "false",
|
||||
"timestamp": "2025-02-08T21:13:36.357Z"
|
||||
}
|
||||
},
|
||||
"samsungce.definedRecipe": {
|
||||
"definedRecipe": {
|
||||
"value": {
|
||||
"cavityId": "0",
|
||||
"recipeType": "0",
|
||||
"categoryId": 0,
|
||||
"itemId": 0,
|
||||
"servingSize": 0,
|
||||
"browingLevel": 0,
|
||||
"option": 0
|
||||
},
|
||||
"timestamp": "2025-02-08T21:13:36.160Z"
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": null
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": "U7CNQWBWSCD7C",
|
||||
"timestamp": "2025-02-08T21:13:36.256Z"
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": [],
|
||||
"timestamp": "2025-02-08T21:13:36.213Z"
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-08T21:13:36.213Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"ovenOperatingState": {
|
||||
"completionTime": {
|
||||
"value": "2025-02-08T21:13:36.184Z",
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
},
|
||||
"machineState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": 0,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
},
|
||||
"supportedMachineStates": {
|
||||
"value": null
|
||||
},
|
||||
"ovenJobState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T21:13:36.160Z"
|
||||
},
|
||||
"operationTime": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-08T21:13:36.188Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hood": {
|
||||
"samsungce.hoodFanSpeed": {
|
||||
"settableMaxFanSpeed": {
|
||||
"value": 3,
|
||||
"timestamp": "2025-02-09T00:01:06.959Z"
|
||||
},
|
||||
"hoodFanSpeed": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T00:01:07.813Z"
|
||||
},
|
||||
"supportedHoodFanSpeed": {
|
||||
"value": [0, 1, 2, 3, 4, 5],
|
||||
"timestamp": "2022-03-23T15:59:12.796Z"
|
||||
},
|
||||
"settableMinFanSpeed": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-02-09T00:01:06.959Z"
|
||||
}
|
||||
},
|
||||
"samsungce.lamp": {
|
||||
"brightnessLevel": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
},
|
||||
"supportedBrightnessLevel": {
|
||||
"value": ["off", "low", "high"],
|
||||
"timestamp": "2025-02-08T21:13:36.289Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,727 @@
|
||||
{
|
||||
"components": {
|
||||
"pantry-01": {
|
||||
"samsungce.fridgePantryInfo": {
|
||||
"name": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [],
|
||||
"timestamp": "2022-02-07T10:47:54.524Z"
|
||||
}
|
||||
},
|
||||
"samsungce.fridgePantryMode": {
|
||||
"mode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedModes": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"pantry-02": {
|
||||
"samsungce.fridgePantryInfo": {
|
||||
"name": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [],
|
||||
"timestamp": "2022-02-07T10:47:54.524Z"
|
||||
}
|
||||
},
|
||||
"samsungce.fridgePantryMode": {
|
||||
"mode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedModes": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"icemaker": {
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [],
|
||||
"timestamp": "2024-10-12T13:55:04.008Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T13:55:01.720Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"onedoor": {
|
||||
"custom.fridgeMode": {
|
||||
"fridgeModeValue": {
|
||||
"value": null
|
||||
},
|
||||
"fridgeMode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedFridgeModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.unavailableCapabilities": {
|
||||
"unavailableCommands": {
|
||||
"value": [],
|
||||
"timestamp": "2024-11-08T04:14:59.899Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["samsungce.freezerConvertMode", "custom.fridgeMode"],
|
||||
"timestamp": "2024-11-12T08:23:59.944Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": null
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.freezerConvertMode": {
|
||||
"supportedFreezerConvertModes": {
|
||||
"value": null
|
||||
},
|
||||
"freezerConvertMode": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"cooler": {
|
||||
"custom.fridgeMode": {
|
||||
"fridgeModeValue": {
|
||||
"value": null
|
||||
},
|
||||
"fridgeMode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedFridgeModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-09T16:26:21.425Z"
|
||||
}
|
||||
},
|
||||
"samsungce.unavailableCapabilities": {
|
||||
"unavailableCommands": {
|
||||
"value": [],
|
||||
"timestamp": "2024-11-08T04:14:59.899Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["custom.fridgeMode"],
|
||||
"timestamp": "2024-10-12T13:55:04.008Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 37,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
}
|
||||
},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": 34,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": 44,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": {
|
||||
"minimum": 34,
|
||||
"maximum": 44,
|
||||
"step": 1
|
||||
},
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 37,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"freezer": {
|
||||
"custom.fridgeMode": {
|
||||
"fridgeModeValue": {
|
||||
"value": null
|
||||
},
|
||||
"fridgeMode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedFridgeModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-09T14:48:16.247Z"
|
||||
}
|
||||
},
|
||||
"samsungce.unavailableCapabilities": {
|
||||
"unavailableCommands": {
|
||||
"value": [],
|
||||
"timestamp": "2024-11-08T04:14:59.899Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["custom.fridgeMode", "samsungce.freezerConvertMode"],
|
||||
"timestamp": "2024-11-08T01:09:17.382Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 0,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-23T04:42:18.178Z"
|
||||
}
|
||||
},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": -8,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": 5,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
}
|
||||
},
|
||||
"samsungce.freezerConvertMode": {
|
||||
"supportedFreezerConvertModes": {
|
||||
"value": null
|
||||
},
|
||||
"freezerConvertMode": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": {
|
||||
"minimum": -8,
|
||||
"maximum": 5,
|
||||
"step": 1
|
||||
},
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 0,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-01-19T21:07:55.764Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": {
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-09T16:26:21.425Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dongleSoftwareInstallation": {
|
||||
"status": {
|
||||
"value": "completed",
|
||||
"timestamp": "2022-02-07T10:47:54.524Z"
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": null
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": null
|
||||
},
|
||||
"description": {
|
||||
"value": null
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": 20,
|
||||
"timestamp": "2024-11-08T01:09:17.382Z"
|
||||
},
|
||||
"binaryId": {
|
||||
"value": "TP2X_REF_20K",
|
||||
"timestamp": "2025-02-09T13:55:01.720Z"
|
||||
}
|
||||
},
|
||||
"samsungce.quickControl": {
|
||||
"version": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.fridgeMode": {
|
||||
"fridgeModeValue": {
|
||||
"value": null
|
||||
},
|
||||
"fridgeMode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedFridgeModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null
|
||||
},
|
||||
"mndt": {
|
||||
"value": null
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "A-RFWW-TP2-21-COMMON_20220110",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "MediaTek",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "7db87911-7dce-1cf2-7119-b953432a2f09",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "[refrigerator] Samsung",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "TP2X_REF_20K|00115641|0004014D011411200103000020000000",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-REF-NORMAL-000001",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "DAWIT 2.0",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "TizenRT 1.0 + IPv6",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "7db87911-7dce-1cf2-7119-b953432a2f09",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2024-12-21T22:04:22.037Z"
|
||||
}
|
||||
},
|
||||
"samsungce.fridgeVacationMode": {
|
||||
"vacationMode": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"temperatureMeasurement",
|
||||
"thermostatCoolingSetpoint",
|
||||
"custom.fridgeMode",
|
||||
"custom.deodorFilter",
|
||||
"samsungce.dongleSoftwareInstallation",
|
||||
"samsungce.quickControl",
|
||||
"samsungce.deviceInfoPrivate",
|
||||
"demandResponseLoadControl",
|
||||
"samsungce.fridgeVacationMode",
|
||||
"sec.diagnosticsInformation"
|
||||
],
|
||||
"timestamp": "2025-02-09T13:55:01.720Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 24100101,
|
||||
"timestamp": "2024-11-08T04:14:59.025Z"
|
||||
}
|
||||
},
|
||||
"sec.diagnosticsInformation": {
|
||||
"logType": {
|
||||
"value": null
|
||||
},
|
||||
"endpoint": {
|
||||
"value": null
|
||||
},
|
||||
"minVersion": {
|
||||
"value": null
|
||||
},
|
||||
"signinPermission": {
|
||||
"value": null
|
||||
},
|
||||
"setupId": {
|
||||
"value": null
|
||||
},
|
||||
"protocolType": {
|
||||
"value": null
|
||||
},
|
||||
"tsId": {
|
||||
"value": null
|
||||
},
|
||||
"mnId": {
|
||||
"value": null
|
||||
},
|
||||
"dumpType": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.deviceReportStateConfiguration": {
|
||||
"reportStateRealtimePeriod": {
|
||||
"value": null
|
||||
},
|
||||
"reportStateRealtime": {
|
||||
"value": {
|
||||
"state": "disabled"
|
||||
},
|
||||
"timestamp": "2025-01-19T21:07:55.703Z"
|
||||
},
|
||||
"reportStatePeriod": {
|
||||
"value": "enabled",
|
||||
"timestamp": "2025-01-19T21:07:55.703Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledComponents": {
|
||||
"disabledComponents": {
|
||||
"value": [
|
||||
"icemaker-02",
|
||||
"pantry-01",
|
||||
"pantry-02",
|
||||
"cvroom",
|
||||
"onedoor"
|
||||
],
|
||||
"timestamp": "2024-11-08T01:09:17.382Z"
|
||||
}
|
||||
},
|
||||
"demandResponseLoadControl": {
|
||||
"drlcStatus": {
|
||||
"value": {
|
||||
"drlcType": 1,
|
||||
"drlcLevel": 0,
|
||||
"duration": 0,
|
||||
"override": false
|
||||
},
|
||||
"timestamp": "2025-01-19T21:07:55.691Z"
|
||||
}
|
||||
},
|
||||
"samsungce.sabbathMode": {
|
||||
"supportedActions": {
|
||||
"value": ["on", "off"],
|
||||
"timestamp": "2025-01-19T21:07:55.799Z"
|
||||
},
|
||||
"status": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-01-19T21:07:55.799Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": {
|
||||
"energy": 1568087,
|
||||
"deltaEnergy": 7,
|
||||
"power": 6,
|
||||
"powerEnergy": 13.555977778169844,
|
||||
"persistedEnergy": 0,
|
||||
"energySaved": 0,
|
||||
"start": "2025-02-09T17:38:01Z",
|
||||
"end": "2025-02-09T17:49:00Z"
|
||||
},
|
||||
"timestamp": "2025-02-09T17:49:00.507Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["x.com.samsung.da.rm.micomdata"],
|
||||
"if": ["oic.if.baseline", "oic.if.a"],
|
||||
"x.com.samsung.rm.micomdata": "D0C0022B00000000000DFE15051F5AA54400000000000000000000000000000000000000000000000001F04A00C5E0",
|
||||
"x.com.samsung.rm.micomdataLength": 94
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/rm/micomdata/vs/0"
|
||||
},
|
||||
"timestamp": "2023-07-19T05:25:39.852Z"
|
||||
}
|
||||
},
|
||||
"refrigeration": {
|
||||
"defrost": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-01-19T21:07:55.772Z"
|
||||
},
|
||||
"rapidCooling": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-01-19T21:07:55.725Z"
|
||||
},
|
||||
"rapidFreezing": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-01-19T21:07:55.725Z"
|
||||
}
|
||||
},
|
||||
"custom.deodorFilter": {
|
||||
"deodorFilterCapacity": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterStatus": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterResetType": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterUsage": {
|
||||
"value": null
|
||||
},
|
||||
"deodorFilterUsageStep": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.powerCool": {
|
||||
"activated": {
|
||||
"value": false,
|
||||
"timestamp": "2025-01-19T21:07:55.725Z"
|
||||
}
|
||||
},
|
||||
"custom.energyType": {
|
||||
"energyType": {
|
||||
"value": "2.0",
|
||||
"timestamp": "2022-02-07T10:47:54.524Z"
|
||||
},
|
||||
"energySavingSupport": {
|
||||
"value": false,
|
||||
"timestamp": "2022-02-07T10:47:54.524Z"
|
||||
},
|
||||
"drMaxDuration": {
|
||||
"value": 1440,
|
||||
"unit": "min",
|
||||
"timestamp": "2022-02-07T11:39:47.504Z"
|
||||
},
|
||||
"energySavingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingInfo": {
|
||||
"value": null
|
||||
},
|
||||
"supportedEnergySavingLevels": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperation": {
|
||||
"value": null
|
||||
},
|
||||
"notificationTemplateID": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperationSupport": {
|
||||
"value": false,
|
||||
"timestamp": "2022-02-07T11:39:47.504Z"
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": {},
|
||||
"timestamp": "2025-01-19T21:07:55.725Z"
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": "P7CNQWBWM3XBW",
|
||||
"timestamp": "2025-01-19T21:07:55.744Z"
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": [],
|
||||
"timestamp": "2025-01-19T21:07:55.744Z"
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-01-19T21:07:55.725Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.powerFreeze": {
|
||||
"activated": {
|
||||
"value": false,
|
||||
"timestamp": "2025-01-19T21:07:55.725Z"
|
||||
}
|
||||
},
|
||||
"custom.waterFilter": {
|
||||
"waterFilterUsageStep": {
|
||||
"value": 1,
|
||||
"timestamp": "2025-01-19T21:07:55.758Z"
|
||||
},
|
||||
"waterFilterResetType": {
|
||||
"value": ["replaceable"],
|
||||
"timestamp": "2025-01-19T21:07:55.758Z"
|
||||
},
|
||||
"waterFilterCapacity": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterUsage": {
|
||||
"value": 100,
|
||||
"timestamp": "2025-02-09T04:02:12.910Z"
|
||||
},
|
||||
"waterFilterStatus": {
|
||||
"value": "replace",
|
||||
"timestamp": "2025-02-09T04:02:12.910Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cvroom": {
|
||||
"custom.fridgeMode": {
|
||||
"fridgeModeValue": {
|
||||
"value": null
|
||||
},
|
||||
"fridgeMode": {
|
||||
"value": null
|
||||
},
|
||||
"supportedFridgeModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["temperatureMeasurement", "thermostatCoolingSetpoint"],
|
||||
"timestamp": "2022-02-07T11:39:42.105Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"icemaker-02": {
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [],
|
||||
"timestamp": "2022-02-07T11:39:42.105Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,274 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"custom.disabledComponents": {
|
||||
"disabledComponents": {
|
||||
"value": ["station"],
|
||||
"timestamp": "2020-11-03T04:43:07.114Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": null,
|
||||
"timestamp": "2020-11-03T04:43:07.092Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"samsungce.robotCleanerOperatingState": {
|
||||
"supportedOperatingState": {
|
||||
"value": [
|
||||
"homing",
|
||||
"error",
|
||||
"idle",
|
||||
"charging",
|
||||
"chargingForRemainingJob",
|
||||
"paused",
|
||||
"cleaning"
|
||||
],
|
||||
"timestamp": "2020-11-03T04:43:06.547Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": "idle",
|
||||
"timestamp": "2023-06-18T15:59:24.580Z"
|
||||
},
|
||||
"cleaningStep": {
|
||||
"value": null
|
||||
},
|
||||
"homingReason": {
|
||||
"value": "none",
|
||||
"timestamp": "2020-11-03T04:43:22.926Z"
|
||||
},
|
||||
"isMapBasedOperationAvailable": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": null
|
||||
},
|
||||
"battery": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2022-09-09T22:55:13.962Z"
|
||||
},
|
||||
"type": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["x.com.samsung.da.alarms"],
|
||||
"if": ["oic.if.baseline", "oic.if.a"],
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.code": "4",
|
||||
"x.com.samsung.da.alarmType": "Device",
|
||||
"x.com.samsung.da.triggeredTime": "2023-06-18T15:59:30",
|
||||
"x.com.samsung.da.state": "deleted"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/alarms/vs/0"
|
||||
},
|
||||
"timestamp": "2023-06-18T15:59:28.267Z"
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": null
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": null
|
||||
},
|
||||
"description": {
|
||||
"value": null
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": null
|
||||
},
|
||||
"binaryId": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2023-06-18T15:59:27.658Z"
|
||||
}
|
||||
},
|
||||
"robotCleanerTurboMode": {
|
||||
"robotCleanerTurboMode": {
|
||||
"value": "off",
|
||||
"timestamp": "2022-09-08T02:53:49.826Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null,
|
||||
"timestamp": "2020-06-02T23:30:52.793Z"
|
||||
},
|
||||
"mndt": {
|
||||
"value": null,
|
||||
"timestamp": "2020-06-03T13:34:18.508Z"
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "1.0",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "3442dfc6-17c0-a65f-dae0-4c6e01786f44",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": null,
|
||||
"timestamp": "2020-06-03T00:49:53.813Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2021-12-23T07:09:40.610Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "[robot vacuum] Samsung",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "powerbot_7000_17M|50016055|80010404011141000100000000000000",
|
||||
"timestamp": "2022-09-07T06:42:36.551Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-RVC-NORMAL-000001",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "00",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "Tizen(3/0)",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "3442dfc6-17c0-a65f-dae0-4c6e01786f44",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2019-07-07T19:45:19.771Z"
|
||||
}
|
||||
},
|
||||
"samsungce.robotCleanerCleaningMode": {
|
||||
"supportedCleaningMode": {
|
||||
"value": ["auto", "spot", "manual", "stop"],
|
||||
"timestamp": "2020-11-03T04:43:06.547Z"
|
||||
},
|
||||
"repeatModeEnabled": {
|
||||
"value": false,
|
||||
"timestamp": "2020-12-21T01:32:56.245Z"
|
||||
},
|
||||
"supportRepeatMode": {
|
||||
"value": true,
|
||||
"timestamp": "2020-11-03T04:43:06.547Z"
|
||||
},
|
||||
"cleaningMode": {
|
||||
"value": "stop",
|
||||
"timestamp": "2022-09-09T21:25:20.601Z"
|
||||
}
|
||||
},
|
||||
"robotCleanerMovement": {
|
||||
"robotCleanerMovement": {
|
||||
"value": "idle",
|
||||
"timestamp": "2023-06-18T15:59:24.580Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"samsungce.robotCleanerMapAreaInfo",
|
||||
"samsungce.robotCleanerMapCleaningInfo",
|
||||
"samsungce.robotCleanerPatrol",
|
||||
"samsungce.robotCleanerPetMonitoring",
|
||||
"samsungce.robotCleanerPetMonitoringReport",
|
||||
"samsungce.robotCleanerPetCleaningSchedule",
|
||||
"soundDetection",
|
||||
"samsungce.soundDetectionSensitivity",
|
||||
"samsungce.musicPlaylist",
|
||||
"mediaPlayback",
|
||||
"mediaTrackControl",
|
||||
"imageCapture",
|
||||
"videoCapture",
|
||||
"audioVolume",
|
||||
"audioMute",
|
||||
"audioNotification",
|
||||
"powerConsumptionReport",
|
||||
"custom.hepaFilter",
|
||||
"samsungce.robotCleanerMotorFilter",
|
||||
"samsungce.robotCleanerRelayCleaning",
|
||||
"audioTrackAddressing",
|
||||
"samsungce.robotCleanerWelcome"
|
||||
],
|
||||
"timestamp": "2022-09-08T01:03:48.820Z"
|
||||
}
|
||||
},
|
||||
"robotCleanerCleaningMode": {
|
||||
"robotCleanerCleaningMode": {
|
||||
"value": "stop",
|
||||
"timestamp": "2022-09-09T21:25:20.601Z"
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": null
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": null
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": null
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": null
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 22100101,
|
||||
"timestamp": "2022-11-01T09:26:07.107Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,786 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"samsungce.dishwasherWashingCourse": {
|
||||
"customCourseCandidates": {
|
||||
"value": null
|
||||
},
|
||||
"washingCourse": {
|
||||
"value": "normal",
|
||||
"timestamp": "2025-02-08T20:21:26.497Z"
|
||||
},
|
||||
"supportedCourses": {
|
||||
"value": [
|
||||
"auto",
|
||||
"normal",
|
||||
"heavy",
|
||||
"delicate",
|
||||
"express",
|
||||
"rinseOnly",
|
||||
"selfClean"
|
||||
],
|
||||
"timestamp": "2025-02-08T18:00:37.194Z"
|
||||
}
|
||||
},
|
||||
"dishwasherOperatingState": {
|
||||
"completionTime": {
|
||||
"value": "2025-02-08T22:49:26Z",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
},
|
||||
"machineState": {
|
||||
"value": "stop",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
},
|
||||
"supportedMachineStates": {
|
||||
"value": ["stop", "run", "pause"],
|
||||
"timestamp": "2024-09-10T10:21:02.853Z"
|
||||
},
|
||||
"dishwasherJobState": {
|
||||
"value": "unknown",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dishwasherWashingOptions": {
|
||||
"dryPlus": {
|
||||
"value": null
|
||||
},
|
||||
"stormWash": {
|
||||
"value": null
|
||||
},
|
||||
"hotAirDry": {
|
||||
"value": null
|
||||
},
|
||||
"selectedZone": {
|
||||
"value": {
|
||||
"value": "all",
|
||||
"settable": ["none", "upper", "lower", "all"]
|
||||
},
|
||||
"timestamp": "2022-11-09T00:20:42.461Z"
|
||||
},
|
||||
"speedBooster": {
|
||||
"value": {
|
||||
"value": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"timestamp": "2023-11-24T14:46:55.375Z"
|
||||
},
|
||||
"highTempWash": {
|
||||
"value": {
|
||||
"value": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"timestamp": "2025-02-08T07:39:54.739Z"
|
||||
},
|
||||
"sanitizingWash": {
|
||||
"value": null
|
||||
},
|
||||
"heatedDry": {
|
||||
"value": null
|
||||
},
|
||||
"zoneBooster": {
|
||||
"value": {
|
||||
"value": "none",
|
||||
"settable": ["none", "left", "right", "all"]
|
||||
},
|
||||
"timestamp": "2022-11-20T07:10:27.445Z"
|
||||
},
|
||||
"addRinse": {
|
||||
"value": null
|
||||
},
|
||||
"supportedList": {
|
||||
"value": [
|
||||
"selectedZone",
|
||||
"zoneBooster",
|
||||
"speedBooster",
|
||||
"sanitize",
|
||||
"highTempWash"
|
||||
],
|
||||
"timestamp": "2021-06-27T01:19:38.000Z"
|
||||
},
|
||||
"rinsePlus": {
|
||||
"value": null
|
||||
},
|
||||
"sanitize": {
|
||||
"value": {
|
||||
"value": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"timestamp": "2025-01-18T23:49:09.964Z"
|
||||
},
|
||||
"steamSoak": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": null
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": null
|
||||
},
|
||||
"description": {
|
||||
"value": null
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": null
|
||||
},
|
||||
"binaryId": {
|
||||
"value": "DA_DW_A51_20_COMMON",
|
||||
"timestamp": "2025-02-08T19:29:30.987Z"
|
||||
}
|
||||
},
|
||||
"custom.dishwasherOperatingProgress": {
|
||||
"dishwasherOperatingProgress": {
|
||||
"value": "none",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T20:21:26.386Z"
|
||||
}
|
||||
},
|
||||
"samsungce.quickControl": {
|
||||
"version": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.waterConsumptionReport": {
|
||||
"waterConsumption": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null
|
||||
},
|
||||
"mndt": {
|
||||
"value": null
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "DA_DW_A51_20_COMMON_30230714",
|
||||
"timestamp": "2023-11-02T15:58:55.699Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "ARTIK051",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "f36dc7ce-cac0-0667-dc14-a3704eb5e676",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2024-07-04T13:53:32.032Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "[dishwasher] Samsung",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "DA_DW_A51_20_COMMON|30007242|40010201001311000101000000000000",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-WM-DW-000001",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "DAWIT 2.0",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "TizenRT 1.0 + IPv6",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "f36dc7ce-cac0-0667-dc14-a3704eb5e676",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2021-06-27T01:19:37.615Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"samsungce.waterConsumptionReport",
|
||||
"sec.wifiConfiguration",
|
||||
"samsungce.quickControl",
|
||||
"samsungce.deviceInfoPrivate",
|
||||
"demandResponseLoadControl",
|
||||
"sec.diagnosticsInformation",
|
||||
"custom.waterFilter"
|
||||
],
|
||||
"timestamp": "2025-02-08T19:29:32.447Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 24040105,
|
||||
"timestamp": "2024-07-02T02:56:22.508Z"
|
||||
}
|
||||
},
|
||||
"sec.diagnosticsInformation": {
|
||||
"logType": {
|
||||
"value": null
|
||||
},
|
||||
"endpoint": {
|
||||
"value": null
|
||||
},
|
||||
"minVersion": {
|
||||
"value": null
|
||||
},
|
||||
"signinPermission": {
|
||||
"value": null
|
||||
},
|
||||
"setupId": {
|
||||
"value": null
|
||||
},
|
||||
"protocolType": {
|
||||
"value": null
|
||||
},
|
||||
"tsId": {
|
||||
"value": null
|
||||
},
|
||||
"mnId": {
|
||||
"value": null
|
||||
},
|
||||
"dumpType": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.dishwasherOperation": {
|
||||
"supportedOperatingState": {
|
||||
"value": ["ready", "running", "paused"],
|
||||
"timestamp": "2024-09-10T10:21:02.853Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
},
|
||||
"reservable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-08T18:00:37.194Z"
|
||||
},
|
||||
"progressPercentage": {
|
||||
"value": 1,
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
},
|
||||
"remainingTimeStr": {
|
||||
"value": "02:28",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
},
|
||||
"operationTime": {
|
||||
"value": null
|
||||
},
|
||||
"remainingTime": {
|
||||
"value": 148.0,
|
||||
"unit": "min",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
},
|
||||
"timeLeftToStart": {
|
||||
"value": 0.0,
|
||||
"unit": "min",
|
||||
"timestamp": "2025-02-08T18:00:37.482Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dishwasherJobState": {
|
||||
"scheduledJobs": {
|
||||
"value": [
|
||||
{
|
||||
"jobName": "washing",
|
||||
"timeInSec": 3600
|
||||
},
|
||||
{
|
||||
"jobName": "rinsing",
|
||||
"timeInSec": 1020
|
||||
},
|
||||
{
|
||||
"jobName": "drying",
|
||||
"timeInSec": 1200
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-02-08T20:21:26.928Z"
|
||||
},
|
||||
"dishwasherJobState": {
|
||||
"value": "none",
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
}
|
||||
},
|
||||
"samsungce.kidsLock": {
|
||||
"lockState": {
|
||||
"value": "unlocked",
|
||||
"timestamp": "2025-02-08T18:00:37.450Z"
|
||||
}
|
||||
},
|
||||
"demandResponseLoadControl": {
|
||||
"drlcStatus": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": {
|
||||
"energy": 101600,
|
||||
"deltaEnergy": 0,
|
||||
"power": 0,
|
||||
"powerEnergy": 0.0,
|
||||
"persistedEnergy": 0,
|
||||
"energySaved": 0,
|
||||
"persistedSavedEnergy": 0,
|
||||
"start": "2025-02-08T20:21:21Z",
|
||||
"end": "2025-02-08T20:21:26Z"
|
||||
},
|
||||
"timestamp": "2025-02-08T20:21:26.596Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"samsungce.dishwasherWashingCourseDetails": {
|
||||
"predefinedCourses": {
|
||||
"value": [
|
||||
{
|
||||
"courseName": "auto",
|
||||
"energyUsage": 3,
|
||||
"waterUsage": 3,
|
||||
"temperature": {
|
||||
"min": 50,
|
||||
"max": 60,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 136,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": ["none", "left"]
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "lower", "all"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"courseName": "normal",
|
||||
"energyUsage": 3,
|
||||
"waterUsage": 4,
|
||||
"temperature": {
|
||||
"min": 45,
|
||||
"max": 62,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 148,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": ["none", "left"]
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "lower", "all"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"courseName": "heavy",
|
||||
"energyUsage": 4,
|
||||
"waterUsage": 5,
|
||||
"temperature": {
|
||||
"min": 65,
|
||||
"max": 65,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 155,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": ["none", "left"]
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "lower", "all"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"courseName": "delicate",
|
||||
"energyUsage": 2,
|
||||
"waterUsage": 3,
|
||||
"temperature": {
|
||||
"min": 50,
|
||||
"max": 50,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 112,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": []
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "lower", "all"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"courseName": "express",
|
||||
"energyUsage": 2,
|
||||
"waterUsage": 2,
|
||||
"temperature": {
|
||||
"min": 52,
|
||||
"max": 52,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 60,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": [false, true]
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": ["none", "left"]
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "lower", "all"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"courseName": "rinseOnly",
|
||||
"energyUsage": 1,
|
||||
"waterUsage": 1,
|
||||
"temperature": {
|
||||
"min": 40,
|
||||
"max": 40,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 14,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": []
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "lower", "all"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"courseName": "selfClean",
|
||||
"energyUsage": 5,
|
||||
"waterUsage": 4,
|
||||
"temperature": {
|
||||
"min": 70,
|
||||
"max": 70,
|
||||
"unit": "C"
|
||||
},
|
||||
"expectedTime": {
|
||||
"time": 139,
|
||||
"unit": "min"
|
||||
},
|
||||
"options": {
|
||||
"highTempWash": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"sanitize": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"speedBooster": {
|
||||
"default": false,
|
||||
"settable": []
|
||||
},
|
||||
"zoneBooster": {
|
||||
"default": "none",
|
||||
"settable": []
|
||||
},
|
||||
"selectedZone": {
|
||||
"default": "all",
|
||||
"settable": ["none", "all"]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-02-08T18:00:37.194Z"
|
||||
},
|
||||
"waterUsageMax": {
|
||||
"value": 5,
|
||||
"timestamp": "2025-02-08T18:00:37.194Z"
|
||||
},
|
||||
"energyUsageMax": {
|
||||
"value": 5,
|
||||
"timestamp": "2025-02-08T18:00:37.194Z"
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["oic.r.operational.state"],
|
||||
"if": ["oic.if.baseline", "oic.if.a"],
|
||||
"currentMachineState": "idle",
|
||||
"machineStates": ["pause", "active", "idle"],
|
||||
"jobStates": [
|
||||
"None",
|
||||
"Predrain",
|
||||
"Prewash",
|
||||
"Wash",
|
||||
"Rinse",
|
||||
"Drying",
|
||||
"Finish"
|
||||
],
|
||||
"currentJobState": "None",
|
||||
"remainingTime": "02:16:00",
|
||||
"progressPercentage": "1"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/operational/state/0"
|
||||
},
|
||||
"timestamp": "2023-07-19T04:23:15.606Z"
|
||||
}
|
||||
},
|
||||
"sec.wifiConfiguration": {
|
||||
"autoReconnection": {
|
||||
"value": null
|
||||
},
|
||||
"minVersion": {
|
||||
"value": null
|
||||
},
|
||||
"supportedWiFiFreq": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAuthType": {
|
||||
"value": null
|
||||
},
|
||||
"protocolType": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.dishwasherOperatingPercentage": {
|
||||
"dishwasherOperatingPercentage": {
|
||||
"value": 1,
|
||||
"timestamp": "2025-02-08T20:21:26.452Z"
|
||||
}
|
||||
},
|
||||
"remoteControlStatus": {
|
||||
"remoteControlEnabled": {
|
||||
"value": "false",
|
||||
"timestamp": "2025-02-08T18:00:37.555Z"
|
||||
}
|
||||
},
|
||||
"custom.supportedOptions": {
|
||||
"course": {
|
||||
"value": null
|
||||
},
|
||||
"referenceTable": {
|
||||
"value": null
|
||||
},
|
||||
"supportedCourses": {
|
||||
"value": ["82", "83", "84", "85", "86", "87", "88"],
|
||||
"timestamp": "2025-02-08T18:00:37.194Z"
|
||||
}
|
||||
},
|
||||
"custom.dishwasherDelayStartTime": {
|
||||
"dishwasherDelayStartTime": {
|
||||
"value": "00:00:00",
|
||||
"timestamp": "2025-02-08T18:00:37.482Z"
|
||||
}
|
||||
},
|
||||
"custom.energyType": {
|
||||
"energyType": {
|
||||
"value": "2.0",
|
||||
"timestamp": "2023-08-25T03:23:06.667Z"
|
||||
},
|
||||
"energySavingSupport": {
|
||||
"value": true,
|
||||
"timestamp": "2024-10-01T00:08:09.813Z"
|
||||
},
|
||||
"drMaxDuration": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingInfo": {
|
||||
"value": null
|
||||
},
|
||||
"supportedEnergySavingLevels": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperation": {
|
||||
"value": null
|
||||
},
|
||||
"notificationTemplateID": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperationSupport": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": null
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": "MTCNQWBWIV6TS",
|
||||
"timestamp": "2025-02-08T18:00:37.538Z"
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": [],
|
||||
"timestamp": "2022-07-20T03:37:30.706Z"
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-08T18:00:37.538Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.waterFilter": {
|
||||
"waterFilterUsageStep": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterResetType": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterCapacity": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterLastResetDate": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterUsage": {
|
||||
"value": null
|
||||
},
|
||||
"waterFilterStatus": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,719 @@
|
||||
{
|
||||
"components": {
|
||||
"hca.main": {
|
||||
"hca.dryerMode": {
|
||||
"mode": {
|
||||
"value": "normal",
|
||||
"timestamp": "2025-02-08T18:10:11.023Z"
|
||||
},
|
||||
"supportedModes": {
|
||||
"value": ["normal", "timeDry", "quickDry"],
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": {
|
||||
"custom.dryerWrinklePrevent": {
|
||||
"operatingState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
},
|
||||
"dryerWrinklePrevent": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T18:10:10.840Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dryerDryingTemperature": {
|
||||
"dryingTemperature": {
|
||||
"value": "medium",
|
||||
"timestamp": "2025-02-08T18:10:10.840Z"
|
||||
},
|
||||
"supportedDryingTemperature": {
|
||||
"value": ["none", "extraLow", "low", "mediumLow", "medium", "high"],
|
||||
"timestamp": "2025-01-04T22:52:14.884Z"
|
||||
}
|
||||
},
|
||||
"samsungce.welcomeMessage": {
|
||||
"welcomeMessage": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.dongleSoftwareInstallation": {
|
||||
"status": {
|
||||
"value": "completed",
|
||||
"timestamp": "2022-06-14T06:49:02.183Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dryerCyclePreset": {
|
||||
"maxNumberOfPresets": {
|
||||
"value": 10,
|
||||
"timestamp": "2025-02-08T18:10:10.990Z"
|
||||
},
|
||||
"presets": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.deviceIdentification": {
|
||||
"micomAssayCode": {
|
||||
"value": "20233741",
|
||||
"timestamp": "2025-02-08T18:10:11.113Z"
|
||||
},
|
||||
"modelName": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumber": {
|
||||
"value": null
|
||||
},
|
||||
"serialNumberExtra": {
|
||||
"value": null
|
||||
},
|
||||
"modelClassificationCode": {
|
||||
"value": "3000000100111100020B000000000000",
|
||||
"timestamp": "2025-02-08T18:10:11.113Z"
|
||||
},
|
||||
"description": {
|
||||
"value": "DA_WM_A51_20_COMMON_DV6300R/DC92-02385A_0090",
|
||||
"timestamp": "2025-02-08T18:10:11.113Z"
|
||||
},
|
||||
"releaseYear": {
|
||||
"value": null
|
||||
},
|
||||
"binaryId": {
|
||||
"value": "DA_WM_A51_20_COMMON",
|
||||
"timestamp": "2025-02-08T18:10:11.113Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T18:10:10.911Z"
|
||||
}
|
||||
},
|
||||
"samsungce.quickControl": {
|
||||
"version": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.dryerFreezePrevent": {
|
||||
"operatingState": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null
|
||||
},
|
||||
"mndt": {
|
||||
"value": null
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "DA_WM_A51_20_COMMON_30230708",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "ARTIK051",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "02f7256e-8353-5bdd-547f-bd5b1647e01b",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "[dryer] Samsung",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "DA_WM_A51_20_COMMON|20233741|3000000100111100020B000000000000",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-WM-WD-000001",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "DAWIT 2.0",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "TizenRT 1.0 + IPv6",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "02f7256e-8353-5bdd-547f-bd5b1647e01b",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2025-01-04T22:52:14.222Z"
|
||||
}
|
||||
},
|
||||
"custom.dryerDryLevel": {
|
||||
"dryerDryLevel": {
|
||||
"value": "normal",
|
||||
"timestamp": "2025-02-08T18:10:10.840Z"
|
||||
},
|
||||
"supportedDryerDryLevel": {
|
||||
"value": ["none", "damp", "less", "normal", "more", "very"],
|
||||
"timestamp": "2021-06-01T22:54:28.224Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dryerAutoCycleLink": {
|
||||
"dryerAutoCycleLink": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-08T18:10:11.986Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dryerCycle": {
|
||||
"dryerCycle": {
|
||||
"value": "Table_00_Course_01",
|
||||
"timestamp": "2025-02-08T18:10:11.023Z"
|
||||
},
|
||||
"supportedCycles": {
|
||||
"value": [
|
||||
{
|
||||
"cycle": "01",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D33E",
|
||||
"default": "normal",
|
||||
"options": ["damp", "less", "normal", "more", "very"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8410",
|
||||
"default": "medium",
|
||||
"options": ["medium"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "9C",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D33E",
|
||||
"default": "normal",
|
||||
"options": ["damp", "less", "normal", "more", "very"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8520",
|
||||
"default": "high",
|
||||
"options": ["high"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "A5",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D33E",
|
||||
"default": "normal",
|
||||
"options": ["damp", "less", "normal", "more", "very"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8520",
|
||||
"default": "high",
|
||||
"options": ["high"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "9E",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D33E",
|
||||
"default": "normal",
|
||||
"options": ["damp", "less", "normal", "more", "very"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8308",
|
||||
"default": "mediumLow",
|
||||
"options": ["mediumLow"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "9B",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D520",
|
||||
"default": "very",
|
||||
"options": ["very"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8520",
|
||||
"default": "high",
|
||||
"options": ["high"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "27",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8520",
|
||||
"default": "high",
|
||||
"options": ["high"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "E5",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "A0",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "A4",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "853E",
|
||||
"default": "high",
|
||||
"options": ["extraLow", "low", "mediumLow", "medium", "high"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "A6",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D000",
|
||||
"default": "none",
|
||||
"options": []
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8520",
|
||||
"default": "high",
|
||||
"options": ["high"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "A3",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D308",
|
||||
"default": "normal",
|
||||
"options": ["normal"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8410",
|
||||
"default": "medium",
|
||||
"options": ["medium"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cycle": "A2",
|
||||
"supportedOptions": {
|
||||
"dryingLevel": {
|
||||
"raw": "D33E",
|
||||
"default": "normal",
|
||||
"options": ["damp", "less", "normal", "more", "very"]
|
||||
},
|
||||
"dryingTemperature": {
|
||||
"raw": "8102",
|
||||
"default": "extraLow",
|
||||
"options": ["extraLow"]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-01-04T22:52:14.884Z"
|
||||
},
|
||||
"referenceTable": {
|
||||
"value": {
|
||||
"id": "Table_00"
|
||||
},
|
||||
"timestamp": "2025-02-08T18:10:11.023Z"
|
||||
},
|
||||
"specializedFunctionClassification": {
|
||||
"value": 4,
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": [
|
||||
"samsungce.dryerCyclePreset",
|
||||
"samsungce.welcomeMessage",
|
||||
"samsungce.dongleSoftwareInstallation",
|
||||
"sec.wifiConfiguration",
|
||||
"samsungce.quickControl",
|
||||
"samsungce.deviceInfoPrivate",
|
||||
"demandResponseLoadControl",
|
||||
"samsungce.dryerFreezePrevent",
|
||||
"sec.diagnosticsInformation"
|
||||
],
|
||||
"timestamp": "2024-07-05T16:04:06.674Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 24110101,
|
||||
"timestamp": "2024-12-03T02:59:11.115Z"
|
||||
}
|
||||
},
|
||||
"sec.diagnosticsInformation": {
|
||||
"logType": {
|
||||
"value": null
|
||||
},
|
||||
"endpoint": {
|
||||
"value": null
|
||||
},
|
||||
"minVersion": {
|
||||
"value": null
|
||||
},
|
||||
"signinPermission": {
|
||||
"value": null
|
||||
},
|
||||
"setupId": {
|
||||
"value": null
|
||||
},
|
||||
"protocolType": {
|
||||
"value": null
|
||||
},
|
||||
"tsId": {
|
||||
"value": null
|
||||
},
|
||||
"mnId": {
|
||||
"value": null
|
||||
},
|
||||
"dumpType": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.kidsLock": {
|
||||
"lockState": {
|
||||
"value": "unlocked",
|
||||
"timestamp": "2025-02-08T18:10:10.825Z"
|
||||
}
|
||||
},
|
||||
"demandResponseLoadControl": {
|
||||
"drlcStatus": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.detergentOrder": {
|
||||
"alarmEnabled": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
},
|
||||
"orderThreshold": {
|
||||
"value": 0,
|
||||
"unit": "cc",
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": {
|
||||
"energy": 4495500,
|
||||
"deltaEnergy": 0,
|
||||
"power": 0,
|
||||
"powerEnergy": 0.0,
|
||||
"persistedEnergy": 0,
|
||||
"energySaved": 0,
|
||||
"start": "2025-02-07T04:00:19Z",
|
||||
"end": "2025-02-08T18:10:11Z"
|
||||
},
|
||||
"timestamp": "2025-02-08T18:10:11.053Z"
|
||||
}
|
||||
},
|
||||
"dryerOperatingState": {
|
||||
"completionTime": {
|
||||
"value": "2025-02-08T19:25:10Z",
|
||||
"timestamp": "2025-02-08T18:10:10.962Z"
|
||||
},
|
||||
"machineState": {
|
||||
"value": "stop",
|
||||
"timestamp": "2025-02-08T18:10:10.962Z"
|
||||
},
|
||||
"supportedMachineStates": {
|
||||
"value": ["stop", "run", "pause"],
|
||||
"timestamp": "2025-02-08T18:10:10.962Z"
|
||||
},
|
||||
"dryerJobState": {
|
||||
"value": "none",
|
||||
"timestamp": "2025-02-08T18:10:10.962Z"
|
||||
}
|
||||
},
|
||||
"samsungce.detergentState": {
|
||||
"remainingAmount": {
|
||||
"value": 0,
|
||||
"unit": "cc",
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
},
|
||||
"dosage": {
|
||||
"value": 0,
|
||||
"unit": "cc",
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
},
|
||||
"initialAmount": {
|
||||
"value": 0,
|
||||
"unit": "cc",
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
},
|
||||
"detergentType": {
|
||||
"value": "none",
|
||||
"timestamp": "2021-06-01T22:54:28.372Z"
|
||||
}
|
||||
},
|
||||
"samsungce.dryerDelayEnd": {
|
||||
"remainingTime": {
|
||||
"value": 0,
|
||||
"unit": "min",
|
||||
"timestamp": "2025-02-08T18:10:10.962Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"custom.jobBeginningStatus": {
|
||||
"jobBeginningStatus": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["x.com.samsung.da.information"],
|
||||
"if": ["oic.if.baseline", "oic.if.a"],
|
||||
"x.com.samsung.da.modelNum": "DA_WM_A51_20_COMMON|20233741|3000000100111100020B000000000000",
|
||||
"x.com.samsung.da.description": "DA_WM_A51_20_COMMON_DV6300R/DC92-02385A_0090",
|
||||
"x.com.samsung.da.serialNum": "FFFFFFFFFFFFFFF",
|
||||
"x.com.samsung.da.otnDUID": "7XCDM6YAIRCGM",
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "0",
|
||||
"x.com.samsung.da.description": "DA_WM_A51_20_COMMON|20233741|3000000100111100020B000000000000",
|
||||
"x.com.samsung.da.type": "Software",
|
||||
"x.com.samsung.da.number": "02198A220728(E256)",
|
||||
"x.com.samsung.da.newVersionAvailable": "0"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "1",
|
||||
"x.com.samsung.da.description": "DA_WM_A51_20_COMMON",
|
||||
"x.com.samsung.da.type": "Firmware",
|
||||
"x.com.samsung.da.number": "18112816,20112625",
|
||||
"x.com.samsung.da.newVersionAvailable": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/information/vs/0"
|
||||
},
|
||||
"timestamp": "2023-08-06T22:48:43.192Z"
|
||||
}
|
||||
},
|
||||
"sec.wifiConfiguration": {
|
||||
"autoReconnection": {
|
||||
"value": null
|
||||
},
|
||||
"minVersion": {
|
||||
"value": null
|
||||
},
|
||||
"supportedWiFiFreq": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAuthType": {
|
||||
"value": null
|
||||
},
|
||||
"protocolType": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"remoteControlStatus": {
|
||||
"remoteControlEnabled": {
|
||||
"value": "false",
|
||||
"timestamp": "2025-02-08T18:10:10.970Z"
|
||||
}
|
||||
},
|
||||
"custom.supportedOptions": {
|
||||
"course": {
|
||||
"value": null
|
||||
},
|
||||
"referenceTable": {
|
||||
"value": {
|
||||
"id": "Table_00"
|
||||
},
|
||||
"timestamp": "2025-02-08T18:10:11.023Z"
|
||||
},
|
||||
"supportedCourses": {
|
||||
"value": [
|
||||
"01",
|
||||
"9C",
|
||||
"A5",
|
||||
"9E",
|
||||
"9B",
|
||||
"27",
|
||||
"E5",
|
||||
"A0",
|
||||
"A4",
|
||||
"A6",
|
||||
"A3",
|
||||
"A2"
|
||||
],
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
}
|
||||
},
|
||||
"custom.energyType": {
|
||||
"energyType": {
|
||||
"value": "2.0",
|
||||
"timestamp": "2022-06-14T06:49:02.183Z"
|
||||
},
|
||||
"energySavingSupport": {
|
||||
"value": false,
|
||||
"timestamp": "2022-06-14T06:49:02.721Z"
|
||||
},
|
||||
"drMaxDuration": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingLevel": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingInfo": {
|
||||
"value": null
|
||||
},
|
||||
"supportedEnergySavingLevels": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperation": {
|
||||
"value": null
|
||||
},
|
||||
"notificationTemplateID": {
|
||||
"value": null
|
||||
},
|
||||
"energySavingOperationSupport": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.dryerOperatingState": {
|
||||
"operatingState": {
|
||||
"value": "ready",
|
||||
"timestamp": "2025-02-07T04:00:18.186Z"
|
||||
},
|
||||
"supportedOperatingStates": {
|
||||
"value": ["ready", "running", "paused"],
|
||||
"timestamp": "2022-11-01T13:43:26.961Z"
|
||||
},
|
||||
"scheduledJobs": {
|
||||
"value": [
|
||||
{
|
||||
"jobName": "drying",
|
||||
"timeInMin": 57
|
||||
},
|
||||
{
|
||||
"jobName": "cooling",
|
||||
"timeInMin": 3
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-02-08T18:10:10.497Z"
|
||||
},
|
||||
"progress": {
|
||||
"value": 1,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T04:00:18.186Z"
|
||||
},
|
||||
"remainingTimeStr": {
|
||||
"value": "01:15",
|
||||
"timestamp": "2025-02-07T04:00:18.186Z"
|
||||
},
|
||||
"dryerJobState": {
|
||||
"value": "none",
|
||||
"timestamp": "2025-02-07T04:00:18.186Z"
|
||||
},
|
||||
"remainingTime": {
|
||||
"value": 75,
|
||||
"unit": "min",
|
||||
"timestamp": "2025-02-07T04:00:18.186Z"
|
||||
}
|
||||
},
|
||||
"samsungce.softwareUpdate": {
|
||||
"targetModule": {
|
||||
"value": null
|
||||
},
|
||||
"otnDUID": {
|
||||
"value": "7XCDM6YAIRCGM",
|
||||
"timestamp": "2025-02-08T18:10:11.113Z"
|
||||
},
|
||||
"lastUpdatedDate": {
|
||||
"value": null
|
||||
},
|
||||
"availableModules": {
|
||||
"value": [],
|
||||
"timestamp": "2024-12-02T00:29:53.432Z"
|
||||
},
|
||||
"newVersionAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2024-12-02T00:29:53.432Z"
|
||||
},
|
||||
"operatingState": {
|
||||
"value": null
|
||||
},
|
||||
"progress": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.dryerDryingTime": {
|
||||
"supportedDryingTime": {
|
||||
"value": ["0", "20", "30", "40", "50", "60"],
|
||||
"timestamp": "2021-06-01T22:54:28.224Z"
|
||||
},
|
||||
"dryingTime": {
|
||||
"value": "0",
|
||||
"unit": "min",
|
||||
"timestamp": "2025-02-08T18:10:10.840Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,51 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"presenceSensor": {
|
||||
"presence": {
|
||||
"value": "not present",
|
||||
"timestamp": "2025-02-11T13:58:50.044Z"
|
||||
}
|
||||
},
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2025-01-16T21:14:07.471Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "online",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-11T14:23:22.053Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 71,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-11T14:36:16.823Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"motionSensor": {
|
||||
"motion": {
|
||||
"value": "inactive",
|
||||
"timestamp": "2025-02-11T13:58:50.044Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"relativeHumidityMeasurement": {
|
||||
"humidity": {
|
||||
"value": 32,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-11T14:36:17.275Z"
|
||||
}
|
||||
},
|
||||
"thermostatOperatingState": {
|
||||
"thermostatOperatingState": {
|
||||
"value": "heating",
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
}
|
||||
},
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2025-01-16T21:14:07.448Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "online",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 71,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-11T14:23:21.556Z"
|
||||
}
|
||||
},
|
||||
"thermostatHeatingSetpoint": {
|
||||
"heatingSetpoint": {
|
||||
"value": 71,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
},
|
||||
"heatingSetpointRange": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"thermostatFanMode": {
|
||||
"thermostatFanMode": {
|
||||
"value": "auto",
|
||||
"data": {
|
||||
"supportedThermostatFanModes": ["on", "auto"]
|
||||
},
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
},
|
||||
"supportedThermostatFanModes": {
|
||||
"value": ["on", "auto"],
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"thermostatMode": {
|
||||
"thermostatMode": {
|
||||
"value": "heat",
|
||||
"data": {
|
||||
"supportedThermostatModes": ["off", "cool", "auxheatonly", "auto"]
|
||||
},
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
},
|
||||
"supportedThermostatModes": {
|
||||
"value": ["off", "cool", "auxheatonly", "auto"],
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 73,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-11T13:39:58.286Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T23:21:22.908Z"
|
||||
}
|
||||
},
|
||||
"fanSpeed": {
|
||||
"fanSpeed": {
|
||||
"value": 60,
|
||||
"timestamp": "2025-02-10T21:09:08.357Z"
|
||||
}
|
||||
},
|
||||
"airConditionerFanMode": {
|
||||
"fanMode": {
|
||||
"value": null,
|
||||
"timestamp": "2021-04-06T16:44:10.381Z"
|
||||
},
|
||||
"supportedAcFanModes": {
|
||||
"value": ["auto", "low", "medium", "high", "turbo"],
|
||||
"timestamp": "2024-09-10T10:26:28.605Z"
|
||||
},
|
||||
"availableAcFanModes": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"switchLevel": {
|
||||
"levelRange": {
|
||||
"value": null
|
||||
},
|
||||
"level": {
|
||||
"value": 39,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T02:39:25.819Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T23:21:22.908Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2023-12-17T18:11:41.671Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "online",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-07T15:14:53.823Z"
|
||||
}
|
||||
},
|
||||
"switchLevel": {
|
||||
"levelRange": {
|
||||
"value": {
|
||||
"minimum": 1,
|
||||
"maximum": 100
|
||||
},
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T15:14:53.823Z"
|
||||
},
|
||||
"level": {
|
||||
"value": 70,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T21:56:04.127Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"synthetic.lightingEffectFade": {
|
||||
"fade": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"colorTemperature": {
|
||||
"colorTemperatureRange": {
|
||||
"value": {
|
||||
"minimum": 2000,
|
||||
"maximum": 6535
|
||||
},
|
||||
"unit": "K",
|
||||
"timestamp": "2025-02-07T15:14:53.823Z"
|
||||
},
|
||||
"colorTemperature": {
|
||||
"value": 3000,
|
||||
"unit": "K",
|
||||
"timestamp": "2025-02-07T21:56:04.127Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-07T21:56:04.127Z"
|
||||
}
|
||||
},
|
||||
"synthetic.lightingEffectCircadian": {
|
||||
"circadian": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"colorControl": {
|
||||
"saturation": {
|
||||
"value": 60,
|
||||
"timestamp": "2025-02-07T15:14:53.812Z"
|
||||
},
|
||||
"color": {
|
||||
"value": null
|
||||
},
|
||||
"hue": {
|
||||
"value": 60.8072,
|
||||
"timestamp": "2025-02-07T15:14:53.812Z"
|
||||
}
|
||||
},
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2023-12-17T18:11:41.678Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "online",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-07T15:14:53.812Z"
|
||||
}
|
||||
},
|
||||
"switchLevel": {
|
||||
"levelRange": {
|
||||
"value": {
|
||||
"minimum": 1,
|
||||
"maximum": 100
|
||||
},
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T15:14:53.812Z"
|
||||
},
|
||||
"level": {
|
||||
"value": 70,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T21:56:02.381Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"synthetic.lightingEffectFade": {
|
||||
"fade": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungim.hueSyncMode": {
|
||||
"mode": {
|
||||
"value": "normal",
|
||||
"timestamp": "2025-02-07T15:14:53.812Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-08T07:08:19.519Z"
|
||||
}
|
||||
},
|
||||
"colorTemperature": {
|
||||
"colorTemperatureRange": {
|
||||
"value": {
|
||||
"minimum": 2000,
|
||||
"maximum": 6535
|
||||
},
|
||||
"unit": "K",
|
||||
"timestamp": "2025-02-06T15:14:52.807Z"
|
||||
},
|
||||
"colorTemperature": {
|
||||
"value": 3000,
|
||||
"unit": "K",
|
||||
"timestamp": "2025-02-07T21:56:02.381Z"
|
||||
}
|
||||
},
|
||||
"synthetic.lightingEffectCircadian": {
|
||||
"circadian": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"presenceSensor": {
|
||||
"presence": {
|
||||
"value": "present",
|
||||
"timestamp": "2023-09-22T18:12:25.012Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"contactSensor": {
|
||||
"contact": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-08T14:00:28.332Z"
|
||||
}
|
||||
},
|
||||
"threeAxis": {
|
||||
"threeAxis": {
|
||||
"value": [20, 8, -1042],
|
||||
"unit": "mG",
|
||||
"timestamp": "2025-02-09T17:27:36.673Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 67.0,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-09T17:56:19.744Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": null
|
||||
},
|
||||
"battery": {
|
||||
"value": 50,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T12:24:02.074Z"
|
||||
},
|
||||
"type": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"firmwareUpdate": {
|
||||
"lastUpdateStatusReason": {
|
||||
"value": null
|
||||
},
|
||||
"availableVersion": {
|
||||
"value": "0000001B",
|
||||
"timestamp": "2025-02-09T04:20:25.600Z"
|
||||
},
|
||||
"lastUpdateStatus": {
|
||||
"value": null
|
||||
},
|
||||
"supportedCommands": {
|
||||
"value": null
|
||||
},
|
||||
"state": {
|
||||
"value": "normalOperation",
|
||||
"timestamp": "2025-02-09T04:20:25.600Z"
|
||||
},
|
||||
"updateAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-09T04:20:25.601Z"
|
||||
},
|
||||
"currentVersion": {
|
||||
"value": "0000001B",
|
||||
"timestamp": "2025-02-09T04:20:25.593Z"
|
||||
},
|
||||
"lastUpdateTime": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"accelerationSensor": {
|
||||
"acceleration": {
|
||||
"value": "inactive",
|
||||
"timestamp": "2025-02-09T17:27:46.812Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"healthCheck": {
|
||||
"checkInterval": {
|
||||
"value": 60,
|
||||
"unit": "s",
|
||||
"data": {
|
||||
"deviceScheme": "UNTRACKED",
|
||||
"protocol": "cloud"
|
||||
},
|
||||
"timestamp": "2024-12-04T10:10:02.934Z"
|
||||
},
|
||||
"healthStatus": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-Enroll": {
|
||||
"value": null
|
||||
},
|
||||
"DeviceWatch-DeviceStatus": {
|
||||
"value": "online",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-09T10:09:47.758Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"airConditionerMode": {
|
||||
"availableAcModes": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAcModes": {
|
||||
"value": null
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"value": "cool",
|
||||
"timestamp": "2025-02-09T10:09:47.758Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 20,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-02-09T10:09:47.758Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-02-09T10:09:47.758Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"refresh": {},
|
||||
"firmwareUpdate": {
|
||||
"lastUpdateStatusReason": {
|
||||
"value": null
|
||||
},
|
||||
"availableVersion": {
|
||||
"value": "00102101",
|
||||
"timestamp": "2025-02-08T19:37:03.624Z"
|
||||
},
|
||||
"lastUpdateStatus": {
|
||||
"value": null
|
||||
},
|
||||
"supportedCommands": {
|
||||
"value": null
|
||||
},
|
||||
"state": {
|
||||
"value": "normalOperation",
|
||||
"timestamp": "2025-02-08T19:37:03.622Z"
|
||||
},
|
||||
"updateAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-08T19:37:03.624Z"
|
||||
},
|
||||
"currentVersion": {
|
||||
"value": "00102101",
|
||||
"timestamp": "2025-02-08T19:37:03.594Z"
|
||||
},
|
||||
"lastUpdateTime": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-09T17:31:12.210Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,259 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"mediaPlayback": {
|
||||
"supportedPlaybackCommands": {
|
||||
"value": ["play", "pause", "stop"],
|
||||
"timestamp": "2025-02-02T13:18:40.078Z"
|
||||
},
|
||||
"playbackStatus": {
|
||||
"value": "playing",
|
||||
"timestamp": "2025-02-09T19:53:58.330Z"
|
||||
}
|
||||
},
|
||||
"mediaPresets": {
|
||||
"presets": {
|
||||
"value": [
|
||||
{
|
||||
"id": "10",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000059036.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Dra \u00e5t skogen Sune!"
|
||||
},
|
||||
{
|
||||
"id": "22",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000001894.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Fy katten Sune"
|
||||
},
|
||||
{
|
||||
"id": "29",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000001896.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Gult \u00e4r fult, Sune"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"imageUrl": "https://static.mytuner.mobi/media/tvos_radios/2l5zg6lhjbab.png",
|
||||
"mediaSource": "myTuner Radio",
|
||||
"name": "Kiss"
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000046017.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "L\u00e4skigt Sune!"
|
||||
},
|
||||
{
|
||||
"id": "16",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0002590598.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Pluggh\u00e4sten Sune"
|
||||
},
|
||||
{
|
||||
"id": "14",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000000070.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sagan om Sune"
|
||||
},
|
||||
{
|
||||
"id": "18",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000006452.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sk\u00e4mtaren Sune"
|
||||
},
|
||||
{
|
||||
"id": "26",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000001892.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Spik och panik, Sune!"
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0003119145.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune - T\u00e5gsemestern"
|
||||
},
|
||||
{
|
||||
"id": "25",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000000071.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune b\u00f6rjar tv\u00e5an"
|
||||
},
|
||||
{
|
||||
"id": "9",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000006448.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune i Grekland"
|
||||
},
|
||||
{
|
||||
"id": "8",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0002492498.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune i Ullared"
|
||||
},
|
||||
{
|
||||
"id": "30",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0002072946.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune och familjen Anderssons sjuka jul"
|
||||
},
|
||||
{
|
||||
"id": "17",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000000475.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune och klantpappan"
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000042688.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune och Mamma Mysko"
|
||||
},
|
||||
{
|
||||
"id": "20",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000000072.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune och syster vampyr"
|
||||
},
|
||||
{
|
||||
"id": "15",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000039918.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune slutar f\u00f6rsta klass"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000017431.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sune v\u00e4rsta killen!"
|
||||
},
|
||||
{
|
||||
"id": "27",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000068900.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes halloween"
|
||||
},
|
||||
{
|
||||
"id": "19",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000000476.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes hemligheter"
|
||||
},
|
||||
{
|
||||
"id": "21",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0002370989.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes hj\u00e4rnsl\u00e4pp"
|
||||
},
|
||||
{
|
||||
"id": "24",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000001889.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes jul"
|
||||
},
|
||||
{
|
||||
"id": "28",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000034437.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes party"
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000006450.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes skolresa"
|
||||
},
|
||||
{
|
||||
"id": "13",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000000477.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes sommar"
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000046015.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Sunes Sommarstuga"
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0002099327.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Supersnuten Sune"
|
||||
},
|
||||
{
|
||||
"id": "23",
|
||||
"imageUrl": "https://www.storytel.com//images/320x320/0000563738.jpg",
|
||||
"mediaSource": "Storytel",
|
||||
"name": "Zunes stolpskott"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-02-02T13:18:48.272Z"
|
||||
}
|
||||
},
|
||||
"audioVolume": {
|
||||
"volume": {
|
||||
"value": 15,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T19:57:37.230Z"
|
||||
}
|
||||
},
|
||||
"mediaGroup": {
|
||||
"groupMute": {
|
||||
"value": "unmuted",
|
||||
"timestamp": "2025-02-07T01:19:54.911Z"
|
||||
},
|
||||
"groupPrimaryDeviceId": {
|
||||
"value": "RINCON_38420B9108F601400",
|
||||
"timestamp": "2025-02-09T19:52:24.000Z"
|
||||
},
|
||||
"groupId": {
|
||||
"value": "RINCON_38420B9108F601400:3579458382",
|
||||
"timestamp": "2025-02-09T19:54:06.936Z"
|
||||
},
|
||||
"groupVolume": {
|
||||
"value": 12,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-07T01:19:54.911Z"
|
||||
},
|
||||
"groupRole": {
|
||||
"value": "ungrouped",
|
||||
"timestamp": "2025-02-09T19:52:23.974Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"mediaTrackControl": {
|
||||
"supportedTrackControlCommands": {
|
||||
"value": ["nextTrack", "previousTrack"],
|
||||
"timestamp": "2025-02-02T13:18:40.123Z"
|
||||
}
|
||||
},
|
||||
"audioMute": {
|
||||
"mute": {
|
||||
"value": "unmuted",
|
||||
"timestamp": "2025-02-09T19:57:35.487Z"
|
||||
}
|
||||
},
|
||||
"audioNotification": {},
|
||||
"audioTrackData": {
|
||||
"totalTime": {
|
||||
"value": null
|
||||
},
|
||||
"audioTrackData": {
|
||||
"value": {
|
||||
"album": "Forever Young",
|
||||
"albumArtUrl": "http://192.168.1.123:1400/getaa?s=1&u=x-sonos-spotify%3aspotify%253atrack%253a3bg2qahpZmsg5wV2EMPXIk%3fsid%3d9%26flags%3d8232%26sn%3d9",
|
||||
"artist": "David Guetta",
|
||||
"mediaSource": "Spotify",
|
||||
"title": "Forever Young"
|
||||
},
|
||||
"timestamp": "2025-02-09T19:53:55.615Z"
|
||||
},
|
||||
"elapsedTime": {
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"mediaPlayback": {
|
||||
"supportedPlaybackCommands": {
|
||||
"value": ["play", "pause", "stop"],
|
||||
"timestamp": "2025-02-09T15:42:12.923Z"
|
||||
},
|
||||
"playbackStatus": {
|
||||
"value": "stopped",
|
||||
"timestamp": "2025-02-09T15:42:12.923Z"
|
||||
}
|
||||
},
|
||||
"samsungvd.soundFrom": {
|
||||
"mode": {
|
||||
"value": 3,
|
||||
"timestamp": "2025-02-09T15:42:13.215Z"
|
||||
},
|
||||
"detailName": {
|
||||
"value": "External Device",
|
||||
"timestamp": "2025-02-09T15:42:13.215Z"
|
||||
}
|
||||
},
|
||||
"audioVolume": {
|
||||
"volume": {
|
||||
"value": 17,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T17:25:51.839Z"
|
||||
}
|
||||
},
|
||||
"samsungvd.audioGroupInfo": {
|
||||
"role": {
|
||||
"value": null
|
||||
},
|
||||
"status": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"audioNotification": {},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungvd.audioInputSource": {
|
||||
"supportedInputSources": {
|
||||
"value": ["digital", "HDMI1", "bluetooth", "wifi", "HDMI2"],
|
||||
"timestamp": "2025-02-09T17:18:44.680Z"
|
||||
},
|
||||
"inputSource": {
|
||||
"value": "HDMI1",
|
||||
"timestamp": "2025-02-09T17:18:44.680Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "on",
|
||||
"timestamp": "2025-02-09T17:25:51.536Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": "2024-12-10T02:12:44Z",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mndt": {
|
||||
"value": "2023-01-01",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "SAT-iMX8M23WWC-1010.5",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "0d94e5db-8501-2355-eb4f-214163702cac",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "Soundbar Living",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "HW-Q990C",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "VD-NetworkAudio-002S",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "7.0",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "Tizen",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "0d94e5db-8501-2355-eb4f-214163702cac",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2024-12-31T01:03:42.587Z"
|
||||
}
|
||||
},
|
||||
"audioMute": {
|
||||
"mute": {
|
||||
"value": "unmuted",
|
||||
"timestamp": "2025-02-09T17:18:44.787Z"
|
||||
}
|
||||
},
|
||||
"samsungvd.thingStatus": {
|
||||
"updatedTime": {
|
||||
"value": 1739115734,
|
||||
"timestamp": "2025-02-09T15:42:13.949Z"
|
||||
},
|
||||
"status": {
|
||||
"value": "Idle",
|
||||
"timestamp": "2025-02-09T15:42:13.949Z"
|
||||
}
|
||||
},
|
||||
"audioTrackData": {
|
||||
"totalTime": {
|
||||
"value": 0,
|
||||
"timestamp": "2024-12-31T00:29:29.953Z"
|
||||
},
|
||||
"audioTrackData": {
|
||||
"value": {
|
||||
"title": "",
|
||||
"artist": "",
|
||||
"album": ""
|
||||
},
|
||||
"timestamp": "2024-12-31T00:29:29.953Z"
|
||||
},
|
||||
"elapsedTime": {
|
||||
"value": 0,
|
||||
"timestamp": "2024-12-31T00:29:29.828Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"mediaPlayback": {
|
||||
"supportedPlaybackCommands": {
|
||||
"value": ["play", "pause", "stop", "fastForward", "rewind"],
|
||||
"timestamp": "2020-05-07T02:58:10.250Z"
|
||||
},
|
||||
"playbackStatus": {
|
||||
"value": null,
|
||||
"timestamp": "2020-08-04T21:53:22.108Z"
|
||||
}
|
||||
},
|
||||
"audioVolume": {
|
||||
"volume": {
|
||||
"value": 13,
|
||||
"unit": "%",
|
||||
"timestamp": "2021-08-21T19:19:52.832Z"
|
||||
}
|
||||
},
|
||||
"samsungvd.supportsPowerOnByOcf": {
|
||||
"supportsPowerOnByOcf": {
|
||||
"value": null,
|
||||
"timestamp": "2020-10-29T10:47:20.305Z"
|
||||
}
|
||||
},
|
||||
"samsungvd.mediaInputSource": {
|
||||
"supportedInputSourcesMap": {
|
||||
"value": [
|
||||
{
|
||||
"id": "dtv",
|
||||
"name": "TV"
|
||||
},
|
||||
{
|
||||
"id": "HDMI1",
|
||||
"name": "PlayStation 4"
|
||||
},
|
||||
{
|
||||
"id": "HDMI4",
|
||||
"name": "HT-CT370"
|
||||
},
|
||||
{
|
||||
"id": "HDMI4",
|
||||
"name": "HT-CT370"
|
||||
}
|
||||
],
|
||||
"timestamp": "2021-10-16T15:18:11.622Z"
|
||||
},
|
||||
"inputSource": {
|
||||
"value": "HDMI1",
|
||||
"timestamp": "2021-08-28T16:29:59.716Z"
|
||||
}
|
||||
},
|
||||
"mediaInputSource": {
|
||||
"supportedInputSources": {
|
||||
"value": ["digitalTv", "HDMI1", "HDMI4", "HDMI4"],
|
||||
"timestamp": "2021-10-16T15:18:11.622Z"
|
||||
},
|
||||
"inputSource": {
|
||||
"value": "HDMI1",
|
||||
"timestamp": "2021-08-28T16:29:59.716Z"
|
||||
}
|
||||
},
|
||||
"custom.tvsearch": {},
|
||||
"samsungvd.ambient": {},
|
||||
"refresh": {},
|
||||
"custom.error": {
|
||||
"error": {
|
||||
"value": null,
|
||||
"timestamp": "2020-08-04T21:53:22.148Z"
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": {
|
||||
"payload": {
|
||||
"rt": ["x.com.samsung.tv.deviceinfo"],
|
||||
"if": ["oic.if.baseline", "oic.if.r"],
|
||||
"x.com.samsung.country": "USA",
|
||||
"x.com.samsung.infolinkversion": "T-INFOLINK2017-1008",
|
||||
"x.com.samsung.modelid": "17_KANTM_UHD",
|
||||
"x.com.samsung.tv.blemac": "CC:6E:A4:1F:4C:F7",
|
||||
"x.com.samsung.tv.btmac": "CC:6E:A4:1F:4C:F7",
|
||||
"x.com.samsung.tv.category": "tv",
|
||||
"x.com.samsung.tv.countrycode": "US",
|
||||
"x.com.samsung.tv.duid": "B2NBQRAG357IX",
|
||||
"x.com.samsung.tv.ethmac": "c0:48:e6:e7:fc:2c",
|
||||
"x.com.samsung.tv.p2pmac": "ce:6e:a4:1f:4c:f6",
|
||||
"x.com.samsung.tv.udn": "717fb7ed-b310-4cfe-8954-1cd8211dd689",
|
||||
"x.com.samsung.tv.wifimac": "cc:6e:a4:1f:4c:f6"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"href": "/sec/tv/deviceinfo"
|
||||
},
|
||||
"timestamp": "2021-08-30T19:18:12.303Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "on",
|
||||
"timestamp": "2021-10-16T15:18:11.317Z"
|
||||
}
|
||||
},
|
||||
"tvChannel": {
|
||||
"tvChannel": {
|
||||
"value": "",
|
||||
"timestamp": "2020-05-07T02:58:10.479Z"
|
||||
},
|
||||
"tvChannelName": {
|
||||
"value": "",
|
||||
"timestamp": "2021-08-21T18:53:06.643Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": "2021-08-21T14:50:34Z",
|
||||
"timestamp": "2021-08-21T19:19:51.890Z"
|
||||
},
|
||||
"mndt": {
|
||||
"value": "2017-01-01",
|
||||
"timestamp": "2021-08-21T19:19:51.890Z"
|
||||
},
|
||||
"mnfv": {
|
||||
"value": "T-KTMAKUC-1290.3",
|
||||
"timestamp": "2021-08-21T18:52:57.543Z"
|
||||
},
|
||||
"mnhw": {
|
||||
"value": "0-0",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"di": {
|
||||
"value": "4588d2d9-a8cf-40f4-9a0b-ed5dfbaccda1",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": "http://www.samsung.com/sec/tv/overview/",
|
||||
"timestamp": "2021-08-21T19:19:51.890Z"
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2021-08-21T18:52:58.071Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "[TV] Samsung 8 Series (49)",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "UN49MU8000",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "VD-STV_2017_K",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": "http://www.samsung.com",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"mnpv": {
|
||||
"value": "Tizen 3.0",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"mnos": {
|
||||
"value": "4.1.10",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"pi": {
|
||||
"value": "4588d2d9-a8cf-40f4-9a0b-ed5dfbaccda1",
|
||||
"timestamp": "2020-05-07T02:58:10.206Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2021-08-21T18:52:58.071Z"
|
||||
}
|
||||
},
|
||||
"custom.picturemode": {
|
||||
"pictureMode": {
|
||||
"value": "Dynamic",
|
||||
"timestamp": "2020-12-23T01:33:37.069Z"
|
||||
},
|
||||
"supportedPictureModes": {
|
||||
"value": ["Dynamic", "Standard", "Natural", "Movie"],
|
||||
"timestamp": "2020-05-07T02:58:10.585Z"
|
||||
},
|
||||
"supportedPictureModesMap": {
|
||||
"value": [
|
||||
{
|
||||
"id": "modeDynamic",
|
||||
"name": "Dynamic"
|
||||
},
|
||||
{
|
||||
"id": "modeStandard",
|
||||
"name": "Standard"
|
||||
},
|
||||
{
|
||||
"id": "modeNatural",
|
||||
"name": "Natural"
|
||||
},
|
||||
{
|
||||
"id": "modeMovie",
|
||||
"name": "Movie"
|
||||
}
|
||||
],
|
||||
"timestamp": "2020-12-23T01:33:37.069Z"
|
||||
}
|
||||
},
|
||||
"samsungvd.ambientContent": {
|
||||
"supportedAmbientApps": {
|
||||
"value": [],
|
||||
"timestamp": "2021-01-17T01:10:11.985Z"
|
||||
}
|
||||
},
|
||||
"custom.accessibility": {},
|
||||
"custom.recording": {},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["samsungvd.ambient", "samsungvd.ambientContent"],
|
||||
"timestamp": "2021-01-17T01:10:11.985Z"
|
||||
}
|
||||
},
|
||||
"custom.soundmode": {
|
||||
"supportedSoundModesMap": {
|
||||
"value": [
|
||||
{
|
||||
"id": "modeStandard",
|
||||
"name": "Standard"
|
||||
}
|
||||
],
|
||||
"timestamp": "2021-08-21T19:19:52.887Z"
|
||||
},
|
||||
"soundMode": {
|
||||
"value": "Standard",
|
||||
"timestamp": "2020-12-23T01:33:37.272Z"
|
||||
},
|
||||
"supportedSoundModes": {
|
||||
"value": ["Standard"],
|
||||
"timestamp": "2021-08-21T19:19:52.887Z"
|
||||
}
|
||||
},
|
||||
"audioMute": {
|
||||
"mute": {
|
||||
"value": "muted",
|
||||
"timestamp": "2021-08-21T19:19:52.832Z"
|
||||
}
|
||||
},
|
||||
"mediaTrackControl": {
|
||||
"supportedTrackControlCommands": {
|
||||
"value": null,
|
||||
"timestamp": "2020-08-04T21:53:22.384Z"
|
||||
}
|
||||
},
|
||||
"custom.launchapp": {},
|
||||
"samsungvd.firmwareVersion": {
|
||||
"firmwareVersion": {
|
||||
"value": null,
|
||||
"timestamp": "2020-10-29T10:47:19.376Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"thermostatOperatingState": {
|
||||
"thermostatOperatingState": {
|
||||
"value": "pending cool",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
},
|
||||
"thermostatHeatingSetpoint": {
|
||||
"heatingSetpoint": {
|
||||
"value": 814.7469111058201,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"heatingSetpointRange": {
|
||||
"value": {
|
||||
"maximum": 3226.693210895862,
|
||||
"step": 9234.459191378826,
|
||||
"minimum": 6214.940743832475
|
||||
},
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": {
|
||||
"maximum": 1826.722761785079,
|
||||
"step": 138.2080712609211,
|
||||
"minimum": 9268.726934158902
|
||||
},
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"temperature": {
|
||||
"value": 8554.194688973037,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
},
|
||||
"thermostatFanMode": {
|
||||
"thermostatFanMode": {
|
||||
"value": "followschedule",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"supportedThermostatFanModes": {
|
||||
"value": ["on"],
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
},
|
||||
"thermostatMode": {
|
||||
"thermostatMode": {
|
||||
"value": "auxheatonly",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"supportedThermostatModes": {
|
||||
"value": ["rush hour"],
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": 51,
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"battery": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"type": {
|
||||
"value": "38140",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": {
|
||||
"maximum": 7288.145606306409,
|
||||
"step": 7620.031701049315,
|
||||
"minimum": 4997.721228739137
|
||||
},
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 244.33726326608746,
|
||||
"unit": "F",
|
||||
"timestamp": "2025-02-10T22:04:56.341Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"refresh": {},
|
||||
"valve": {
|
||||
"valve": {
|
||||
"value": "closed",
|
||||
"timestamp": "2025-02-11T11:27:02.262Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"waterSensor": {
|
||||
"water": {
|
||||
"value": "dry",
|
||||
"timestamp": "2025-02-10T21:58:18.784Z"
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": 84,
|
||||
"timestamp": "2025-02-10T21:58:18.784Z"
|
||||
},
|
||||
"battery": {
|
||||
"value": 100,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-10T21:58:18.784Z"
|
||||
},
|
||||
"type": {
|
||||
"value": "46120",
|
||||
"timestamp": "2025-02-10T21:58:18.784Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"lock": {
|
||||
"supportedUnlockDirections": {
|
||||
"value": null
|
||||
},
|
||||
"supportedLockValues": {
|
||||
"value": null
|
||||
},
|
||||
"lock": {
|
||||
"value": "locked",
|
||||
"data": {},
|
||||
"timestamp": "2025-02-09T17:29:56.641Z"
|
||||
},
|
||||
"supportedLockCommands": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": null
|
||||
},
|
||||
"battery": {
|
||||
"value": 86,
|
||||
"unit": "%",
|
||||
"timestamp": "2025-02-09T17:18:14.150Z"
|
||||
},
|
||||
"type": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"firmwareUpdate": {
|
||||
"lastUpdateStatusReason": {
|
||||
"value": null
|
||||
},
|
||||
"availableVersion": {
|
||||
"value": "00840847",
|
||||
"timestamp": "2025-02-09T11:48:45.331Z"
|
||||
},
|
||||
"lastUpdateStatus": {
|
||||
"value": null
|
||||
},
|
||||
"supportedCommands": {
|
||||
"value": null
|
||||
},
|
||||
"state": {
|
||||
"value": "normalOperation",
|
||||
"timestamp": "2025-02-09T11:48:45.331Z"
|
||||
},
|
||||
"updateAvailable": {
|
||||
"value": false,
|
||||
"timestamp": "2025-02-09T11:48:45.332Z"
|
||||
},
|
||||
"currentVersion": {
|
||||
"value": "00840847",
|
||||
"timestamp": "2025-02-09T11:48:45.328Z"
|
||||
},
|
||||
"lastUpdateTime": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"lockCodes": {
|
||||
"codeLength": {
|
||||
"value": null,
|
||||
"timestamp": "2020-08-04T15:29:24.127Z"
|
||||
},
|
||||
"maxCodes": {
|
||||
"value": 250,
|
||||
"timestamp": "2023-08-22T01:34:19.751Z"
|
||||
},
|
||||
"maxCodeLength": {
|
||||
"value": 8,
|
||||
"timestamp": "2023-08-22T01:34:18.690Z"
|
||||
},
|
||||
"codeChanged": {
|
||||
"value": "8 unset",
|
||||
"data": {
|
||||
"codeName": "Code 8"
|
||||
},
|
||||
"timestamp": "2025-01-06T04:56:31.712Z"
|
||||
},
|
||||
"lock": {
|
||||
"value": "locked",
|
||||
"data": {
|
||||
"method": "manual"
|
||||
},
|
||||
"timestamp": "2023-07-10T23:03:42.305Z"
|
||||
},
|
||||
"minCodeLength": {
|
||||
"value": 4,
|
||||
"timestamp": "2023-08-22T01:34:18.781Z"
|
||||
},
|
||||
"codeReport": {
|
||||
"value": 5,
|
||||
"timestamp": "2022-08-01T01:36:58.424Z"
|
||||
},
|
||||
"scanCodes": {
|
||||
"value": "Complete",
|
||||
"timestamp": "2025-01-06T04:56:31.730Z"
|
||||
},
|
||||
"lockCodes": {
|
||||
"value": "{\"1\":\"Salim\",\"2\":\"Saima\",\"3\":\"Sarah\",\"4\":\"Aisha\",\"5\":\"Moiz\"}",
|
||||
"timestamp": "2025-01-06T04:56:28.325Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "f0af21a2-d5a1-437c-b10a-b34a87394b71",
|
||||
"name": "aeotec-home-energy-meter-gen5",
|
||||
"label": "Aeotec Energy Monitor",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "3e0921d3-0a66-3d49-b458-752e596838e9",
|
||||
"deviceManufacturerCode": "0086-0002-005F",
|
||||
"locationId": "6911ddf5-f0cb-4516-a06a-3a2a6ec22bca",
|
||||
"ownerId": "93257fc4-6471-2566-b06e-2fe72dd979fa",
|
||||
"roomId": "cdf080f0-0542-41d7-a606-aff69683e04c",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Meter",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "powerMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "energyMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "voltageMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "CurbPowerMeter",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-01-12T23:02:44.917Z",
|
||||
"parentDeviceId": "6a2d07a4-dd77-48bc-9acf-017029aaf099",
|
||||
"profile": {
|
||||
"id": "6372c227-93c7-32ef-9be5-aef2221adff1"
|
||||
},
|
||||
"zwave": {
|
||||
"networkId": "0A",
|
||||
"driverId": "b98b34ce-1d1d-480c-bb17-41307a90cde0",
|
||||
"executingLocally": true,
|
||||
"hubId": "6a2d07a4-dd77-48bc-9acf-017029aaf099",
|
||||
"networkSecurityLevel": "ZWAVE_S0_LEGACY",
|
||||
"provisioningState": "PROVISIONED",
|
||||
"manufacturerId": 134,
|
||||
"productType": 2,
|
||||
"productId": 95
|
||||
},
|
||||
"type": "ZWAVE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "68e786a6-7f61-4c3a-9e13-70b803cf782b",
|
||||
"name": "base-electric-meter",
|
||||
"label": "Aeon Energy Monitor",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "8e619cd9-c271-3ba0-9015-62bc074bc47f",
|
||||
"deviceManufacturerCode": "0086-0002-0009",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "94be4a1e-382a-4b7f-a5ef-fdb1a7d9f9e6",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "powerMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "energyMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "CurbPowerMeter",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-06-03T16:23:57.284Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "d382796f-8ed5-3088-8735-eb03e962203b"
|
||||
},
|
||||
"zwave": {
|
||||
"networkId": "2A",
|
||||
"driverId": "4fb7ec02-2697-4d73-977d-2b1c65c4484f",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"networkSecurityLevel": "ZWAVE_LEGACY_NON_SECURE",
|
||||
"provisioningState": "PROVISIONED",
|
||||
"manufacturerId": 134,
|
||||
"productType": 2,
|
||||
"productId": 9
|
||||
},
|
||||
"type": "ZWAVE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "10e06a70-ee7d-4832-85e9-a0a06a7a05bd",
|
||||
"name": "c2c-arlo-pro-3-switch",
|
||||
"label": "2nd Floor Hallway",
|
||||
"manufacturerName": "SmartThings",
|
||||
"presentationId": "SmartThings-smartthings-c2c_arlo_pro_3",
|
||||
"deviceManufacturerCode": "Arlo",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "68b45114-9af8-4906-8636-b973a6faa271",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "soundSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "videoStream",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "motionSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "videoCapture",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "alarm",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Camera",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2024-11-21T21:55:59.340Z",
|
||||
"profile": {
|
||||
"id": "89aefc3a-e210-4678-944c-638d47d296f6"
|
||||
},
|
||||
"viper": {
|
||||
"manufacturerName": "Arlo",
|
||||
"modelName": "VMC4041PB",
|
||||
"endpointAppId": "viper_555d6f40-b65a-11ea-8fe0-77cb99571462"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
59
tests/components/smartthings/fixtures/devices/c2c_shade.json
Normal file
59
tests/components/smartthings/fixtures/devices/c2c_shade.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "571af102-15db-4030-b76b-245a691f74a5",
|
||||
"name": "c2c-shade",
|
||||
"label": "Curtain 1A",
|
||||
"manufacturerName": "SmartThings",
|
||||
"presentationId": "SmartThings-smartthings-c2c-shade",
|
||||
"deviceManufacturerCode": "WonderLabs Company",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "windowShade",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switchLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Blind",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-02-07T23:01:15.883Z",
|
||||
"profile": {
|
||||
"id": "0ceffb3e-10d3-4123-bb42-2a92c93c6e25"
|
||||
},
|
||||
"viper": {
|
||||
"manufacturerName": "WonderLabs Company",
|
||||
"modelName": "WoCurtain3",
|
||||
"hwVersion": "WoCurtain3-WoCurtain3",
|
||||
"endpointAppId": "viper_f18eb770-077d-11ea-bb72-9922e3ed0d38"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "d0268a69-abfb-4c92-a646-61cec2e510ad",
|
||||
"name": "plug-level-power",
|
||||
"label": "Dimmer Debian",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "bb7c4cfb-6eaf-3efc-823b-06a54fc9ded9",
|
||||
"deviceManufacturerCode": "CentraLite",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "94be4a1e-382a-4b7f-a5ef-fdb1a7d9f9e6",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switchLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "firmwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "SmartPlug",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2024-08-15T22:16:37.926Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "24195ea4-635c-3450-a235-71bc78ab3d1c"
|
||||
},
|
||||
"zigbee": {
|
||||
"eui": "000D6F0003C04BC9",
|
||||
"networkId": "F50E",
|
||||
"driverId": "f2e891c6-00cc-446c-9192-8ebda63d9898",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"provisioningState": "PROVISIONED"
|
||||
},
|
||||
"type": "ZIGBEE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "2d9a892b-1c93-45a5-84cb-0e81889498c6",
|
||||
"name": "contact-profile",
|
||||
"label": ".Front Door Open/Closed Sensor",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "a7f2c1d9-89b3-35a4-b217-fc68d9e4e752",
|
||||
"deviceManufacturerCode": "Visonic",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "68b45114-9af8-4906-8636-b973a6faa271",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "firmwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "ContactSensor",
|
||||
"categoryType": "manufacturer"
|
||||
},
|
||||
{
|
||||
"name": "ContactSensor",
|
||||
"categoryType": "user"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-09-28T17:38:59.179Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "22aa5a07-ac33-365f-b2f1-5ecef8cdb0eb"
|
||||
},
|
||||
"zigbee": {
|
||||
"eui": "000D6F000576F604",
|
||||
"networkId": "5A44",
|
||||
"driverId": "408981c2-91d4-4dfc-bbfb-84ca0205d993",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"provisioningState": "PROVISIONED"
|
||||
},
|
||||
"type": "ZIGBEE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,311 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "96a5ef74-5832-a84b-f1f7-ca799957065d",
|
||||
"name": "[room a/c] Samsung",
|
||||
"label": "AC Office Granit",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-AC-RAC-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "58d3fd7c-c512-4da3-b500-ef269382756c",
|
||||
"ownerId": "f9a28d7c-1ed5-d9e9-a81c-18971ec081db",
|
||||
"roomId": "85a79db4-9cf2-4f09-a5b2-cd70a5c0cef0",
|
||||
"deviceTypeName": "Samsung OCF Air Conditioner",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerFanMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "fanOscillationMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airQualitySensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "relativeHumidityMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "dustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "veryFineDustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioVolume",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.spiMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerOptionalMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerTropicalNightMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.autoCleaningMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deviceReportStateConfiguration",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dustFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerOdorController",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deodorFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledComponents",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dongleSoftwareInstallation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.selfCheck",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "AirConditioner",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"label": "1",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerFanMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "fanOscillationMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "relativeHumidityMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airQualitySensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "dustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "veryFineDustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "odorSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioVolume",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.autoCleaningMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerTropicalNightMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.spiMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerOptionalMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deviceReportStateConfiguration",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dustFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerOdorController",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deodorFilter",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2021-04-06T16:43:34.753Z",
|
||||
"profile": {
|
||||
"id": "60fbc713-8da5-315d-b31a-6d6dcde4be7b"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.airconditioner",
|
||||
"name": "[room a/c] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "ARTIK051_KRAC_18K|10193441|60010132001111110200000000000000",
|
||||
"platformVersion": "0G3MPDCKA00010E",
|
||||
"platformOS": "TizenRT2.0",
|
||||
"hwVersion": "1.0",
|
||||
"firmwareVersion": "0.1.0",
|
||||
"vendorId": "DA-AC-RAC-000001",
|
||||
"lastSignupTime": "2021-04-06T16:43:27.889445Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "4ece486b-89db-f06a-d54d-748b676b4d8e",
|
||||
"name": "Samsung-Room-Air-Conditioner",
|
||||
"label": "Aire Dormitorio Principal",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-AC-RAC-01001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "c4189ac1-208f-461a-8ab6-ea67937b3743",
|
||||
"ownerId": "85ea07e1-7063-f673-3ba5-125293f297c8",
|
||||
"roomId": "1f66199a-1773-4d8f-97b7-44c312a62cf7",
|
||||
"deviceTypeName": "Samsung OCF Air Conditioner",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerFanMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "bypassable",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "fanOscillationMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "relativeHumidityMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airQualitySensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "odorSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "dustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "veryFineDustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioVolume",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioNotification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.spiMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerOptionalMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerTropicalNightMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.autoCleaningMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deviceReportStateConfiguration",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dustFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.veryFineDustFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deodorFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.electricHepaFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.doNotDisturbMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.periodicSensing",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.airConditionerOdorController",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.alwaysOnSensing",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.airConditionerBeep",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.airConditionerLighting",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.airQualityHealthConcern",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.buttonDisplayCondition",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dustFilterAlarm",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.individualControlLock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.selfCheck",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.silentAction",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.quickControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.welcomeCooling",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.unavailableCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.wifiConfiguration",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.calmConnectionCare",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "AirConditioner",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-01-28T21:31:35.755Z",
|
||||
"profile": {
|
||||
"id": "091a55f4-7054-39fa-b23e-b56deb7580f8"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.airconditioner",
|
||||
"name": "Samsung-Room-Air-Conditioner",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "1.2.1",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "ARA-WW-TP1-22-COMMON|10229641|60010523001511014600083200800000",
|
||||
"platformVersion": "DAWIT 2.0",
|
||||
"platformOS": "TizenRT 3.1",
|
||||
"hwVersion": "Realtek",
|
||||
"firmwareVersion": "ARA-WW-TP1-22-COMMON_11240702",
|
||||
"vendorId": "DA-AC-RAC-01001",
|
||||
"vendorResourceClientServerVersion": "Realtek Release 3.1.240221",
|
||||
"lastSignupTime": "2025-01-28T21:31:30.090416369Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "2bad3237-4886-e699-1b90-4a51a3d55c8a",
|
||||
"name": "Samsung Microwave",
|
||||
"label": "Microwave",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-KS-MICROWAVE-0101X",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "586e4602-34ab-4a22-993e-5f616b04604f",
|
||||
"ownerId": "b603d7e8-6066-4e10-8102-afa752a63816",
|
||||
"roomId": "f4d03391-ab13-4c1d-b4dc-d6ddf86014a2",
|
||||
"deviceTypeName": "oic.d.microwave",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ovenSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ovenMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ovenOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "doorControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.hoodFanSpeed",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.definedRecipe",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.doorState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kitchenDeviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kitchenDeviceDefaults",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.ovenMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.ovenOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.microwavePower",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kitchenModeSpecification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kidsLock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Microwave",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "hood",
|
||||
"label": "hood",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "samsungce.lamp",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.hoodFanSpeed",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2022-03-23T15:59:10.704Z",
|
||||
"profile": {
|
||||
"id": "e5db3b6f-cad6-3caa-9775-9c9cae20f4a4"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.microwave",
|
||||
"name": "Samsung Microwave",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "TP2X_DA-KS-MICROWAVE-0101X|40436241|50040100011411000200000000000000",
|
||||
"platformVersion": "DAWIT 3.0",
|
||||
"platformOS": "TizenRT 2.0 + IPv6",
|
||||
"hwVersion": "MediaTek",
|
||||
"firmwareVersion": "AKS-WW-TP2-20-MICROWAVE-OTR_40230125",
|
||||
"vendorId": "DA-KS-MICROWAVE-0101X",
|
||||
"vendorResourceClientServerVersion": "MediaTek Release 2.220916.2",
|
||||
"lastSignupTime": "2022-04-17T15:33:11.063457Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,412 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "7db87911-7dce-1cf2-7119-b953432a2f09",
|
||||
"name": "[refrigerator] Samsung",
|
||||
"label": "Refrigerator",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-REF-NORMAL-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "3a1f7e7c-4e59-4c29-adb0-0813be691efd",
|
||||
"deviceTypeName": "Samsung OCF Refrigerator",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refrigeration",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deodorFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.deviceReportStateConfiguration",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.fridgeMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledComponents",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.waterFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dongleSoftwareInstallation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.fridgeVacationMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.powerCool",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.powerFreeze",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.sabbathMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.quickControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Refrigerator",
|
||||
"categoryType": "manufacturer"
|
||||
},
|
||||
{
|
||||
"name": "Refrigerator",
|
||||
"categoryType": "user"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "freezer",
|
||||
"label": "freezer",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.fridgeMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.freezerConvertMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.unavailableCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cooler",
|
||||
"label": "cooler",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.fridgeMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.unavailableCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cvroom",
|
||||
"label": "cvroom",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.fridgeMode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "onedoor",
|
||||
"label": "onedoor",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.fridgeMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.freezerConvertMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.unavailableCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "icemaker",
|
||||
"label": "icemaker",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "icemaker-02",
|
||||
"label": "icemaker-02",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "pantry-01",
|
||||
"label": "pantry-01",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "samsungce.fridgePantryInfo",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.fridgePantryMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "pantry-02",
|
||||
"label": "pantry-02",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "samsungce.fridgePantryInfo",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.fridgePantryMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2022-01-08T16:50:43.544Z",
|
||||
"profile": {
|
||||
"id": "f2a9af35-5df8-3477-91df-94941d302591"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.refrigerator",
|
||||
"name": "[refrigerator] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "TP2X_REF_20K|00115641|0004014D011411200103000020000000",
|
||||
"platformVersion": "DAWIT 2.0",
|
||||
"platformOS": "TizenRT 1.0 + IPv6",
|
||||
"hwVersion": "MediaTek",
|
||||
"firmwareVersion": "A-RFWW-TP2-21-COMMON_20220110",
|
||||
"vendorId": "DA-REF-NORMAL-000001",
|
||||
"vendorResourceClientServerVersion": "MediaTek Release 2.210524.1",
|
||||
"lastSignupTime": "2024-08-06T15:24:29.362093Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "3442dfc6-17c0-a65f-dae0-4c6e01786f44",
|
||||
"name": "[robot vacuum] Samsung",
|
||||
"label": "Robot vacuum",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-RVC-NORMAL-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "586e4602-34ab-4a22-993e-5f616b04604f",
|
||||
"ownerId": "b603d7e8-6066-4e10-8102-afa752a63816",
|
||||
"roomId": "5d425f41-042a-4d9a-92c4-e43150a61bae",
|
||||
"deviceTypeName": "Samsung OCF Robot Vacuum",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Robot vacuum",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "robotCleanerTurboMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "robotCleanerMovement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "robotCleanerCleaningMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledComponents",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.robotCleanerCleaningMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.robotCleanerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "RobotCleaner",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2018-06-06T23:04:25Z",
|
||||
"profile": {
|
||||
"id": "61b1c3cd-61cc-3dde-a4ba-9477d5e559cb"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.robotcleaner",
|
||||
"name": "[robot vacuum] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "powerbot_7000_17M|50016055|80010404011141000100000000000000",
|
||||
"platformVersion": "00",
|
||||
"platformOS": "Tizen(3/0)",
|
||||
"hwVersion": "1.0",
|
||||
"firmwareVersion": "1.0",
|
||||
"vendorId": "DA-RVC-NORMAL-000001",
|
||||
"lastSignupTime": "2020-11-03T04:43:02.729Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "f36dc7ce-cac0-0667-dc14-a3704eb5e676",
|
||||
"name": "[dishwasher] Samsung",
|
||||
"label": "Dishwasher",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-WM-DW-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "586e4602-34ab-4a22-993e-5f616b04604f",
|
||||
"ownerId": "b603d7e8-6066-4e10-8102-afa752a63816",
|
||||
"roomId": "f4d03391-ab13-4c1d-b4dc-d6ddf86014a2",
|
||||
"deviceTypeName": "Samsung OCF Dishwasher",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "dishwasherOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dishwasherOperatingProgress",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dishwasherOperatingPercentage",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dishwasherDelayStartTime",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.supportedOptions",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.waterFilter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dishwasherJobState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dishwasherWashingCourse",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dishwasherWashingCourseDetails",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dishwasherOperation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dishwasherWashingOptions",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kidsLock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.waterConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.quickControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.wifiConfiguration",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Dishwasher",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2021-06-27T01:19:35.408Z",
|
||||
"profile": {
|
||||
"id": "0cba797c-40ee-3473-aa01-4ee5b6cb8c67"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.dishwasher",
|
||||
"name": "[dishwasher] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "DA_DW_A51_20_COMMON|30007242|40010201001311000101000000000000",
|
||||
"platformVersion": "DAWIT 2.0",
|
||||
"platformOS": "TizenRT 1.0 + IPv6",
|
||||
"hwVersion": "ARTIK051",
|
||||
"firmwareVersion": "DA_DW_A51_20_COMMON_30230714",
|
||||
"vendorId": "DA-WM-DW-000001",
|
||||
"vendorResourceClientServerVersion": "ARTIK051 Release 2.210224.1",
|
||||
"lastSignupTime": "2021-10-16T17:28:59.984202Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "02f7256e-8353-5bdd-547f-bd5b1647e01b",
|
||||
"name": "[dryer] Samsung",
|
||||
"label": "Dryer",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-WM-WD-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "781d5f1e-c87e-455e-87f7-8e954879e91d",
|
||||
"ownerId": "b603d7e8-6066-4e10-8102-afa752a63816",
|
||||
"roomId": "2a8637b2-77ad-475e-b537-7b6f7f97fff6",
|
||||
"deviceTypeName": "Samsung OCF Dryer",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "dryerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dryerDryLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dryerWrinklePrevent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.jobBeginningStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.supportedOptions",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentOrder",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dongleSoftwareInstallation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerAutoCycleLink",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerCycle",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerCyclePreset",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerDelayEnd",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerDryingTemperature",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerDryingTime",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerFreezePrevent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dryerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kidsLock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.welcomeMessage",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.quickControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.wifiConfiguration",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Dryer",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "hca.main",
|
||||
"label": "hca.main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "hca.dryerMode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2021-06-01T22:54:25.907Z",
|
||||
"profile": {
|
||||
"id": "53a1d049-eeda-396c-8324-e33438ef57be"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.dryer",
|
||||
"name": "[dryer] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "DA_WM_A51_20_COMMON|20233741|3000000100111100020B000000000000",
|
||||
"platformVersion": "DAWIT 2.0",
|
||||
"platformOS": "TizenRT 1.0 + IPv6",
|
||||
"hwVersion": "ARTIK051",
|
||||
"firmwareVersion": "DA_WM_A51_20_COMMON_30230708",
|
||||
"vendorId": "DA-WM-WD-000001",
|
||||
"vendorResourceClientServerVersion": "ARTIK051 Release 2.210224.1",
|
||||
"lastSignupTime": "2021-06-01T22:54:22.826697Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "f984b91d-f250-9d42-3436-33f09a422a47",
|
||||
"name": "[washer] Samsung",
|
||||
"label": "Washer",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-WM-WM-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "781d5f1e-c87e-455e-87f7-8e954879e91d",
|
||||
"ownerId": "b603d7e8-6066-4e10-8102-afa752a63816",
|
||||
"roomId": "2a8637b2-77ad-475e-b537-7b6f7f97fff6",
|
||||
"deviceTypeName": "Samsung OCF Washer",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "washerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dryerDryLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.jobBeginningStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.supportedOptions",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerAutoDetergent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerAutoSoftener",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerRinseCycles",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerSoilLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerSpinLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerWaterTemperature",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.autoDispenseDetergent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.autoDispenseSoftener",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentOrder",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dongleSoftwareInstallation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentAutoReplenishment",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softenerAutoReplenishment",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kidsLock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softenerOrder",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softenerState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerBubbleSoak",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerCycle",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerCyclePreset",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerDelayEnd",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerFreezePrevent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerWashingTime",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerWaterLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerWaterValve",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.welcomeMessage",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.waterConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.quickControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.energyPlanner",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.wifiConfiguration",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Washer",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "hca.main",
|
||||
"label": "hca.main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "hca.washerMode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2021-06-01T22:52:18.023Z",
|
||||
"profile": {
|
||||
"id": "3f221c79-d81c-315f-8e8b-b5742802a1e3"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.washer",
|
||||
"name": "[washer] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "DA_WM_TP2_20_COMMON|20233741|2001000100131100022B010000000000",
|
||||
"platformVersion": "DAWIT 2.0",
|
||||
"platformOS": "TizenRT 2.0 + IPv6",
|
||||
"hwVersion": "MediaTek",
|
||||
"firmwareVersion": "DA_WM_TP2_20_COMMON_30230804",
|
||||
"vendorId": "DA-WM-WM-000001",
|
||||
"vendorResourceClientServerVersion": "MediaTek Release 2.211214.1",
|
||||
"lastSignupTime": "2021-06-01T22:52:13.923649Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "d5dc3299-c266-41c7-bd08-f540aea54b89",
|
||||
"name": "ecobee Sensor",
|
||||
"label": "Child Bedroom",
|
||||
"manufacturerName": "0A0b",
|
||||
"presentationId": "ST_635a866e-a3ea-4184-9d60-9c72ea603dfd",
|
||||
"deviceManufacturerCode": "ecobee",
|
||||
"locationId": "b6fe1fcb-e82b-4ce8-a5e1-85e96adba06c",
|
||||
"ownerId": "b473ee01-2b1f-7bb1-c433-3caec75960bc",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "motionSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "presenceSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "MotionSensor",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-01-16T21:14:07.283Z",
|
||||
"profile": {
|
||||
"id": "8ab3ca07-0d07-471b-a276-065e46d7aa8a"
|
||||
},
|
||||
"viper": {
|
||||
"manufacturerName": "ecobee",
|
||||
"modelName": "aresSmart-ecobee3_remote_sensor",
|
||||
"swVersion": "250206213001",
|
||||
"hwVersion": "250206213001",
|
||||
"endpointAppId": "viper_92ccdcc0-4184-11eb-b9c5-036180216747"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "028469cb-6e89-4f14-8d9a-bfbca5e0fbfc",
|
||||
"name": "v4 - ecobee Thermostat - Heat and Cool (F)",
|
||||
"label": "Main Floor",
|
||||
"manufacturerName": "0A0b",
|
||||
"presentationId": "ST_5334da38-8076-4b40-9f6c-ac3fccaa5d24",
|
||||
"deviceManufacturerCode": "ecobee",
|
||||
"locationId": "b6fe1fcb-e82b-4ce8-a5e1-85e96adba06c",
|
||||
"ownerId": "b473ee01-2b1f-7bb1-c433-3caec75960bc",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "relativeHumidityMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatHeatingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatFanMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Thermostat",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-01-16T21:14:07.276Z",
|
||||
"profile": {
|
||||
"id": "234d537d-d388-497f-b0f4-2e25025119ba"
|
||||
},
|
||||
"viper": {
|
||||
"manufacturerName": "ecobee",
|
||||
"modelName": "aresSmart-thermostat",
|
||||
"swVersion": "250206151734",
|
||||
"hwVersion": "250206151734",
|
||||
"endpointAppId": "viper_92ccdcc0-4184-11eb-b9c5-036180216747"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
50
tests/components/smartthings/fixtures/devices/fake_fan.json
Normal file
50
tests/components/smartthings/fixtures/devices/fake_fan.json
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "f1af21a2-d5a1-437c-b10a-b34a87394b71",
|
||||
"name": "fake-fan",
|
||||
"label": "Fake fan",
|
||||
"manufacturerName": "Myself",
|
||||
"presentationId": "3f0921d3-0a66-3d49-b458-752e596838e9",
|
||||
"deviceManufacturerCode": "0086-0002-005F",
|
||||
"locationId": "6f11ddf5-f0cb-4516-a06a-3a2a6ec22bca",
|
||||
"ownerId": "9f257fc4-6471-2566-b06e-2fe72dd979fa",
|
||||
"roomId": "cdf080f0-0542-41d7-a606-aff69683e04c",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "fanSpeed",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerFanMode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Fan",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-01-12T23:02:44.917Z",
|
||||
"parentDeviceId": "6a2dd7a4-dd77-48bc-9acf-017029aaf099",
|
||||
"profile": {
|
||||
"id": "6372cd27-93c7-32ef-9be5-aef2221adff1"
|
||||
},
|
||||
"type": "ZWAVE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "aaedaf28-2ae0-4c1d-b57e-87f6a420c298",
|
||||
"name": "GE Dimmer Switch",
|
||||
"label": "Basement Exit Light",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "31cf01ee-cb49-3d95-ac2d-2afab47f25c7",
|
||||
"deviceManufacturerCode": "0063-4944-3130",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"roomId": "e73dcd00-6953-431d-ae79-73fd2f2c528e",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Basement Exit Light",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switchLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Switch",
|
||||
"categoryType": "manufacturer"
|
||||
},
|
||||
{
|
||||
"name": "Switch",
|
||||
"categoryType": "user"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2020-05-25T18:18:01Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "ec5458c2-c011-3479-a59b-82b42820c2f7"
|
||||
},
|
||||
"zwave": {
|
||||
"networkId": "14",
|
||||
"driverId": "2cbf55e3-dbc2-48a2-8be5-4c3ce756b692",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"networkSecurityLevel": "ZWAVE_LEGACY_NON_SECURE",
|
||||
"provisioningState": "NONFUNCTIONAL",
|
||||
"manufacturerId": 99,
|
||||
"productType": 18756,
|
||||
"productId": 12592
|
||||
},
|
||||
"type": "ZWAVE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "440063de-a200-40b5-8a6b-f3399eaa0370",
|
||||
"name": "hue-color-temperature-bulb",
|
||||
"label": "Bathroom spot",
|
||||
"manufacturerName": "0A2r",
|
||||
"presentationId": "ST_b93bec0e-1a81-4471-83fc-4dddca504acd",
|
||||
"deviceManufacturerCode": "Signify Netherlands B.V.",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "colorTemperature",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switchLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "synthetic.lightingEffectCircadian",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "synthetic.lightingEffectFade",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Light",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-12-17T18:11:41.453Z",
|
||||
"profile": {
|
||||
"id": "a79e4507-ecaa-3c7e-b660-a3a71f30eafb"
|
||||
},
|
||||
"viper": {
|
||||
"uniqueIdentifier": "ea409b82a6184ad9b49bd6318692cc1c",
|
||||
"manufacturerName": "Signify Netherlands B.V.",
|
||||
"modelName": "Hue ambiance spot",
|
||||
"swVersion": "1.122.2",
|
||||
"hwVersion": "LTG002",
|
||||
"endpointAppId": "viper_71ee45b0-a794-11e9-86b2-fdd6b9f75ce6"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "cb958955-b015-498c-9e62-fc0c51abd054",
|
||||
"name": "hue-rgbw-color-bulb",
|
||||
"label": "Standing light",
|
||||
"manufacturerName": "0A2r",
|
||||
"presentationId": "ST_2733b8dc-4b0f-4593-8e49-2432202abd52",
|
||||
"deviceManufacturerCode": "Signify Netherlands B.V.",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "colorControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "colorTemperature",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switchLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungim.hueSyncMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "synthetic.lightingEffectCircadian",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "synthetic.lightingEffectFade",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Light",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-12-17T18:11:41.454Z",
|
||||
"profile": {
|
||||
"id": "71be1b96-c5b5-38f7-a22c-65f5392ce7ed"
|
||||
},
|
||||
"viper": {
|
||||
"uniqueIdentifier": "f5f891a57b9d45408230b4228bdc2111",
|
||||
"manufacturerName": "Signify Netherlands B.V.",
|
||||
"modelName": "Hue color lamp",
|
||||
"swVersion": "1.122.2",
|
||||
"hwVersion": "LCA001",
|
||||
"endpointAppId": "viper_71ee45b0-a794-11e9-86b2-fdd6b9f75ce6"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
41
tests/components/smartthings/fixtures/devices/iphone.json
Normal file
41
tests/components/smartthings/fixtures/devices/iphone.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "184c67cc-69e2-44b6-8f73-55c963068ad9",
|
||||
"name": "iPhone",
|
||||
"label": "iPhone",
|
||||
"manufacturerName": "SmartThings",
|
||||
"presentationId": "SmartThings-smartthings-Mobile_Presence",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "presenceSensor",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "MobilePresence",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2021-12-02T16:14:24.394Z",
|
||||
"parentDeviceId": "b8e11599-5297-4574-8e62-885995fcaa20",
|
||||
"profile": {
|
||||
"id": "21d0f660-98b4-3f7b-8114-fe62e555628e"
|
||||
},
|
||||
"type": "MOBILE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "7d246592-93db-4d72-a10d-5a51793ece8c",
|
||||
"name": "Multipurpose Sensor",
|
||||
"label": "Deck Door",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "c385e2bc-acb8-317b-be2a-6efd1f879720",
|
||||
"deviceManufacturerCode": "SmartThings",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"roomId": "b277a3c0-b8fe-44de-9133-c1108747810c",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Deck Door",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "contactSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "threeAxis",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "accelerationSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "firmwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "MultiFunctionalSensor",
|
||||
"categoryType": "manufacturer"
|
||||
},
|
||||
{
|
||||
"name": "Door",
|
||||
"categoryType": "user"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2019-02-23T16:53:57Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "4471213f-121b-38fd-b022-51df37ac1d4c"
|
||||
},
|
||||
"zigbee": {
|
||||
"eui": "24FD5B00010AED6B",
|
||||
"networkId": "C972",
|
||||
"driverId": "408981c2-91d4-4dfc-bbfb-84ca0205d993",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"provisioningState": "PROVISIONED"
|
||||
},
|
||||
"type": "ZIGBEE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "bf4b1167-48a3-4af7-9186-0900a678ffa5",
|
||||
"name": "sensibo-airconditioner-1",
|
||||
"label": "Office",
|
||||
"manufacturerName": "0ABU",
|
||||
"presentationId": "sensibo-airconditioner-1",
|
||||
"deviceManufacturerCode": "Sensibo",
|
||||
"locationId": "fe14085e-bacb-4997-bc0c-df08204eaea2",
|
||||
"ownerId": "49228038-22ca-1c78-d7ab-b774b4569480",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "healthCheck",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "AirConditioner",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2024-12-04T10:10:02.873Z",
|
||||
"profile": {
|
||||
"id": "ddaffb28-8ebb-4bd6-9d6f-57c28dcb434d"
|
||||
},
|
||||
"viper": {
|
||||
"manufacturerName": "Sensibo",
|
||||
"modelName": "skyplus",
|
||||
"swVersion": "SKY40147",
|
||||
"hwVersion": "SKY40147",
|
||||
"endpointAppId": "viper_5661d200-806e-11e9-abe0-3b2f83c8954c"
|
||||
},
|
||||
"type": "VIPER",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "550a1c72-65a0-4d55-b97b-75168e055398",
|
||||
"name": "SYLVANIA SMART+ Smart Plug",
|
||||
"label": "Arlo Beta Basestation",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "28127039-043b-3df0-adf2-7541403dc4c1",
|
||||
"deviceManufacturerCode": "LEDVANCE",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "94be4a1e-382a-4b7f-a5ef-fdb1a7d9f9e6",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Pi Hole",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "firmwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Switch",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2018-10-05T12:23:14Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "daeff874-075a-32e3-8b11-bdb99d8e67c7"
|
||||
},
|
||||
"zigbee": {
|
||||
"eui": "F0D1B80000051E05",
|
||||
"networkId": "801E",
|
||||
"driverId": "f2e891c6-00cc-446c-9192-8ebda63d9898",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"provisioningState": "PROVISIONED"
|
||||
},
|
||||
"type": "ZIGBEE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "c85fced9-c474-4a47-93c2-037cc7829536",
|
||||
"name": "sonos-player",
|
||||
"label": "Elliots Rum",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "ef0a871d-9ed1-377d-8746-0da1dfd50598",
|
||||
"deviceManufacturerCode": "Sonos",
|
||||
"locationId": "eed0e167-e793-459b-80cb-a0b02e2b86c2",
|
||||
"ownerId": "2c69cc36-85ae-c41a-9981-a4ee96cd9137",
|
||||
"roomId": "105e6d1a-52a4-4797-a235-5a48d7d433c8",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "mediaPlayback",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaGroup",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaPresets",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaTrackControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioMute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioNotification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioTrackData",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioVolume",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Speaker",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-02-02T13:18:28.570Z",
|
||||
"parentDeviceId": "2f7f7d2b-e683-48ae-86f7-e57df6a0bce2",
|
||||
"profile": {
|
||||
"id": "0443d359-3f76-383f-82a4-6fc4a879ef1d"
|
||||
},
|
||||
"lan": {
|
||||
"networkId": "38420B9108F6",
|
||||
"driverId": "c21a6c77-872c-474e-be5b-5f6f11a240ef",
|
||||
"executingLocally": true,
|
||||
"hubId": "2f7f7d2b-e683-48ae-86f7-e57df6a0bce2",
|
||||
"provisioningState": "TYPED"
|
||||
},
|
||||
"type": "LAN",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "0d94e5db-8501-2355-eb4f-214163702cac",
|
||||
"name": "Soundbar",
|
||||
"label": "Soundbar Living",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "VD-NetworkAudio-002S",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "c4189ac1-208f-461a-8ab6-ea67937b3743",
|
||||
"ownerId": "85ea07e1-7063-f673-3ba5-125293f297c8",
|
||||
"roomId": "db506ec3-83b1-4125-9c4c-eb597da5db6a",
|
||||
"deviceTypeName": "Samsung OCF Network Audio Player",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioVolume",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioMute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioTrackData",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.audioInputSource",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaPlayback",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioNotification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.soundFrom",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.thingStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.audioGroupInfo",
|
||||
"version": 1,
|
||||
"ephemeral": true
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "NetworkAudio",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2024-10-26T02:58:40.549Z",
|
||||
"profile": {
|
||||
"id": "3a714028-20ea-3feb-9891-46092132c737"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.networkaudio",
|
||||
"name": "Soundbar Living",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "HW-Q990C",
|
||||
"platformVersion": "7.0",
|
||||
"platformOS": "Tizen",
|
||||
"hwVersion": "",
|
||||
"firmwareVersion": "SAT-iMX8M23WWC-1010.5",
|
||||
"vendorId": "VD-NetworkAudio-002S",
|
||||
"vendorResourceClientServerVersion": "3.2.41",
|
||||
"lastSignupTime": "2024-10-26T02:58:36.491256384Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
148
tests/components/smartthings/fixtures/devices/vd_stv_2017_k.json
Normal file
148
tests/components/smartthings/fixtures/devices/vd_stv_2017_k.json
Normal file
@ -0,0 +1,148 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "4588d2d9-a8cf-40f4-9a0b-ed5dfbaccda1",
|
||||
"name": "[TV] Samsung 8 Series (49)",
|
||||
"label": "[TV] Samsung 8 Series (49)",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "VD-STV_2017_K",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "94be4a1e-382a-4b7f-a5ef-fdb1a7d9f9e6",
|
||||
"deviceTypeName": "Samsung OCF TV",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioVolume",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "audioMute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "tvChannel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaInputSource",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaPlayback",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "mediaTrackControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.error",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.picturemode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.soundmode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.accessibility",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.launchapp",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.recording",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.tvsearch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.ambient",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.ambientContent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.mediaInputSource",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.firmwareVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungvd.supportsPowerOnByOcf",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Television",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2020-05-07T02:58:10Z",
|
||||
"profile": {
|
||||
"id": "bac5c673-8eea-3d00-b1d2-283b46539017"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.tv",
|
||||
"name": "[TV] Samsung 8 Series (49)",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "UN49MU8000",
|
||||
"platformVersion": "Tizen 3.0",
|
||||
"platformOS": "4.1.10",
|
||||
"hwVersion": "0-0",
|
||||
"firmwareVersion": "T-KTMAKUC-1290.3",
|
||||
"vendorId": "VD-STV_2017_K",
|
||||
"locale": "en_US",
|
||||
"lastSignupTime": "2021-08-21T18:52:56.748359Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "2894dc93-0f11-49cc-8a81-3a684cebebf6",
|
||||
"name": "asd",
|
||||
"label": "asd",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "78906115-bf23-3c43-9cd6-f42ca3d5517a",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"roomId": "58826afc-9f38-426a-b868-dc94776286e3",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "thermostatHeatingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatFanMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Thermostat",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-02-10T22:04:56.174Z",
|
||||
"profile": {
|
||||
"id": "e921d7f2-5851-363d-89d5-5e83f5ab44c6"
|
||||
},
|
||||
"virtual": {
|
||||
"name": "asd",
|
||||
"executingLocally": false
|
||||
},
|
||||
"type": "VIRTUAL",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3",
|
||||
"name": "volvo",
|
||||
"label": "volvo",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "916408b6-c94e-38b8-9fbf-03c8a48af5c3",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"roomId": "58826afc-9f38-426a-b868-dc94776286e3",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "valve",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "WaterValve",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-02-11T11:27:02.052Z",
|
||||
"profile": {
|
||||
"id": "f8e25992-7f5d-31da-b04d-497012590113"
|
||||
},
|
||||
"virtual": {
|
||||
"name": "volvo",
|
||||
"executingLocally": false
|
||||
},
|
||||
"type": "VIRTUAL",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "a2a6018b-2663-4727-9d1d-8f56953b5116",
|
||||
"name": "asd",
|
||||
"label": "asd",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "838ae989-b832-3610-968c-2940491600f6",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"roomId": "58826afc-9f38-426a-b868-dc94776286e3",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "waterSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "LeakSensor",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-02-10T21:58:18.688Z",
|
||||
"profile": {
|
||||
"id": "39230a95-d42d-34d4-a33c-f79573495a30"
|
||||
},
|
||||
"virtual": {
|
||||
"name": "asd",
|
||||
"executingLocally": false
|
||||
},
|
||||
"type": "VIRTUAL",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "a9f587c5-5d8b-4273-8907-e7f609af5158",
|
||||
"name": "Yale Push Button Deadbolt Lock",
|
||||
"label": "Basement Door Lock",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "45f9424f-4e20-34b0-abb6-5f26b189acb0",
|
||||
"deviceManufacturerCode": "Yale",
|
||||
"locationId": "c4d3b2a1-09f8-765e-4d3c-2b1a09f8e7d6 ",
|
||||
"ownerId": "d47f2b19-3a6e-4c8d-bf21-9e8a7c5d134e",
|
||||
"roomId": "94be4a1e-382a-4b7f-a5ef-fdb1a7d9f9e6",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Basement Door Lock",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "lock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "lockCodes",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "firmwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "SmartLock",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2016-11-18T23:01:19Z",
|
||||
"parentDeviceId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"profile": {
|
||||
"id": "51b76691-3c3a-3fce-8c7c-4f9d50e5885a"
|
||||
},
|
||||
"zigbee": {
|
||||
"eui": "000D6F0002FB6E24",
|
||||
"networkId": "C771",
|
||||
"driverId": "ce930ffd-8155-4dca-aaa9-6c4158fc4278",
|
||||
"executingLocally": true,
|
||||
"hubId": "074fa784-8be8-4c70-8e22-6f5ed6f81b7e",
|
||||
"provisioningState": "PROVISIONED"
|
||||
},
|
||||
"type": "ZIGBEE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "LOCAL"
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
9
tests/components/smartthings/fixtures/locations.json
Normal file
9
tests/components/smartthings/fixtures/locations.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"locationId": "397678e5-9995-4a39-9d9f-ae6ba310236c",
|
||||
"name": "Home"
|
||||
}
|
||||
],
|
||||
"_links": null
|
||||
}
|
34
tests/components/smartthings/fixtures/scenes.json
Normal file
34
tests/components/smartthings/fixtures/scenes.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"sceneId": "743b0f37-89b8-476c-aedf-eea8ad8cd29d",
|
||||
"sceneName": "Away",
|
||||
"sceneIcon": "203",
|
||||
"sceneColor": null,
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"createdBy": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"createdDate": 1738964737000,
|
||||
"lastUpdatedDate": 1738964737000,
|
||||
"lastExecutedDate": null,
|
||||
"editable": false,
|
||||
"apiVersion": "20200501"
|
||||
},
|
||||
{
|
||||
"sceneId": "f3341e8b-9b32-4509-af2e-4f7c952e98ba",
|
||||
"sceneName": "Home",
|
||||
"sceneIcon": "204",
|
||||
"sceneColor": null,
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"createdBy": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"createdDate": 1738964731000,
|
||||
"lastUpdatedDate": 1738964731000,
|
||||
"lastExecutedDate": null,
|
||||
"editable": false,
|
||||
"apiVersion": "20200501"
|
||||
}
|
||||
],
|
||||
"_links": {
|
||||
"next": null,
|
||||
"previous": null
|
||||
}
|
||||
}
|
529
tests/components/smartthings/snapshots/test_binary_sensor.ambr
Normal file
529
tests/components/smartthings/snapshots/test_binary_sensor.ambr
Normal file
@ -0,0 +1,529 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[c2c_arlo_pro_3_switch][binary_sensor.2nd_floor_hallway_motion-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.2nd_floor_hallway_motion',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.MOTION: 'motion'>,
|
||||
'original_icon': None,
|
||||
'original_name': '2nd Floor Hallway motion',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '10e06a70-ee7d-4832-85e9-a0a06a7a05bd.motion',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[c2c_arlo_pro_3_switch][binary_sensor.2nd_floor_hallway_motion-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'motion',
|
||||
'friendly_name': '2nd Floor Hallway motion',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.2nd_floor_hallway_motion',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[c2c_arlo_pro_3_switch][binary_sensor.2nd_floor_hallway_sound-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.2nd_floor_hallway_sound',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.SOUND: 'sound'>,
|
||||
'original_icon': None,
|
||||
'original_name': '2nd Floor Hallway sound',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '10e06a70-ee7d-4832-85e9-a0a06a7a05bd.sound',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[c2c_arlo_pro_3_switch][binary_sensor.2nd_floor_hallway_sound-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'sound',
|
||||
'friendly_name': '2nd Floor Hallway sound',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.2nd_floor_hallway_sound',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[contact_sensor][binary_sensor.front_door_open_closed_sensor_contact-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.front_door_open_closed_sensor_contact',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.DOOR: 'door'>,
|
||||
'original_icon': None,
|
||||
'original_name': '.Front Door Open/Closed Sensor contact',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '2d9a892b-1c93-45a5-84cb-0e81889498c6.contact',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[contact_sensor][binary_sensor.front_door_open_closed_sensor_contact-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'door',
|
||||
'friendly_name': '.Front Door Open/Closed Sensor contact',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.front_door_open_closed_sensor_contact',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_000001][binary_sensor.refrigerator_contact-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.refrigerator_contact',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.DOOR: 'door'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Refrigerator contact',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '7db87911-7dce-1cf2-7119-b953432a2f09.contact',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_000001][binary_sensor.refrigerator_contact-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'door',
|
||||
'friendly_name': 'Refrigerator contact',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.refrigerator_contact',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_sensor][binary_sensor.child_bedroom_motion-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.child_bedroom_motion',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.MOTION: 'motion'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Child Bedroom motion',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'd5dc3299-c266-41c7-bd08-f540aea54b89.motion',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_sensor][binary_sensor.child_bedroom_motion-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'motion',
|
||||
'friendly_name': 'Child Bedroom motion',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.child_bedroom_motion',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_sensor][binary_sensor.child_bedroom_presence-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.child_bedroom_presence',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.PRESENCE: 'presence'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Child Bedroom presence',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'd5dc3299-c266-41c7-bd08-f540aea54b89.presence',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_sensor][binary_sensor.child_bedroom_presence-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'presence',
|
||||
'friendly_name': 'Child Bedroom presence',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.child_bedroom_presence',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[iphone][binary_sensor.iphone_presence-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.iphone_presence',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.PRESENCE: 'presence'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'iPhone presence',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '184c67cc-69e2-44b6-8f73-55c963068ad9.presence',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[iphone][binary_sensor.iphone_presence-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'presence',
|
||||
'friendly_name': 'iPhone presence',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.iphone_presence',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[multipurpose_sensor][binary_sensor.deck_door_acceleration-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.deck_door_acceleration',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.MOVING: 'moving'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Deck Door acceleration',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '7d246592-93db-4d72-a10d-5a51793ece8c.acceleration',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[multipurpose_sensor][binary_sensor.deck_door_acceleration-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'moving',
|
||||
'friendly_name': 'Deck Door acceleration',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.deck_door_acceleration',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[multipurpose_sensor][binary_sensor.deck_door_contact-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.deck_door_contact',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.DOOR: 'door'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Deck Door contact',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '7d246592-93db-4d72-a10d-5a51793ece8c.contact',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[multipurpose_sensor][binary_sensor.deck_door_contact-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'door',
|
||||
'friendly_name': 'Deck Door contact',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.deck_door_contact',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_valve][binary_sensor.volvo_valve-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.volvo_valve',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.OPENING: 'opening'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'volvo valve',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3.valve',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_valve][binary_sensor.volvo_valve-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'opening',
|
||||
'friendly_name': 'volvo valve',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.volvo_valve',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_water_sensor][binary_sensor.asd_water-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.asd_water',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.MOISTURE: 'moisture'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'asd water',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'a2a6018b-2663-4727-9d1d-8f56953b5116.water',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_water_sensor][binary_sensor.asd_water-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'moisture',
|
||||
'friendly_name': 'asd water',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.asd_water',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
356
tests/components/smartthings/snapshots/test_climate.ambr
Normal file
356
tests/components/smartthings/snapshots/test_climate.ambr
Normal file
@ -0,0 +1,356 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[da_ac_rac_000001][climate.ac_office_granit-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.DRY: 'dry'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'preset_modes': list([
|
||||
'windFree',
|
||||
]),
|
||||
'swing_modes': None,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.ac_office_granit',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'AC Office Granit',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 441>,
|
||||
'translation_key': None,
|
||||
'unique_id': '96a5ef74-5832-a84b-f1f7-ca799957065d',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_000001][climate.ac_office_granit-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 25,
|
||||
'drlc_status_duration': 0,
|
||||
'drlc_status_level': -1,
|
||||
'drlc_status_override': False,
|
||||
'drlc_status_start': '1970-01-01T00:00:00Z',
|
||||
'fan_mode': 'low',
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'friendly_name': 'AC Office Granit',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.DRY: 'dry'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'preset_mode': None,
|
||||
'preset_modes': list([
|
||||
'windFree',
|
||||
]),
|
||||
'supported_features': <ClimateEntityFeature: 441>,
|
||||
'swing_mode': 'off',
|
||||
'swing_modes': None,
|
||||
'temperature': 25,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.ac_office_granit',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_01001][climate.aire_dormitorio_principal-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.DRY: 'dry'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'preset_modes': list([
|
||||
'windFree',
|
||||
]),
|
||||
'swing_modes': list([
|
||||
'off',
|
||||
'vertical',
|
||||
'horizontal',
|
||||
'both',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.aire_dormitorio_principal',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Aire Dormitorio Principal',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 441>,
|
||||
'translation_key': None,
|
||||
'unique_id': '4ece486b-89db-f06a-d54d-748b676b4d8e',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_01001][climate.aire_dormitorio_principal-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 27,
|
||||
'drlc_status_duration': 0,
|
||||
'drlc_status_level': 0,
|
||||
'drlc_status_override': False,
|
||||
'drlc_status_start': '1970-01-01T00:00:00Z',
|
||||
'fan_mode': 'high',
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'friendly_name': 'Aire Dormitorio Principal',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.DRY: 'dry'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'preset_mode': None,
|
||||
'preset_modes': list([
|
||||
'windFree',
|
||||
]),
|
||||
'supported_features': <ClimateEntityFeature: 441>,
|
||||
'swing_mode': 'off',
|
||||
'swing_modes': list([
|
||||
'off',
|
||||
'vertical',
|
||||
'horizontal',
|
||||
'both',
|
||||
]),
|
||||
'temperature': 23,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.aire_dormitorio_principal',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_thermostat][climate.main_floor-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'on',
|
||||
'auto',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
]),
|
||||
'max_temp': 35.0,
|
||||
'min_temp': 7.0,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.main_floor',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Main Floor',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 395>,
|
||||
'translation_key': None,
|
||||
'unique_id': '028469cb-6e89-4f14-8d9a-bfbca5e0fbfc',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_thermostat][climate.main_floor-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_humidity': 32,
|
||||
'current_temperature': 21.7,
|
||||
'fan_mode': 'auto',
|
||||
'fan_modes': list([
|
||||
'on',
|
||||
'auto',
|
||||
]),
|
||||
'friendly_name': 'Main Floor',
|
||||
'hvac_action': <HVACAction.HEATING: 'heating'>,
|
||||
'hvac_modes': list([
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
]),
|
||||
'max_temp': 35.0,
|
||||
'min_temp': 7.0,
|
||||
'supported_features': <ClimateEntityFeature: 395>,
|
||||
'target_temp_high': None,
|
||||
'target_temp_low': None,
|
||||
'temperature': 21.7,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.main_floor',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_thermostat][climate.asd-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'on',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
]),
|
||||
'max_temp': 35.0,
|
||||
'min_temp': 7.0,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.asd',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'asd',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 395>,
|
||||
'translation_key': None,
|
||||
'unique_id': '2894dc93-0f11-49cc-8a81-3a684cebebf6',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_thermostat][climate.asd-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 4734.6,
|
||||
'fan_mode': 'followschedule',
|
||||
'fan_modes': list([
|
||||
'on',
|
||||
]),
|
||||
'friendly_name': 'asd',
|
||||
'hvac_action': <HVACAction.COOLING: 'cooling'>,
|
||||
'hvac_modes': list([
|
||||
]),
|
||||
'max_temp': 35.0,
|
||||
'min_temp': 7.0,
|
||||
'supported_features': <ClimateEntityFeature: 395>,
|
||||
'target_temp_high': None,
|
||||
'target_temp_low': None,
|
||||
'temperature': None,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.asd',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
100
tests/components/smartthings/snapshots/test_cover.ambr
Normal file
100
tests/components/smartthings/snapshots/test_cover.ambr
Normal file
@ -0,0 +1,100 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[c2c_shade][cover.curtain_1a-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'cover',
|
||||
'entity_category': None,
|
||||
'entity_id': 'cover.curtain_1a',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <CoverDeviceClass.SHADE: 'shade'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Curtain 1A',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <CoverEntityFeature: 7>,
|
||||
'translation_key': None,
|
||||
'unique_id': '571af102-15db-4030-b76b-245a691f74a5',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[c2c_shade][cover.curtain_1a-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_position': 100,
|
||||
'device_class': 'shade',
|
||||
'friendly_name': 'Curtain 1A',
|
||||
'supported_features': <CoverEntityFeature: 7>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'cover.curtain_1a',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'open',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ks_microwave_0101x][cover.microwave-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'cover',
|
||||
'entity_category': None,
|
||||
'entity_id': 'cover.microwave',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <CoverDeviceClass.DOOR: 'door'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Microwave',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <CoverEntityFeature: 3>,
|
||||
'translation_key': None,
|
||||
'unique_id': '2bad3237-4886-e699-1b90-4a51a3d55c8a',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ks_microwave_0101x][cover.microwave-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'door',
|
||||
'friendly_name': 'Microwave',
|
||||
'supported_features': <CoverEntityFeature: 3>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'cover.microwave',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
67
tests/components/smartthings/snapshots/test_fan.ambr
Normal file
67
tests/components/smartthings/snapshots/test_fan.ambr
Normal file
@ -0,0 +1,67 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[fake_fan][fan.fake_fan-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'preset_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'fan',
|
||||
'entity_category': None,
|
||||
'entity_id': 'fan.fake_fan',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Fake fan',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <FanEntityFeature: 57>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'f1af21a2-d5a1-437c-b10a-b34a87394b71',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[fake_fan][fan.fake_fan-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Fake fan',
|
||||
'percentage': 2000,
|
||||
'percentage_step': 33.333333333333336,
|
||||
'preset_mode': None,
|
||||
'preset_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'supported_features': <FanEntityFeature: 57>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'fan.fake_fan',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
1024
tests/components/smartthings/snapshots/test_init.ambr
Normal file
1024
tests/components/smartthings/snapshots/test_init.ambr
Normal file
File diff suppressed because it is too large
Load Diff
267
tests/components/smartthings/snapshots/test_light.ambr
Normal file
267
tests/components/smartthings/snapshots/test_light.ambr
Normal file
@ -0,0 +1,267 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[centralite][light.dimmer_debian-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.BRIGHTNESS: 'brightness'>,
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'light',
|
||||
'entity_category': None,
|
||||
'entity_id': 'light.dimmer_debian',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Dimmer Debian',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'd0268a69-abfb-4c92-a646-61cec2e510ad',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[centralite][light.dimmer_debian-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'brightness': None,
|
||||
'color_mode': None,
|
||||
'friendly_name': 'Dimmer Debian',
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.BRIGHTNESS: 'brightness'>,
|
||||
]),
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'light.dimmer_debian',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ge_in_wall_smart_dimmer][light.basement_exit_light-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.BRIGHTNESS: 'brightness'>,
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'light',
|
||||
'entity_category': None,
|
||||
'entity_id': 'light.basement_exit_light',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Basement Exit Light',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'aaedaf28-2ae0-4c1d-b57e-87f6a420c298',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ge_in_wall_smart_dimmer][light.basement_exit_light-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'brightness': None,
|
||||
'color_mode': None,
|
||||
'friendly_name': 'Basement Exit Light',
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.BRIGHTNESS: 'brightness'>,
|
||||
]),
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'light.basement_exit_light',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[hue_color_temperature_bulb][light.bathroom_spot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'max_color_temp_kelvin': 9000,
|
||||
'max_mireds': 500,
|
||||
'min_color_temp_kelvin': 2000,
|
||||
'min_mireds': 111,
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'light',
|
||||
'entity_category': None,
|
||||
'entity_id': 'light.bathroom_spot',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Bathroom spot',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'translation_key': None,
|
||||
'unique_id': '440063de-a200-40b5-8a6b-f3399eaa0370',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[hue_color_temperature_bulb][light.bathroom_spot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'brightness': 178,
|
||||
'color_mode': <ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
'color_temp': 333,
|
||||
'color_temp_kelvin': 3000,
|
||||
'friendly_name': 'Bathroom spot',
|
||||
'hs_color': tuple(
|
||||
27.825,
|
||||
56.895,
|
||||
),
|
||||
'max_color_temp_kelvin': 9000,
|
||||
'max_mireds': 500,
|
||||
'min_color_temp_kelvin': 2000,
|
||||
'min_mireds': 111,
|
||||
'rgb_color': tuple(
|
||||
255,
|
||||
177,
|
||||
110,
|
||||
),
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
]),
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'xy_color': tuple(
|
||||
0.496,
|
||||
0.383,
|
||||
),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'light.bathroom_spot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[hue_rgbw_color_bulb][light.standing_light-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'max_color_temp_kelvin': 9000,
|
||||
'max_mireds': 500,
|
||||
'min_color_temp_kelvin': 2000,
|
||||
'min_mireds': 111,
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
<ColorMode.HS: 'hs'>,
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'light',
|
||||
'entity_category': None,
|
||||
'entity_id': 'light.standing_light',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Standing light',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'cb958955-b015-498c-9e62-fc0c51abd054',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[hue_rgbw_color_bulb][light.standing_light-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'brightness': None,
|
||||
'color_mode': None,
|
||||
'color_temp': None,
|
||||
'color_temp_kelvin': None,
|
||||
'friendly_name': 'Standing light',
|
||||
'hs_color': None,
|
||||
'max_color_temp_kelvin': 9000,
|
||||
'max_mireds': 500,
|
||||
'min_color_temp_kelvin': 2000,
|
||||
'min_mireds': 111,
|
||||
'rgb_color': None,
|
||||
'supported_color_modes': list([
|
||||
<ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
<ColorMode.HS: 'hs'>,
|
||||
]),
|
||||
'supported_features': <LightEntityFeature: 32>,
|
||||
'xy_color': None,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'light.standing_light',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
50
tests/components/smartthings/snapshots/test_lock.ambr
Normal file
50
tests/components/smartthings/snapshots/test_lock.ambr
Normal file
@ -0,0 +1,50 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[yale_push_button_deadbolt_lock][lock.basement_door_lock-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'lock',
|
||||
'entity_category': None,
|
||||
'entity_id': 'lock.basement_door_lock',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Basement Door Lock',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'a9f587c5-5d8b-4273-8907-e7f609af5158',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[yale_push_button_deadbolt_lock][lock.basement_door_lock-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Basement Door Lock',
|
||||
'lock_state': 'locked',
|
||||
'supported_features': <LockEntityFeature: 0>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'lock.basement_door_lock',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'locked',
|
||||
})
|
||||
# ---
|
101
tests/components/smartthings/snapshots/test_scene.ambr
Normal file
101
tests/components/smartthings/snapshots/test_scene.ambr
Normal file
@ -0,0 +1,101 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[scene.away-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'scene',
|
||||
'entity_category': None,
|
||||
'entity_id': 'scene.away',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Away',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '743b0f37-89b8-476c-aedf-eea8ad8cd29d',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[scene.away-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'color': None,
|
||||
'friendly_name': 'Away',
|
||||
'icon': '203',
|
||||
'location_id': '88a3a314-f0c8-40b4-bb44-44ba06c9c42f',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'scene.away',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[scene.home-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'scene',
|
||||
'entity_category': None,
|
||||
'entity_id': 'scene.home',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Home',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'f3341e8b-9b32-4509-af2e-4f7c952e98ba',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[scene.home-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'color': None,
|
||||
'friendly_name': 'Home',
|
||||
'icon': '204',
|
||||
'location_id': '88a3a314-f0c8-40b4-bb44-44ba06c9c42f',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'scene.home',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
4857
tests/components/smartthings/snapshots/test_sensor.ambr
Normal file
4857
tests/components/smartthings/snapshots/test_sensor.ambr
Normal file
File diff suppressed because it is too large
Load Diff
471
tests/components/smartthings/snapshots/test_switch.ambr
Normal file
471
tests/components/smartthings/snapshots/test_switch.ambr
Normal file
@ -0,0 +1,471 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[c2c_arlo_pro_3_switch][switch.2nd_floor_hallway-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.2nd_floor_hallway',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': '2nd Floor Hallway',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '10e06a70-ee7d-4832-85e9-a0a06a7a05bd',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[c2c_arlo_pro_3_switch][switch.2nd_floor_hallway-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': '2nd Floor Hallway',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.2nd_floor_hallway',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ks_microwave_0101x][switch.microwave-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.microwave',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Microwave',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '2bad3237-4886-e699-1b90-4a51a3d55c8a',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ks_microwave_0101x][switch.microwave-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Microwave',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.microwave',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_rvc_normal_000001][switch.robot_vacuum-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.robot_vacuum',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Robot vacuum',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '3442dfc6-17c0-a65f-dae0-4c6e01786f44',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_rvc_normal_000001][switch.robot_vacuum-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Robot vacuum',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.robot_vacuum',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_dw_000001][switch.dishwasher-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.dishwasher',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Dishwasher',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'f36dc7ce-cac0-0667-dc14-a3704eb5e676',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_dw_000001][switch.dishwasher-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Dishwasher',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.dishwasher',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001][switch.dryer-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.dryer',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Dryer',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '02f7256e-8353-5bdd-547f-bd5b1647e01b',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001][switch.dryer-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Dryer',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.dryer',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001][switch.washer-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.washer',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Washer',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'f984b91d-f250-9d42-3436-33f09a422a47',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001][switch.washer-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Washer',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.washer',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensibo_airconditioner_1][switch.office-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.office',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Office',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'bf4b1167-48a3-4af7-9186-0900a678ffa5',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensibo_airconditioner_1][switch.office-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Office',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.office',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[smart_plug][switch.arlo_beta_basestation-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.arlo_beta_basestation',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Arlo Beta Basestation',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '550a1c72-65a0-4d55-b97b-75168e055398',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[smart_plug][switch.arlo_beta_basestation-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Arlo Beta Basestation',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.arlo_beta_basestation',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[vd_network_audio_002s][switch.soundbar_living-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.soundbar_living',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Soundbar Living',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '0d94e5db-8501-2355-eb4f-214163702cac',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[vd_network_audio_002s][switch.soundbar_living-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Soundbar Living',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.soundbar_living',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[vd_stv_2017_k][switch.tv_samsung_8_series_49-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.tv_samsung_8_series_49',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': '[TV] Samsung 8 Series (49)',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '4588d2d9-a8cf-40f4-9a0b-ed5dfbaccda1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[vd_stv_2017_k][switch.tv_samsung_8_series_49-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': '[TV] Samsung 8 Series (49)',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.tv_samsung_8_series_49',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
@ -1,139 +1,53 @@
|
||||
"""Test for the SmartThings binary_sensor platform.
|
||||
"""Test for the SmartThings binary_sensor platform."""
|
||||
|
||||
The only mocking required is of the underlying SmartThings API object so
|
||||
real HTTP calls are not initiated during testing.
|
||||
"""
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from pysmartthings import ATTRIBUTES, CAPABILITIES, Attribute, Capability
|
||||
from pysmartthings import Attribute, Capability
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DEVICE_CLASSES,
|
||||
DOMAIN as BINARY_SENSOR_DOMAIN,
|
||||
)
|
||||
from homeassistant.components.smartthings import binary_sensor
|
||||
from homeassistant.components.smartthings.const import DOMAIN, SIGNAL_SMARTTHINGS_UPDATE
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import ATTR_FRIENDLY_NAME, STATE_UNAVAILABLE, EntityCategory
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .conftest import setup_platform
|
||||
from . import setup_integration, snapshot_smartthings_entities, trigger_update
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_mapping_integrity() -> None:
|
||||
"""Test ensures the map dicts have proper integrity."""
|
||||
# Ensure every CAPABILITY_TO_ATTRIB key is in CAPABILITIES
|
||||
# Ensure every CAPABILITY_TO_ATTRIB value is in ATTRIB_TO_CLASS keys
|
||||
for capability, attrib in binary_sensor.CAPABILITY_TO_ATTRIB.items():
|
||||
assert capability in CAPABILITIES, capability
|
||||
assert attrib in ATTRIBUTES, attrib
|
||||
assert attrib in binary_sensor.ATTRIB_TO_CLASS, attrib
|
||||
# Ensure every ATTRIB_TO_CLASS value is in DEVICE_CLASSES
|
||||
for attrib, device_class in binary_sensor.ATTRIB_TO_CLASS.items():
|
||||
assert attrib in ATTRIBUTES, attrib
|
||||
assert device_class in DEVICE_CLASSES, device_class
|
||||
|
||||
|
||||
async def test_entity_state(hass: HomeAssistant, device_factory) -> None:
|
||||
"""Tests the state attributes properly match the light types."""
|
||||
device = device_factory(
|
||||
"Motion Sensor 1", [Capability.motion_sensor], {Attribute.motion: "inactive"}
|
||||
)
|
||||
await setup_platform(hass, BINARY_SENSOR_DOMAIN, devices=[device])
|
||||
state = hass.states.get("binary_sensor.motion_sensor_1_motion")
|
||||
assert state.state == "off"
|
||||
assert state.attributes[ATTR_FRIENDLY_NAME] == f"{device.label} {Attribute.motion}"
|
||||
|
||||
|
||||
async def test_entity_and_device_attributes(
|
||||
async def test_all_entities(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
devices: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_factory,
|
||||
) -> None:
|
||||
"""Test the attributes of the entity are correct."""
|
||||
# Arrange
|
||||
device = device_factory(
|
||||
"Motion Sensor 1",
|
||||
[Capability.motion_sensor],
|
||||
{
|
||||
Attribute.motion: "inactive",
|
||||
Attribute.mnmo: "123",
|
||||
Attribute.mnmn: "Generic manufacturer",
|
||||
Attribute.mnhw: "v4.56",
|
||||
Attribute.mnfv: "v7.89",
|
||||
},
|
||||
)
|
||||
# Act
|
||||
await setup_platform(hass, BINARY_SENSOR_DOMAIN, devices=[device])
|
||||
# Assert
|
||||
entry = entity_registry.async_get("binary_sensor.motion_sensor_1_motion")
|
||||
assert entry
|
||||
assert entry.unique_id == f"{device.device_id}.{Attribute.motion}"
|
||||
entry = device_registry.async_get_device(identifiers={(DOMAIN, device.device_id)})
|
||||
assert entry
|
||||
assert entry.configuration_url == "https://account.smartthings.com"
|
||||
assert entry.identifiers == {(DOMAIN, device.device_id)}
|
||||
assert entry.name == device.label
|
||||
assert entry.model == "123"
|
||||
assert entry.manufacturer == "Generic manufacturer"
|
||||
assert entry.hw_version == "v4.56"
|
||||
assert entry.sw_version == "v7.89"
|
||||
"""Test all entities."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
|
||||
async def test_update_from_signal(hass: HomeAssistant, device_factory) -> None:
|
||||
"""Test the binary_sensor updates when receiving a signal."""
|
||||
# Arrange
|
||||
device = device_factory(
|
||||
"Motion Sensor 1", [Capability.motion_sensor], {Attribute.motion: "inactive"}
|
||||
)
|
||||
await setup_platform(hass, BINARY_SENSOR_DOMAIN, devices=[device])
|
||||
device.status.apply_attribute_update(
|
||||
"main", Capability.motion_sensor, Attribute.motion, "active"
|
||||
)
|
||||
# Act
|
||||
async_dispatcher_send(hass, SIGNAL_SMARTTHINGS_UPDATE, [device.device_id])
|
||||
# Assert
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.motion_sensor_1_motion")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
|
||||
|
||||
async def test_unload_config_entry(hass: HomeAssistant, device_factory) -> None:
|
||||
"""Test the binary_sensor is removed when the config entry is unloaded."""
|
||||
# Arrange
|
||||
device = device_factory(
|
||||
"Motion Sensor 1", [Capability.motion_sensor], {Attribute.motion: "inactive"}
|
||||
)
|
||||
config_entry = await setup_platform(hass, BINARY_SENSOR_DOMAIN, devices=[device])
|
||||
config_entry.mock_state(hass, ConfigEntryState.LOADED)
|
||||
# Act
|
||||
await hass.config_entries.async_forward_entry_unload(config_entry, "binary_sensor")
|
||||
# Assert
|
||||
assert (
|
||||
hass.states.get("binary_sensor.motion_sensor_1_motion").state
|
||||
== STATE_UNAVAILABLE
|
||||
snapshot_smartthings_entities(
|
||||
hass, entity_registry, snapshot, Platform.BINARY_SENSOR
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_category(
|
||||
hass: HomeAssistant, entity_registry: er.EntityRegistry, device_factory
|
||||
@pytest.mark.parametrize("device_fixture", ["da_ref_normal_000001"])
|
||||
async def test_state_update(
|
||||
hass: HomeAssistant,
|
||||
devices: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Tests the state attributes properly match the light types."""
|
||||
device1 = device_factory(
|
||||
"Motion Sensor 1", [Capability.motion_sensor], {Attribute.motion: "inactive"}
|
||||
)
|
||||
device2 = device_factory(
|
||||
"Tamper Sensor 2", [Capability.tamper_alert], {Attribute.tamper: "inactive"}
|
||||
)
|
||||
await setup_platform(hass, BINARY_SENSOR_DOMAIN, devices=[device1, device2])
|
||||
"""Test state update."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
entry = entity_registry.async_get("binary_sensor.motion_sensor_1_motion")
|
||||
assert entry
|
||||
assert entry.entity_category is None
|
||||
assert hass.states.get("binary_sensor.refrigerator_contact").state == STATE_OFF
|
||||
|
||||
entry = entity_registry.async_get("binary_sensor.tamper_sensor_2_tamper")
|
||||
assert entry
|
||||
assert entry.entity_category is EntityCategory.DIAGNOSTIC
|
||||
await trigger_update(
|
||||
hass,
|
||||
devices,
|
||||
"7db87911-7dce-1cf2-7119-b953432a2f09",
|
||||
Capability.CONTACT_SENSOR,
|
||||
Attribute.CONTACT,
|
||||
"open",
|
||||
)
|
||||
|
||||
assert hass.states.get("binary_sensor.refrigerator_contact").state == STATE_ON
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user