|
|
@@ -287,9 +287,17 @@ class TuyaDpsConfig:
|
|
|
for m in self._config["mapping"]:
|
|
|
if "value" in m:
|
|
|
val.append(m["value"])
|
|
|
+ # If there is a mirroring with no value override, use current value
|
|
|
+ elif "value_mirror" in m:
|
|
|
+ r_dps = self._entity.find_dps(m["value_mirror"])
|
|
|
+ val.append(r_dps.get_value(device))
|
|
|
for c in m.get("conditions", {}):
|
|
|
if "value" in c:
|
|
|
val.append(c["value"])
|
|
|
+ elif "value_mirror" in c:
|
|
|
+ r_dps = self._entity.find_dps(c["value_mirror"])
|
|
|
+ val.append(r_dps.get_value(device))
|
|
|
+
|
|
|
cond = self._active_condition(m, device)
|
|
|
if cond and "mapping" in cond:
|
|
|
_LOGGER.debug("Considering conditional mappings")
|
|
|
@@ -297,6 +305,9 @@ class TuyaDpsConfig:
|
|
|
for m2 in cond["mapping"]:
|
|
|
if "value" in m2:
|
|
|
c_val.append(m2["value"])
|
|
|
+ elif "value_mirror" in m:
|
|
|
+ r_dps = self._entity.find_dps(m["value_mirror"])
|
|
|
+ c_val.append(r_dps.get_value(device))
|
|
|
# if given, the conditional mapping is an override
|
|
|
if c_val:
|
|
|
_LOGGER.debug(f"Overriding {self.name} values {val} with {c_val}")
|
|
|
@@ -356,7 +367,7 @@ class TuyaDpsConfig:
|
|
|
return self._config.get("readonly", False)
|
|
|
|
|
|
def invalid_for(self, value, device):
|
|
|
- mapping = self._find_map_for_value(value)
|
|
|
+ mapping = self._find_map_for_value(value, device)
|
|
|
if mapping:
|
|
|
cond = self._active_condition(mapping, device)
|
|
|
if cond:
|
|
|
@@ -402,6 +413,7 @@ class TuyaDpsConfig:
|
|
|
if not isinstance(scale, (int, float)):
|
|
|
scale = 1
|
|
|
redirect = mapping.get("value_redirect")
|
|
|
+ mirror = mapping.get("value_mirror")
|
|
|
replaced = "value" in mapping
|
|
|
result = mapping.get("value", result)
|
|
|
cond = self._active_condition(mapping, device)
|
|
|
@@ -412,7 +424,7 @@ class TuyaDpsConfig:
|
|
|
result = cond.get("value", result)
|
|
|
scale = cond.get("scale", scale)
|
|
|
redirect = cond.get("value_redirect", redirect)
|
|
|
-
|
|
|
+ mirror = cond.get("value_mirror", mirror)
|
|
|
for m in cond.get("mapping", {}):
|
|
|
if str(m.get("dps_val")) == str(result):
|
|
|
replaced = "value" in m
|
|
|
@@ -422,6 +434,9 @@ class TuyaDpsConfig:
|
|
|
_LOGGER.debug(f"Redirecting {self.name} to {redirect}")
|
|
|
r_dps = self._entity.find_dps(redirect)
|
|
|
return r_dps.get_value(device)
|
|
|
+ if mirror:
|
|
|
+ r_dps = self._entity.find_dps(mirror)
|
|
|
+ return r_dps.get_value(device)
|
|
|
|
|
|
if scale != 1 and isinstance(result, (int, float)):
|
|
|
result = result / scale
|
|
|
@@ -438,16 +453,25 @@ class TuyaDpsConfig:
|
|
|
|
|
|
return result
|
|
|
|
|
|
- def _find_map_for_value(self, value):
|
|
|
+ def _find_map_for_value(self, value, device):
|
|
|
default = None
|
|
|
for m in self._config.get("mapping", {}):
|
|
|
if "dps_val" not in m:
|
|
|
default = m
|
|
|
if "value" in m and str(m["value"]) == str(value):
|
|
|
return m
|
|
|
+ if "value" not in m and "value_mirror" in m:
|
|
|
+ r_dps = self._entity.find_dps(m["value_mirror"])
|
|
|
+ if str(r_dps.get_value(device)) == str(value):
|
|
|
+ return m
|
|
|
+
|
|
|
for c in m.get("conditions", {}):
|
|
|
- if "value" in c and c["value"] == value:
|
|
|
+ if "value" in c and str(c["value"]) == str(value):
|
|
|
return m
|
|
|
+ if "value" not in c and "value_mirror" in c:
|
|
|
+ r_dps = self._entity.find_dps(c["value_mirror"])
|
|
|
+ if str(r_dps.get_value(device)) == str(value):
|
|
|
+ return m
|
|
|
return default
|
|
|
|
|
|
def _active_condition(self, mapping, device, value=None):
|
|
|
@@ -471,7 +495,7 @@ class TuyaDpsConfig:
|
|
|
"""Return the dps values that would be set when setting to value"""
|
|
|
result = value
|
|
|
dps_map = {}
|
|
|
- mapping = self._find_map_for_value(value)
|
|
|
+ mapping = self._find_map_for_value(value, device)
|
|
|
if mapping:
|
|
|
replaced = False
|
|
|
scale = mapping.get("scale", 1)
|
|
|
@@ -487,7 +511,13 @@ class TuyaDpsConfig:
|
|
|
# Conditions may have side effect of setting another value.
|
|
|
cond = self._active_condition(mapping, device, value)
|
|
|
if cond:
|
|
|
- if cond.get("value") == value:
|
|
|
+ cval = cond.get("value")
|
|
|
+ if cval is None:
|
|
|
+ r_dps = cond.get("value_mirror")
|
|
|
+ if r_dps:
|
|
|
+ cval = self._entity.find_dps(r_dps).get_value(device)
|
|
|
+
|
|
|
+ if cval == value:
|
|
|
c_dps = self._entity.find_dps(mapping["constraint"])
|
|
|
c_val = c_dps._map_from_dps(
|
|
|
cond.get("dps_val", device.get_property(c_dps.id)),
|
|
|
@@ -512,7 +542,7 @@ class TuyaDpsConfig:
|
|
|
if scale != 1 and isinstance(result, (int, float)):
|
|
|
_LOGGER.debug(f"Scaling {result} by {scale}")
|
|
|
result = result * scale
|
|
|
- remap = self._find_map_for_value(result)
|
|
|
+ remap = self._find_map_for_value(result, device)
|
|
|
if remap and "dps_val" in remap and "dps_val" not in mapping:
|
|
|
result = remap["dps_val"]
|
|
|
replaced = True
|
|
|
@@ -520,7 +550,7 @@ class TuyaDpsConfig:
|
|
|
if step and isinstance(result, (int, float)):
|
|
|
_LOGGER.debug(f"Stepping {result} to {step}")
|
|
|
result = step * round(float(result) / step)
|
|
|
- remap = self._find_map_for_value(result)
|
|
|
+ remap = self._find_map_for_value(result, device)
|
|
|
if remap and "dps_val" in remap and "dps_val" not in mapping:
|
|
|
result = remap["dps_val"]
|
|
|
replaced = True
|