Skip to content

Commit

Permalink
ADD Support for IR Remotes #152
Browse files Browse the repository at this point in the history
  • Loading branch information
xZetsubou committed Mar 8, 2024
1 parent d08e1f3 commit 0e614f9
Show file tree
Hide file tree
Showing 9 changed files with 437 additions and 10 deletions.
19 changes: 14 additions & 5 deletions custom_components/localtuya/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
EntityCategory,
CONF_ICON,
STATE_UNAVAILABLE,
Platform,
)
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.dispatcher import (
Expand Down Expand Up @@ -56,10 +57,12 @@
CONF_SCALING,
CONF_DEVICE_SLEEP_TIME,
CONF_DPS_STRINGS,
CONF_MANUAL_DPS,
)

_LOGGER = logging.getLogger(__name__)
RESTORE_STATES = {"0": "restore"}
BYPASS_STATUS = {"0": "bypass"}


async def async_setup_entry(
Expand Down Expand Up @@ -359,6 +362,9 @@ def _new_entity_handler(entity_id):
]
await asyncio.gather(*connect_sub_devices)

if "0" in self._device_config.get(CONF_MANUAL_DPS, "").split(","):
self.status_updated(BYPASS_STATUS)

if self._pending_status:
await self.set_dps(self._pending_status)
self._pending_status = {}
Expand Down Expand Up @@ -566,6 +572,7 @@ def __init__(
self._status = {}
self._state = None
self._last_state = None
self._hass = device._hass

# Default value is available to be provided by Platform entities if required
self._default_value = self._config.get(CONF_DEFAULT_VALUE)
Expand All @@ -581,18 +588,17 @@ async def async_added_to_hass(self):

self.debug(f"Adding {self.entity_id} with configuration: {self._config}")

state = await self.async_get_last_state()
if state:
self.status_restored(state)
stored_data = await self.async_get_last_state()
if stored_data:
self.status_restored(stored_data)

async def _update_handler(status):
def _update_handler(status):
"""Update entity state when status was updated."""
if status is None:
status = {}
if self._status != status:
if status == RESTORE_STATES:
status = {}
stored_data: State = await self.async_get_last_state()
self.debug(f"Device is sleep restored state: {stored_data.state}")
if stored_data and stored_data.state != STATE_UNAVAILABLE:
status = {self._dp_id: stored_data.state}
Expand Down Expand Up @@ -660,6 +666,9 @@ def unique_id(self) -> str:
@property
def available(self) -> bool:
"""Return if device is available or not."""
if self._status == BYPASS_STATUS:
return True

return len(self._status) > 0

@property
Expand Down
5 changes: 5 additions & 0 deletions custom_components/localtuya/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"Humidifier": Platform.HUMIDIFIER,
"Light": Platform.LIGHT,
"Number": Platform.NUMBER,
"Remote": Platform.REMOTE,
"Select": Platform.SELECT,
"Sensor": Platform.SENSOR,
"Siren": Platform.SIREN,
Expand Down Expand Up @@ -157,6 +158,10 @@
CONF_OPTIONS = "select_options"
CONF_OPTIONS_FRIENDLY = "select_options_friendly"

# Remote
CONF_SEND_DP = "send_dp"
CONF_RECEIVE_DP = "receive_dp"

# States
ATTR_STATE = "raw_state"
CONF_RESTORE_ON_RECONNECT = "restore_on_reconnect"
Expand Down
67 changes: 67 additions & 0 deletions custom_components/localtuya/core/pytuya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,73 @@ def __repr__(self):
return self.id


class api:
def __init__(
self,
host: str,
device_id: str,
local_key: str,
enable_debug: bool,
protocol_version: float,
listener: TuyaListener = None,
timeout: int = 5,
port: int = 6668,
) -> None:
"""
attributes:
host: The local IP Address of the device.
device_id: the ID of the device.
local_key: device payload, encryption key.
enable_debug: Enable the debug logs for the device.
protocol_version: The protocol version of the device # 3.1, 3.2, 3.3, 3.4 or 3.5
listener: class listener.
"""
self._device_id = device_id
self._host = host
self._local_key = local_key
self._enable_debug = enable_debug
self._protocol_version = protocol_version
self._listener = listener
self._timeout = timeout
self._port = port

#
self.connected: bool
self.is_connecting: bool
self.enable_reconnect: bool = True

self.manager: TuyaProtocol

async def connect(self):
if not self.enable_reconnect:
return
loop = asyncio.get_running_loop()
on_connected = loop.create_future()
try:
_, protocol = await loop.create_connection(
lambda: TuyaProtocol(
self._device_id,
self._local_key,
self._protocol_version,
self._enable_debug,
on_connected,
self._listener or EmptyListener(),
),
self._host,
self._port,
)
except OSError as ex:
raise ValueError(str(ex))
except Exception as ex:
raise ex
except:
raise ValueError(f"Unable to connect to the device. try again.")

await asyncio.wait_for(on_connected, timeout=self._timeout)
self.manager = protocol
return protocol


async def connect(
address,
device_id,
Expand Down
Loading

0 comments on commit 0e614f9

Please sign in to comment.