Add localtuya.set_dp service (#236)
This commit is contained in:
@@ -57,6 +57,8 @@ localtuya:
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
import voluptuous as vol
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_DEVICE_ID,
|
CONF_DEVICE_ID,
|
||||||
@@ -67,16 +69,12 @@ from homeassistant.const import (
|
|||||||
SERVICE_RELOAD,
|
SERVICE_RELOAD,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.reload import async_integration_yaml_config
|
from homeassistant.helpers.reload import async_integration_yaml_config
|
||||||
|
|
||||||
from .common import TuyaDevice
|
from .common import TuyaDevice
|
||||||
from .config_flow import config_schema
|
from .config_flow import config_schema
|
||||||
from .const import (
|
from .const import CONF_PRODUCT_KEY, DATA_DISCOVERY, DOMAIN, TUYA_DEVICE
|
||||||
CONF_PRODUCT_KEY,
|
|
||||||
DATA_DISCOVERY,
|
|
||||||
DOMAIN,
|
|
||||||
TUYA_DEVICE,
|
|
||||||
)
|
|
||||||
from .discovery import TuyaDiscovery
|
from .discovery import TuyaDiscovery
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@@ -85,6 +83,18 @@ UNSUB_LISTENER = "unsub_listener"
|
|||||||
|
|
||||||
CONFIG_SCHEMA = config_schema()
|
CONFIG_SCHEMA = config_schema()
|
||||||
|
|
||||||
|
CONF_DP = "dp"
|
||||||
|
CONF_VALUE = "value"
|
||||||
|
|
||||||
|
SERVICE_SET_DP = "set_dp"
|
||||||
|
SERVICE_SET_DP_SCHEMA = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_DEVICE_ID): cv.string,
|
||||||
|
vol.Required(CONF_DP): int,
|
||||||
|
vol.Required(CONF_VALUE): object,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_update_config_entry_if_from_yaml(hass, entries_by_id, conf):
|
def _async_update_config_entry_if_from_yaml(hass, entries_by_id, conf):
|
||||||
@@ -102,6 +112,14 @@ async def async_setup(hass: HomeAssistant, config: dict):
|
|||||||
|
|
||||||
device_cache = {}
|
device_cache = {}
|
||||||
|
|
||||||
|
def _entry_by_device_id(device_id):
|
||||||
|
"""Look up config entry by device id."""
|
||||||
|
current_entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
for entry in current_entries:
|
||||||
|
if entry.data[CONF_DEVICE_ID] == device_id:
|
||||||
|
return entry
|
||||||
|
return None
|
||||||
|
|
||||||
async def _handle_reload(service):
|
async def _handle_reload(service):
|
||||||
"""Handle reload service call."""
|
"""Handle reload service call."""
|
||||||
config = await async_integration_yaml_config(hass, DOMAIN)
|
config = await async_integration_yaml_config(hass, DOMAIN)
|
||||||
@@ -122,13 +140,20 @@ async def async_setup(hass: HomeAssistant, config: dict):
|
|||||||
|
|
||||||
await asyncio.gather(*reload_tasks)
|
await asyncio.gather(*reload_tasks)
|
||||||
|
|
||||||
def _entry_by_device_id(device_id):
|
async def _handle_set_dp(event):
|
||||||
"""Look up config entry by device id."""
|
"""Handle set_dp service call."""
|
||||||
current_entries = hass.config_entries.async_entries(DOMAIN)
|
entry = _entry_by_device_id(event.data[CONF_DEVICE_ID])
|
||||||
for entry in current_entries:
|
if not entry:
|
||||||
if entry.data[CONF_DEVICE_ID] == device_id:
|
raise HomeAssistantError("unknown device id")
|
||||||
return entry
|
|
||||||
return None
|
if entry.entry_id not in hass.data[DOMAIN]:
|
||||||
|
raise HomeAssistantError("device has not been discovered")
|
||||||
|
|
||||||
|
device = hass.data[DOMAIN][entry.entry_id][TUYA_DEVICE]
|
||||||
|
if not device.connected:
|
||||||
|
raise HomeAssistantError("not connected to device")
|
||||||
|
|
||||||
|
await device.set_dp(event.data[CONF_VALUE], event.data[CONF_DP])
|
||||||
|
|
||||||
def _device_discovered(device):
|
def _device_discovered(device):
|
||||||
"""Update address of device if it has changed."""
|
"""Update address of device if it has changed."""
|
||||||
@@ -193,6 +218,10 @@ async def async_setup(hass: HomeAssistant, config: dict):
|
|||||||
_handle_reload,
|
_handle_reload,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
hass.helpers.service.async_register_admin_service(
|
||||||
|
DOMAIN, SERVICE_SET_DP, _handle_set_dp, schema=SERVICE_SET_DP_SCHEMA
|
||||||
|
)
|
||||||
|
|
||||||
for host_config in config.get(DOMAIN, []):
|
for host_config in config.get(DOMAIN, []):
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.flow.async_init(
|
hass.config_entries.flow.async_init(
|
||||||
|
@@ -111,6 +111,11 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
|
|||||||
for entity in config_entry[CONF_ENTITIES]:
|
for entity in config_entry[CONF_ENTITIES]:
|
||||||
self._dps_to_request[entity[CONF_ID]] = None
|
self._dps_to_request[entity[CONF_ID]] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connected(self):
|
||||||
|
"""Return if connected to device."""
|
||||||
|
return self._interface is not None
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""Connect to device if not already connected."""
|
"""Connect to device if not already connected."""
|
||||||
if not self._is_closing and self._connect_task is None and not self._interface:
|
if not self._is_closing and self._connect_task is None and not self._interface:
|
||||||
|
@@ -1,2 +1,15 @@
|
|||||||
reload:
|
reload:
|
||||||
description: Reload localtuya and re-process yaml configuration.
|
description: Reload localtuya and re-process yaml configuration.
|
||||||
|
|
||||||
|
set_dp:
|
||||||
|
description: Change the value of a datapoint (DP)
|
||||||
|
fields:
|
||||||
|
device_id:
|
||||||
|
description: Device ID of device to change datapoint value for
|
||||||
|
example: 11100118278aab4de001
|
||||||
|
dp:
|
||||||
|
description: Datapoint index
|
||||||
|
example: 1
|
||||||
|
value:
|
||||||
|
description: New value to set
|
||||||
|
example: False
|
||||||
|
Reference in New Issue
Block a user