Skip to content

Commit cd476b4

Browse files
authored
Tuya upgrades 35, sub_devices bump 6.0.0 etc... (rospogrigio#15)
* rewrite add device manually message. * Add 7000 Port listening and reuse port * App broadcasting and improve data decrypt * Add auto protcol in config flow * and supported protocols in const * Add node ID to const * Add settings contexts * Add support for SubDevices and 3.5[Hope] in pytuya core * Fix sample template * clarify CID context * ADD Tuya const * add explain error into config_flow * Clarify Error_values when try to connect! * Report errors values if happend in core! * add node_id to common.py * update config_flow with many changes in PR edit: 1 * remove debug message * comment * increase timeout to 8secs. * revert increase timeout * typo * fix a bug when import template [need rewrite dev_config) * rework on helpers * update dps function version uses constant versions * remove duplicated function * cleansup codes * Fix unique IDs already exists. solve_issue_1 in PR * Rework config_flow actions Menu instead of radiobox * Spaces on Cover Commands Labels * Rename from `LocalTuya integration` to `Local Tuya` * rewrite translation to menu init * remove `CONF ACTION` and adjust `CONF CLOUD` * add `data_description` en lang to template step * Fix devices don't comeback after adding new device * remove unnecessary contect func * remove unnecessary contect func * fix entity_category and some cleans * clean up codes * cleans up helpers * for futrue things. * pump version * Give Docs when installing new integration. * cleans up repo
1 parent 813a227 commit cd476b4

33 files changed

+850
-727
lines changed

Diff for: .dependabot/config.yml

-19
This file was deleted.

Diff for: README.md

+93-127
Large diffs are not rendered by default.

Diff for: custom_components/localtuya/__init__.py

+16-34
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ async def _handle_set_dp(event):
9595

9696
await device.set_dp(event.data[CONF_VALUE], event.data[CONF_DP])
9797

98-
def _device_discovered(device):
98+
def _device_discovered(device: TuyaDevice):
9999
"""Update address of device if it has changed."""
100100
device_ip = device["ip"]
101101
device_id = device["gwId"]
@@ -139,15 +139,14 @@ def _device_discovered(device):
139139
)
140140
new_data[ATTR_UPDATED_AT] = str(int(time.time() * 1000))
141141
hass.config_entries.async_update_entry(entry, data=new_data)
142-
device = hass.data[DOMAIN][TUYA_DEVICES][device_id]
143-
if not device.connected:
144-
device.async_connect()
142+
# No need to do connect task here, when entry updated, it will reconnect. [elif].
143+
# device = hass.data[DOMAIN][TUYA_DEVICES][device_id]
144+
# if not device.connected:
145+
# hass.create_task(device.async_connect())
145146
elif device_id in hass.data[DOMAIN][TUYA_DEVICES]:
146-
# _LOGGER.debug("Device %s found with IP %s", device_id, device_ip)
147-
148147
device = hass.data[DOMAIN][TUYA_DEVICES][device_id]
149148
if not device.connected:
150-
device.async_connect()
149+
hass.create_task(device.async_connect())
151150

152151
def _shutdown(event):
153152
"""Clean up resources when shutting down."""
@@ -157,7 +156,7 @@ async def _async_reconnect(now):
157156
"""Try connecting to devices not already connected to."""
158157
for device_id, device in hass.data[DOMAIN][TUYA_DEVICES].items():
159158
if not device.connected:
160-
device.async_connect()
159+
hass.create_task(device.async_connect())
161160

162161
async_track_time_interval(hass, _async_reconnect, RECONNECT_INTERVAL)
163162

@@ -284,55 +283,38 @@ async def setup_entities(device_ids):
284283
)
285284
hass.data[DOMAIN][TUYA_DEVICES][dev_id] = TuyaDevice(hass, entry, dev_id)
286285

287-
await asyncio.gather(
288-
*[
289-
hass.config_entries.async_forward_entry_setup(entry, platform)
290-
for platform in platforms
291-
]
292-
)
293-
294-
for dev_id in device_ids:
295-
hass.data[DOMAIN][TUYA_DEVICES][dev_id].async_connect()
296-
297286
await async_remove_orphan_entities(hass, entry)
287+
await hass.config_entries.async_forward_entry_setups(entry, platforms)
298288

299-
hass.async_create_task(setup_entities(entry.data[CONF_DEVICES].keys()))
300-
289+
await setup_entities(entry.data[CONF_DEVICES].keys())
301290
unsub_listener = entry.add_update_listener(update_listener)
291+
302292
hass.data[DOMAIN][entry.entry_id] = {UNSUB_LISTENER: unsub_listener}
303293

304294
return True
305295

306296

