Browse Source

Handle bitfields specially in mappings.

Until now, bitfields were just handled as integers, as we only ever
knew of one error code for devices that use them.

SmartMCB had documentation through the Tuya portal of the error field,
so we could add all the possible values, some of which could
conceivably happen concurrently, so it is time to treat bitfields
separately from integers where needed.
Jason Rumney 4 years ago
parent
commit
9678cbeb22

+ 11 - 1
custom_components/tuya_local/helpers/device_config.py

@@ -261,6 +261,16 @@ class TuyaDpsConfig:
         """Return the value of the dps from the given device."""
         return self._map_from_dps(device.get_property(self.id), device)
 
+    def _match(self, matchdata, value):
+        """Return true val1 matches val2"""
+        if self._config["type"] == "bitfield" and matchdata:
+            try:
+                return (int(value) & int(matchdata)) != 0
+            except BaseException:
+                return False
+        else:
+            return str(value) == str(matchdata)
+
     async def async_set_value(self, device, value):
         """Set the value of the dps in the given device to given value."""
         if self.readonly:
@@ -387,7 +397,7 @@ class TuyaDpsConfig:
         for m in self._config.get("mapping", {}):
             if "dps_val" not in m:
                 default = m
-            elif str(m["dps_val"]) == str(value):
+            elif self._match(m["dps_val"], value):
                 return m
         return default
 

+ 9 - 0
tests/devices/test_smartmcb_smt006_energymeter.py

@@ -249,3 +249,12 @@ class TestSmartMcbSMT006EnergyMeter(
                 "breaker_number": "Breaker Number",
             },
         )
+
+    def test_multiple_concurrent_errors(self):
+        self.dps[ERROR_DPS] = 15
+        self.assertTrue(self.multiBSensor["binary_sensor_short_circuit"].is_on)
+        self.assertTrue(self.multiBSensor["binary_sensor_surge"].is_on)
+        self.assertTrue(self.multiBSensor["binary_sensor_overload"].is_on)
+        self.assertTrue(self.multiBSensor["binary_sensor_leakage_current"].is_on)
+        self.assertFalse(self.multiBSensor["binary_sensor_high_temperature"].is_on)
+        self.assertFalse(self.multiBSensor["binary_sensor_fire"].is_on)