Merge branch 'master' into fix_semaphore_release_error

This commit is contained in:
sibowler
2023-01-23 13:00:56 +10:00
20 changed files with 732 additions and 263 deletions

View File

@@ -24,10 +24,11 @@ assignees: ''
Provide details about your environment.
-->
- Localtuya version: <!-- plugin version from HACS, master, commit id -->
- Last working localtuya version (if known and relevant):
- Home Assistant Core version: <!-- Configuration => Info -->
- [] Are you using the Home Assistant Tuya Cloud component ? <!-- if yes, put a x between the two [] => [x] -->
- [] Are you using the Tuya App in parallel ? <!-- if yes, put a x between the two [] => [x] -->
- [] Does the device work using the Home Assistant Tuya Cloud component ? <!-- if yes, put a x between the two [] => [x] -->
- [] Does the device work using the Tinytuya (https://github.com/jasonacox/tinytuya) command line tool ? <!-- if yes, put a x between the two [] => [x] -->
- [] Was the device working with earlier versions of localtuya ? Which one? <!-- if yes, put a x between the two [] => [x] -->
- [] Are you using the Tuya/SmartLife App in parallel ? <!-- if yes, put a x between the two [] => [x] -->
## Steps to reproduce
<!--
@@ -37,14 +38,6 @@ assignees: ''
2.
3.
## Configuration `configuration.yaml` or `config_flow`
<!--
Fill this with the yaml or config_flow configuration of the failing device. Even if it seems unimportant to you.
Remove personal information and local key.
-->
```yaml
```
## DP dump
<!--
@@ -52,17 +45,20 @@ assignees: ''
You can also try to qualify your device using the procedure described https://github.com/rospogrigio/localtuya/wiki/Qualifying-a-device
-->
## Provide Home Assistant taceback/logs
## Provide Home Assistant traceback/logs
<!--
Provide traces if they are relevant. If the problem is reproducible, try to set the log level to debug for this component at least:
In Dev Tools => Services:
Provide logs if they are relevant. In detail, it is useful to be able to compare working with non-working situations, such as HA logs compared to the output of the tuyadebug script or the tinytuya CLI tool.
To increase the debugging level of HA for the devices, check the "enable debug" button when configuring the device, and set the log level to debug for this component at least:
In configuration.yaml:
logger.set_level
custom_components.localtuya: debug
custom_components.localtuya.pytuya: debug
-->
```txt
```
put your log output between these markers
```
## Additional information
<!-- Put here any information that you think it may be relevant -->

View File

@@ -19,7 +19,7 @@ The following Tuya device types are currently supported:
Energy monitoring (voltage, current, watts, etc.) is supported for compatible devices.
> **Currently, only Tuya protocols 3.1 and 3.3 are supported (3.4 is not).**
> **Currently, Tuya protocols from 3.1 to 3.4 are supported.**
This repository's development began as code from [@NameLessJedi](https://github.com/NameLessJedi), [@mileperhour](https://github.com/mileperhour) and [@TradeFace](https://github.com/TradeFace). Their code was then deeply refactored to provide proper integration with Home Assistant environment, adding config flow and other features. Refer to the "Thanks to" section below.
@@ -164,8 +164,11 @@ logger:
default: warning
logs:
custom_components.localtuya: debug
custom_components.localtuya.pytuya: debug
```
Then, edit the device that is showing problems and check the "Enable debugging for this device" button.
# Notes:
* Do not declare anything as "tuya", such as by initiating a "switch.tuya". Using "tuya" launches Home Assistant's built-in, cloud-based Tuya integration in lieu of localtuya.
@@ -177,8 +180,6 @@ logger:
* Everything listed in https://github.com/rospogrigio/localtuya-homeassistant/issues/15
* Support devices that use Tuya protocol v.3.4
# Thanks to:
NameLessJedi https://github.com/NameLessJedi/localtuya-homeassistant and mileperhour https://github.com/mileperhour/localtuya-homeassistant being the major sources of inspiration, and whose code for switches is substantially unchanged.
@@ -187,6 +188,8 @@ TradeFace, for being the only one to provide the correct code for communication
sean6541, for the working (standard) Python Handler for Tuya devices.
jasonacox, for the TinyTuya project from where I could import the code to communicate with devices using protocol 3.4.
postlund, for the ideas, for coding 95% of the refactoring and boosting the quality of this repo to levels hard to imagine (by me, at least) and teaching me A LOT of how things work in Home Assistant.
<a href="https://www.buymeacoffee.com/rospogrigio" target="_blank"><img src="https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>

View File

@@ -25,18 +25,19 @@ from homeassistant.helpers.restore_state import RestoreEntity
from . import pytuya
from .const import (
ATTR_STATE,
ATTR_UPDATED_AT,
CONF_DEFAULT_VALUE,
CONF_ENABLE_DEBUG,
CONF_LOCAL_KEY,
CONF_MODEL,
CONF_PASSIVE_ENTITY,
CONF_PROTOCOL_VERSION,
CONF_RESET_DPIDS,
CONF_RESTORE_ON_RECONNECT,
DATA_CLOUD,
DOMAIN,
TUYA_DEVICES,
CONF_DEFAULT_VALUE,
ATTR_STATE,
CONF_RESTORE_ON_RECONNECT,
CONF_RESET_DPIDS,
CONF_PASSIVE_ENTITY,
)
_LOGGER = logging.getLogger(__name__)
@@ -188,6 +189,7 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
self._dev_config_entry[CONF_DEVICE_ID],
self._local_key,
float(self._dev_config_entry[CONF_PROTOCOL_VERSION]),
self._dev_config_entry.get(CONF_ENABLE_DEBUG, False),
self,
)
self._interface.add_dps_to_request(self.dps_to_request)

