Cover uppercase and new commands (#81)

* Introduced uppercase detection for cover commands
* Added FZ_ZZ as open_close available commands for covers
* Added FZ_ZZ in the YAML config example
* Introduced invert_position Option for cover
* Cover slider inverted properly
* Fixed wrong sample YAML config for cover
* Fixed postlund's remark
This commit is contained in:
rospogrigio
2020-10-21 10:23:00 +02:00
committed by GitHub
parent 3bc16739d9
commit 032fceac2e
6 changed files with 27 additions and 13 deletions

View File

@@ -1,7 +1,5 @@
![logo](https://github.com/rospogrigio/localtuya-homeassistant/blob/master/img/logo-small.png) ![logo](https://github.com/rospogrigio/localtuya-homeassistant/blob/master/img/logo-small.png)
# localtuya-homeassistant
A Home Assistant custom Integration for local handling of Tuya-based devices. A Home Assistant custom Integration for local handling of Tuya-based devices.
Device status is updated receiving push updates from the device instead of polling, so status updates are extremely fast (even if manually operated). Device status is updated receiving push updates from the device instead of polling, so status updates are extremely fast (even if manually operated).

View File

@@ -20,11 +20,12 @@ localtuya:
- platform: cover - platform: cover
friendly_name: Device Cover friendly_name: Device Cover
id: 2 id: 2
open_close_stop_cmds: # Optional, default: "on_off_stop" commands_set: # Optional, default: "on_off_stop"
["on_off_stop","open_close_stop","fz_zz_stop","1_2_3"] ["on_off_stop","open_close_stop","fz_zz_stop","1_2_3"]
positioning_mode: ["none","position","fake"] # Optional, default: "none" positioning_mode: ["none","position","fake"] # Optional, default: "none"
currpos_dp: 3 # Optional, required only for "position" mode currpos_dp: 3 # Optional, required only for "position" mode
setpos_dp: 4 # Optional, required only for "position" mode setpos_dp: 4 # Optional, required only for "position" mode
position_inverted: [True,False] # Optional, default: False
span_time: 25 # Full movement time: Optional, required only for "fake" mode span_time: 25 # Full movement time: Optional, required only for "fake" mode
- platform: fan - platform: fan

View File

@@ -22,6 +22,7 @@ CONF_COMMANDS_SET = "commands_set"
CONF_POSITIONING_MODE = "positioning_mode" CONF_POSITIONING_MODE = "positioning_mode"
CONF_CURRENT_POSITION_DP = "current_position_dp" CONF_CURRENT_POSITION_DP = "current_position_dp"
CONF_SET_POSITION_DP = "set_position_dp" CONF_SET_POSITION_DP = "set_position_dp"
CONF_POSITION_INVERTED = "position_inverted"
CONF_SPAN_TIME = "span_time" CONF_SPAN_TIME = "span_time"
# sensor # sensor

View File

@@ -20,6 +20,7 @@ from .const import (
CONF_CURRENT_POSITION_DP, CONF_CURRENT_POSITION_DP,
CONF_SET_POSITION_DP, CONF_SET_POSITION_DP,
CONF_POSITIONING_MODE, CONF_POSITIONING_MODE,
CONF_POSITION_INVERTED,
CONF_SPAN_TIME, CONF_SPAN_TIME,
) )
from .common import LocalTuyaEntity, async_setup_entry from .common import LocalTuyaEntity, async_setup_entry
@@ -50,6 +51,7 @@ def flow_schema(dps):
), ),
vol.Optional(CONF_CURRENT_POSITION_DP): vol.In(dps), vol.Optional(CONF_CURRENT_POSITION_DP): vol.In(dps),
vol.Optional(CONF_SET_POSITION_DP): vol.In(dps), vol.Optional(CONF_SET_POSITION_DP): vol.In(dps),
vol.Optional(CONF_POSITION_INVERTED, default=False): bool,
vol.Optional(CONF_SPAN_TIME, default=DEFAULT_SPAN_TIME): vol.All( vol.Optional(CONF_SPAN_TIME, default=DEFAULT_SPAN_TIME): vol.All(
vol.Coerce(float), vol.Range(min=1.0, max=300.0) vol.Coerce(float), vol.Range(min=1.0, max=300.0)
), ),
@@ -70,12 +72,12 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
super().__init__(device, config_entry, switchid, **kwargs) super().__init__(device, config_entry, switchid, **kwargs)
self._state = None self._state = None
self._current_cover_position = None self._current_cover_position = None
command_set = DEFAULT_COMMANDS_SET commands_set = DEFAULT_COMMANDS_SET
if self.has_config(CONF_COMMANDS_SET): if self.has_config(CONF_COMMANDS_SET):
command_set = self._config[CONF_COMMANDS_SET] commands_set = self._config[CONF_COMMANDS_SET]
self._open_cmd = command_set.split("_")[0] self._open_cmd = commands_set.split("_")[0]
self._close_cmd = command_set.split("_")[1] self._close_cmd = commands_set.split("_")[1]
self._stop_cmd = command_set.split("_")[2] self._stop_cmd = commands_set.split("_")[2]
print("Initialized cover [{}]".format(self.name)) print("Initialized cover [{}]".format(self.name))
@property @property
@@ -108,6 +110,7 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
"""Return if the cover is open or not.""" """Return if the cover is open or not."""
if self._config[CONF_POSITIONING_MODE] != COVER_MODE_POSITION: if self._config[CONF_POSITIONING_MODE] != COVER_MODE_POSITION:
return None return None
return self._current_cover_position == 100 return self._current_cover_position == 100
@property @property
@@ -115,6 +118,7 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
"""Return if the cover is closed or not.""" """Return if the cover is closed or not."""
if self._config[CONF_POSITIONING_MODE] != COVER_MODE_POSITION: if self._config[CONF_POSITIONING_MODE] != COVER_MODE_POSITION:
return None return None
return self._current_cover_position == 0 return self._current_cover_position == 0
async def async_set_cover_position(self, **kwargs): async def async_set_cover_position(self, **kwargs):
@@ -139,6 +143,9 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
elif self._config[CONF_POSITIONING_MODE] == COVER_MODE_POSITION: elif self._config[CONF_POSITIONING_MODE] == COVER_MODE_POSITION:
converted_position = int(kwargs[ATTR_POSITION]) converted_position = int(kwargs[ATTR_POSITION])
if self._config[CONF_POSITION_INVERTED]:
converted_position = 100 - converted_position
if 0 <= converted_position <= 100 and self.has_config(CONF_SET_POSITION_DP): if 0 <= converted_position <= 100 and self.has_config(CONF_SET_POSITION_DP):
await self._device.set_dp( await self._device.set_dp(
converted_position, self._config[CONF_SET_POSITION_DP] converted_position, self._config[CONF_SET_POSITION_DP]
@@ -162,10 +169,17 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
def status_updated(self): def status_updated(self):
"""Device status was updated.""" """Device status was updated."""
self._state = self.dps(self._dp_id) self._state = self.dps(self._dp_id)
if self._state.isupper():
self._open_cmd = self._open_cmd.upper()
self._close_cmd = self._close_cmd.upper()
self._stop_cmd = self._stop_cmd.upper()
if self.has_config(CONF_CURRENT_POSITION_DP): if self.has_config(CONF_CURRENT_POSITION_DP):
self._current_cover_position = self.dps( curr_pos = self.dps_conf(CONF_CURRENT_POSITION_DP)
self._config[CONF_CURRENT_POSITION_DP] if self._config[CONF_POSITION_INVERTED]:
) self._current_cover_position = 100 - curr_pos
else:
self._current_cover_position = curr_pos
else: else:
self._current_cover_position = 50 self._current_cover_position = 50

View File

@@ -50,6 +50,7 @@
"positioning_mode": "Positioning mode", "positioning_mode": "Positioning mode",
"current_position_dp": "Current Position (when Position mode is *position*)", "current_position_dp": "Current Position (when Position mode is *position*)",
"set_position_dp": "Set Position (when Position Mode is *position*)", "set_position_dp": "Set Position (when Position Mode is *position*)",
"position_inverted": "Invert 0-100 position (when Position Mode is *position*)",
"span_time": "Full opening time, in secs. (when Position Mode is fake*)", "span_time": "Full opening time, in secs. (when Position Mode is fake*)",
"unit_of_measurement": "Unit of Measurement", "unit_of_measurement": "Unit of Measurement",
"device_class": "Device Class", "device_class": "Device Class",
@@ -89,6 +90,7 @@
"positioning_mode": "Positioning mode", "positioning_mode": "Positioning mode",
"current_position_dp": "Current Position (for *position* mode only)", "current_position_dp": "Current Position (for *position* mode only)",
"set_position_dp": "Set Position (for *position* mode only)", "set_position_dp": "Set Position (for *position* mode only)",
"position_inverted": "Invert 0-100 position (when Position Mode is *position*)",
"span_time": "Full opening time, in secs. (for *fake* mode only)", "span_time": "Full opening time, in secs. (for *fake* mode only)",
"unit_of_measurement": "Unit of Measurement", "unit_of_measurement": "Unit of Measurement",
"device_class": "Device Class", "device_class": "Device Class",

View File

@@ -4,8 +4,6 @@
![logo](https://github.com/rospogrigio/localtuya-homeassistant/blob/master/img/logo-small.png) ![logo](https://github.com/rospogrigio/localtuya-homeassistant/blob/master/img/logo-small.png)
# localtuya-homeassistant
A Home Assistant custom Integration for local handling of Tuya-based devices. A Home Assistant custom Integration for local handling of Tuya-based devices.
Device status is updated receiving push updates from the device instead of polling, so status updates are extremely fast (even if manually operated). Device status is updated receiving push updates from the device instead of polling, so status updates are extremely fast (even if manually operated).