307-
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
308-
"""Unload a config entry."""
297+
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
298+
"""Unloading the Tuya platforms."""
309299
platforms = {}
310-
311300
for dev_id, dev_entry in entry.data[CONF_DEVICES].items():
312301
for entity in dev_entry[CONF_ENTITIES]:
313302
platforms[entity[CONF_PLATFORM]] = True
314303

315-
unload_ok = all(
316-
await asyncio.gather(
317-
*[
318-
hass.config_entries.async_forward_entry_unload(entry, component)
319-
for component in platforms
320-
]
321-
)
322-
)
304+
unload_ok = await hass.config_entries.async_unload_platforms(entry, platforms)
323305

324-
hass.data[DOMAIN][entry.entry_id][UNSUB_LISTENER]()
325306
for dev_id, device in hass.data[DOMAIN][TUYA_DEVICES].items():
326307
if device.connected:
327308
await device.close()
328309

329310
if unload_ok:
311+
hass.data[DOMAIN][entry.entry_id][UNSUB_LISTENER]()
330312
hass.data[DOMAIN][TUYA_DEVICES] = {}
331313

332-
return True
314+
return unload_ok
333315

334316

335-
async def update_listener(hass, config_entry):
317+
async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry):
336318
"""Update listener."""
337319
await hass.config_entries.async_reload(config_entry.entry_id)
338320

Diff for: custom_components/localtuya/common.py

+14-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import time
55
from datetime import timedelta
66

7+
from homeassistant.core import HomeAssistant
8+
from homeassistant.config_entries import ConfigEntry
9+
710
from homeassistant.const import (
811
CONF_DEVICE_ID,
912
CONF_DEVICES,
@@ -31,6 +34,7 @@
3134
ATTR_UPDATED_AT,
3235
CONF_DEFAULT_VALUE,
3336
CONF_ENABLE_DEBUG,
37+
CONF_NODE_ID,
3438
CONF_LOCAL_KEY,
3539
CONF_MODEL,
3640
CONF_PASSIVE_ENTITY,
@@ -41,6 +45,7 @@
4145
DOMAIN,
4246
TUYA_DEVICES,
4347
DEFAULT_CATEGORIES,
48+
ENTITY_CATEGORY,
4449
)
4550

4651
_LOGGER = logging.getLogger(__name__)
@@ -83,7 +88,6 @@ async def async_setup_entry(
8388
]
8489

8590
if entities_to_setup:
86-
8791
tuyainterface = hass.data[DOMAIN][TUYA_DEVICES][dev_id]
8892

8993
dps_config_fields = list(get_dps_for_platform(flow_schema))
@@ -134,7 +138,7 @@ def async_config_entry_by_device_id(hass, device_id):
134138
class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
135139
"""Cache wrapper for pytuya.TuyaInterface."""
136140

137-
def __init__(self, hass, config_entry, dev_id):
141+
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry, dev_id: str):
138142
"""Initialize the cache."""
139143
super().__init__()
140144
self._hass = hass
@@ -181,7 +185,7 @@ def async_connect(self):
181185
"""Connect to device if not already connected."""
182186
# self.info("async_connect: %d %r %r", self._is_closing, self._connect_task, self._interface)
183187
if not self._is_closing and self._connect_task is None and not self._interface:
184-
self._connect_task = asyncio.create_task(self._make_connection())
188+
self._connect_task = self._hass.create_task(self._make_connection())
185189

186190
async def _make_connection(self):
187191
"""Subscribe localtuya entity events."""
@@ -194,6 +198,7 @@ async def _make_connection(self):
194198
self._local_key,
195199
float(self._dev_config_entry[CONF_PROTOCOL_VERSION]),
196200
self._dev_config_entry.get(CONF_ENABLE_DEBUG, False),
201+
self._dev_config_entry.get(CONF_NODE_ID, None),
197202
self,
198203
)
199204
self._interface.add_dps_to_request(self.dps_to_request)
@@ -496,12 +501,12 @@ def entity_category(self) -> str:
496501
# Set Default values for unconfigured devices.
497502
if self.has_config(CONF_PLATFORM):
498503
platform = self._config[CONF_PLATFORM]
499-
if any(platform in i for i in DEFAULT_CATEGORIES["CONTROL"]):
500-
return None
501-
elif any(platform in i for i in DEFAULT_CATEGORIES["CONFIG"]):
502-
return EntityCategory.CONFIG
503-
elif any(platform in i for i in DEFAULT_CATEGORIES["DIAGNOSTIC"]):
504-
return EntityCategory.DIAGNOSTIC
504+
# Call default_category from config_flow to set default values!
505+
# This will be removed after a while, this is only made to convert who came from main integration.
506+
# new users will be forced to choose category from config_flow.
507+
from .config_flow import default_category
508+
509+
return default_category(platform)
505510
return None
506511

507512
def dps(self, dp_index):

0 commit comments

Comments
 (0)