View File

@@ -33,7 +33,9 @@ from .const import (
CONF_ADD_DEVICE,
CONF_DPS_STRINGS,
CONF_EDIT_DEVICE,
CONF_ENABLE_DEBUG,
CONF_LOCAL_KEY,
CONF_MANUAL_DPS,
CONF_MODEL,
CONF_NO_CLOUD,
CONF_PRODUCT_NAME,
@@ -45,7 +47,6 @@ from .const import (
DATA_DISCOVERY,
DOMAIN,
PLATFORMS,
CONF_MANUAL_DPS,
)
from .discovery import discover
@@ -82,26 +83,17 @@ CLOUD_SETUP_SCHEMA = vol.Schema(
}
)
CONFIGURE_DEVICE_SCHEMA = vol.Schema(
{
vol.Required(CONF_FRIENDLY_NAME): str,
vol.Required(CONF_LOCAL_KEY): str,
vol.Required(CONF_HOST): str,
vol.Required(CONF_DEVICE_ID): str,
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(["3.1", "3.3"]),
vol.Optional(CONF_SCAN_INTERVAL): int,
vol.Optional(CONF_MANUAL_DPS): str,
vol.Optional(CONF_RESET_DPIDS): str,
}
)
DEVICE_SCHEMA = vol.Schema(
{
vol.Required(CONF_FRIENDLY_NAME): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_DEVICE_ID): cv.string,
vol.Required(CONF_LOCAL_KEY): cv.string,
vol.Required(CONF_FRIENDLY_NAME): cv.string,
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(["3.1", "3.3"]),
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(
["3.1", "3.2", "3.3", "3.4"]
),
vol.Required(CONF_ENABLE_DEBUG, default=False): bool,
vol.Optional(CONF_SCAN_INTERVAL): int,
vol.Optional(CONF_MANUAL_DPS): cv.string,
vol.Optional(CONF_RESET_DPIDS): str,
@@ -141,13 +133,16 @@ def options_schema(entities):
]
return vol.Schema(
{
vol.Required(CONF_FRIENDLY_NAME): str,
vol.Required(CONF_HOST): str,
vol.Required(CONF_LOCAL_KEY): str,
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(["3.1", "3.3"]),
vol.Optional(CONF_SCAN_INTERVAL): int,
vol.Optional(CONF_MANUAL_DPS): str,
vol.Optional(CONF_RESET_DPIDS): str,
vol.Required(CONF_FRIENDLY_NAME): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_LOCAL_KEY): cv.string,
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(
["3.1", "3.2", "3.3", "3.4"]
),
vol.Required(CONF_ENABLE_DEBUG, default=False): bool,
vol.Optional(CONF_SCAN_INTERVAL): cv.string,
vol.Optional(CONF_MANUAL_DPS): cv.string,
vol.Optional(CONF_RESET_DPIDS): cv.string,
vol.Required(
CONF_ENTITIES, description={"suggested_value": entity_names}
): cv.multi_select(entity_names),
@@ -247,6 +242,7 @@ async def validate_input(hass: core.HomeAssistant, data):
data[CONF_DEVICE_ID],
data[CONF_LOCAL_KEY],
float(data[CONF_PROTOCOL_VERSION]),
data[CONF_ENABLE_DEBUG],
)
if CONF_RESET_DPIDS in data:
reset_ids_str = data[CONF_RESET_DPIDS].split(",")
@@ -564,6 +560,11 @@ class LocalTuyaOptionsFlowHandler(config_entries.OptionsFlow):
CONF_ENTITIES: [],
}
)
if len(user_input[CONF_ENTITIES]) == 0:
return self.async_abort(
reason="no_entities",
description_placeholders={},
)
if user_input[CONF_ENTITIES]:
entity_ids = [
int(entity.split(":")[0])
@@ -611,7 +612,7 @@ class LocalTuyaOptionsFlowHandler(config_entries.OptionsFlow):
if dev_id in cloud_devs:
defaults[CONF_LOCAL_KEY] = cloud_devs[dev_id].get(CONF_LOCAL_KEY)
defaults[CONF_FRIENDLY_NAME] = cloud_devs[dev_id].get(CONF_NAME)
schema = schema_defaults(CONFIGURE_DEVICE_SCHEMA, **defaults)
schema = schema_defaults(DEVICE_SCHEMA, **defaults)
placeholders = {"for_device": ""}

View File

@@ -28,6 +28,7 @@ ATTR_UPDATED_AT = "updated_at"
# config flow
CONF_LOCAL_KEY = "local_key"
CONF_ENABLE_DEBUG = "enable_debug"
CONF_PROTOCOL_VERSION = "protocol_version"
CONF_DPS_STRINGS = "dps_strings"
CONF_MODEL = "model"

View File

@@ -108,13 +108,13 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
def is_closed(self):
"""Return if the cover is closed or not."""
if self._config[CONF_POSITIONING_MODE] == COVER_MODE_NONE:
return None
return False
if self._current_cover_position == 0:
return True
if self._current_cover_position == 100:
return False
return None
return False
async def async_set_cover_position(self, **kwargs):
"""Move the cover to a specific position."""

View File

@@ -27,12 +27,12 @@ from .const import (
CONF_FAN_DIRECTION,
CONF_FAN_DIRECTION_FWD,
CONF_FAN_DIRECTION_REV,
CONF_FAN_DPS_TYPE,
CONF_FAN_ORDERED_LIST,
CONF_FAN_OSCILLATING_CONTROL,
CONF_FAN_SPEED_CONTROL,
CONF_FAN_SPEED_MAX,
CONF_FAN_SPEED_MIN,
CONF_FAN_DPS_TYPE,
)
_LOGGER = logging.getLogger(__name__)

View File

@@ -1,7 +1,7 @@
{
"domain": "localtuya",
"name": "LocalTuya integration",
"version": "4.1.1",
"version": "5.0.0",
"documentation": "https://github.com/rospogrigio/localtuya/",
"dependencies": [],
"codeowners": [

View File

@@ -7,14 +7,13 @@ from homeassistant.components.number import DOMAIN, NumberEntity
from homeassistant.const import CONF_DEVICE_CLASS, STATE_UNKNOWN
from .common import LocalTuyaEntity, async_setup_entry
from .const import (
CONF_MIN_VALUE,
CONF_MAX_VALUE,
CONF_DEFAULT_VALUE,
CONF_MAX_VALUE,
CONF_MIN_VALUE,
CONF_PASSIVE_ENTITY,
CONF_RESTORE_ON_RECONNECT,
CONF_STEPSIZE_VALUE,
CONF_PASSIVE_ENTITY,
)
_LOGGER = logging.getLogger(__name__)

File diff suppressed because it is too large Load Diff

View File

@@ -4,19 +4,15 @@ from functools import partial
import voluptuous as vol
from homeassistant.components.select import DOMAIN, SelectEntity
from homeassistant.const import (
CONF_DEVICE_CLASS,
STATE_UNKNOWN,
)
from homeassistant.const import CONF_DEVICE_CLASS, STATE_UNKNOWN
from .common import LocalTuyaEntity, async_setup_entry
from .const import (
CONF_DEFAULT_VALUE,
CONF_OPTIONS,
CONF_OPTIONS_FRIENDLY,
CONF_DEFAULT_VALUE,
CONF_RESTORE_ON_RECONNECT,
CONF_PASSIVE_ENTITY,
CONF_RESTORE_ON_RECONNECT,
)

View File

@@ -9,14 +9,14 @@ from .common import LocalTuyaEntity, async_setup_entry
from .const import (
ATTR_CURRENT,
ATTR_CURRENT_CONSUMPTION,
ATTR_VOLTAGE,
ATTR_STATE,
ATTR_VOLTAGE,
CONF_CURRENT,
CONF_CURRENT_CONSUMPTION,
CONF_VOLTAGE,
CONF_DEFAULT_VALUE,
CONF_RESTORE_ON_RECONNECT,
CONF_PASSIVE_ENTITY,
CONF_RESTORE_ON_RECONNECT,
CONF_VOLTAGE,
)
_LOGGER = logging.getLogger(__name__)

View File

@@ -33,7 +33,8 @@
"options": {
"abort": {
"already_configured": "Device has already been configured.",
"device_success": "Device {dev_name} successfully {action}."
"device_success": "Device {dev_name} successfully {action}.",
"no_entities": "Cannot remove all entities from a device.\nIf you want to delete a device, enter it in the Devices menu, click the 3 dots in the 'Device info' frame, and press the Delete button."
},
"error": {
"authentication_failed": "Failed to authenticate.\n{msg}",
@@ -95,6 +96,7 @@
"device_id": "Device ID",
"local_key": "Local key",
"protocol_version": "Protocol Version",
"enable_debug": "Enable debugging for this device (debug must be enabled also in configuration.yaml)",
"scan_interval": "Scan interval (seconds, only when not updating automatically)",
"entities": "Entities (uncheck an entity to remove it)",
"manual_dps_strings": "Manual DPS to add (separated by commas ',') - used when detection is not working (optional)",

View File

@@ -33,7 +33,8 @@
"options": {
"abort": {
"already_configured": "Il dispositivo è già stato configurato.",
"device_success": "Dispositivo {dev_name} {action} con successo."
"device_success": "Dispositivo {dev_name} {action} con successo.",
"no_entities": "Non si possono rimuovere tutte le entities da un device.\nPer rimuovere un device, entrarci nel menu Devices, premere sui 3 punti nel riquadro 'Device info', e premere il pulsante Delete."
},
"error": {
"authentication_failed": "Autenticazione fallita. Errore:\n{msg}",
@@ -95,6 +96,7 @@
"device_id": "ID del dispositivo",
"local_key": "Chiave locale",
"protocol_version": "Versione del protocollo",
"enable_debug": "Abilita il debugging per questo device (il debug va abilitato anche in configuration.yaml)",
"scan_interval": "Intervallo di scansione (secondi, solo quando non si aggiorna automaticamente)",
"entities": "Entities (deseleziona un'entity per rimuoverla)"
}

View File

@@ -33,7 +33,8 @@
"options": {
"abort": {
"already_configured": "O dispositivo já foi configurado.",
"device_success": "Dispositivo {dev_name} {action} com sucesso."
"device_success": "Dispositivo {dev_name} {action} com sucesso.",
"no_entities": "Não é possível remover todas as entidades de um dispositivo.\nSe você deseja excluir um dispositivo, insira-o no menu Dispositivos, clique nos 3 pontos no quadro 'Informações do dispositivo' e pressione o botão Excluir."
},
"error": {
"authentication_failed": "Falha ao autenticar.\n{msg}",
@@ -95,6 +96,7 @@
"device_id": "ID do dispositivo",
"local_key": "Local key",
"protocol_version": "Versão do protocolo",
"enable_debug": "Ative a depuração para este dispositivo (a depuração também deve ser ativada em configuration.yaml)",
"scan_interval": "Intervalo de escaneamento (segundos, somente quando não estiver atualizando automaticamente)",
"entities": "Entidades (desmarque uma entidade para removê-la)"
}

11
info.md
View File

@@ -23,7 +23,7 @@ The following Tuya device types are currently supported:
Energy monitoring (voltage, current, watts, etc.) is supported for compatible devices.
> **Currently, only Tuya protocols 3.1 and 3.3 are supported (3.4 is not).**
> **Currently, Tuya protocols from 3.1 to 3.4 are supported.**
This repository's development began as code from [@NameLessJedi](https://github.com/NameLessJedi), [@mileperhour](https://github.com/mileperhour) and [@TradeFace](https://github.com/TradeFace). Their code was then deeply refactored to provide proper integration with Home Assistant environment, adding config flow and other features. Refer to the "Thanks to" section below.
@@ -164,8 +164,11 @@ logger:
default: warning
logs:
custom_components.localtuya: debug
custom_components.localtuya.pytuya: debug
```
Then, edit the device that is showing problems and check the "Enable debugging for this device" button.
# Notes:
* Do not declare anything as "tuya", such as by initiating a "switch.tuya". Using "tuya" launches Home Assistant's built-in, cloud-based Tuya integration in lieu of localtuya.
@@ -177,16 +180,16 @@ logger:
* Everything listed in https://github.com/rospogrigio/localtuya-homeassistant/issues/15
* Support devices that use Tuya protocol v.3.4
# Thanks to:
NameLessJedi https://github.com/NameLessJedi/localtuya-homeassistant and mileperhour https://github.com/mileperhour/localtuya-homeassistant being the major sources of inspiration, and whose code for switches is substantially unchanged.
TradeFace, for being the only one to provide the correct code for communication with the cover (in particular, the 0x0d command for the status instead of the 0x0a, and related needs such as double reply to be received): https://github.com/TradeFace/tuya/
TradeFace, for being the only one to provide the correct code for communication with the type_0d devices (in particular, the 0x0d command for the status instead of the 0x0a, and related needs such as double reply to be received): https://github.com/TradeFace/tuya/
sean6541, for the working (standard) Python Handler for Tuya devices.
jasonacox, for the TinyTuya project from where I could import the code to communicate with devices using protocol 3.4.
postlund, for the ideas, for coding 95% of the refactoring and boosting the quality of this repo to levels hard to imagine (by me, at least) and teaching me A LOT of how things work in Home Assistant.
<a href="https://www.buymeacoffee.com/rospogrigio" target="_blank"><img src="https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>

View File

@@ -174,7 +174,9 @@ disable=line-too-long,
unused-variable,
invalid-name,
dangerous-default-value,
unreachable
unreachable,
unnecessary-pass,
broad-except
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option

View File

@@ -1,10 +1,10 @@
[flake8]
exclude = .git,.tox
max-line-length = 88
max-line-length = 120
ignore = E203, W503
[mypy]
python_version = 3.7
python_version = 3.9
ignore_errors = true
follow_imports = silent
ignore_missing_imports = true

View File

@@ -10,7 +10,7 @@ python =
3.9: clean, py39, lint, typing
[testenv]
passenv = TOXENV CI
passenv = TOXENV,CI
whitelist_externals =
true
setenv =

Binary file not shown.