|
|
@@ -476,7 +476,10 @@ class TuyaDpsConfig:
|
|
|
def get_value(self, device):
|
|
|
"""Return the value of the dps from the given device."""
|
|
|
mask = self.mask
|
|
|
- bytevalue = self.decoded_value(device)
|
|
|
+ # Get raw value directly avoiding accidental scaling by decoded_value()
|
|
|
+ raw_from_device = device.get_property(self.id)
|
|
|
+ bytevalue = self.decode_value(raw_from_device, device)
|
|
|
+
|
|
|
if mask and isinstance(bytevalue, bytes):
|
|
|
value = int.from_bytes(bytevalue, self.endianness)
|
|
|
scale = mask & (1 + ~mask)
|
|
|
@@ -489,8 +492,15 @@ class TuyaDpsConfig:
|
|
|
raw_result = to_signed(raw_result, bit_count)
|
|
|
|
|
|
return self._map_from_dps(raw_result, device)
|
|
|
+
|
|
|
+ elif mask and isinstance(bytevalue, int):
|
|
|
+ # Handle masking for integer DPs
|
|
|
+ scale = mask & (1 + ~mask)
|
|
|
+ raw_result = (bytevalue & mask) // scale
|
|
|
+ return self._map_from_dps(raw_result, device)
|
|
|
+
|
|
|
else:
|
|
|
- return self._map_from_dps(device.get_property(self.id), device)
|
|
|
+ return self._map_from_dps(raw_from_device, device)
|
|
|
|
|
|
def decoded_value(self, device):
|
|
|
v = self._map_from_dps(device.get_property(self.id), device)
|
|
|
@@ -1072,14 +1082,25 @@ class TuyaDpsConfig:
|
|
|
# Convert to int
|
|
|
endianness = self.endianness
|
|
|
mask_scale = mask & (1 + ~mask)
|
|
|
- decoded_value = self.decoded_value(device)
|
|
|
- # if we have already updated it as part of this update,
|
|
|
- # use it to preserve bits
|
|
|
+
|
|
|
+ # Get raw current value directly (avoids scaling being auto applied as it causes issues)
|
|
|
+ raw_current = device.get_property(self.id)
|
|
|
if self.id in pending_map:
|
|
|
decoded_value = self.decode_value(pending_map[self.id], device)
|
|
|
- current_value = int.from_bytes(decoded_value, endianness)
|
|
|
- result = (current_value & ~mask) | (mask & int(result * mask_scale))
|
|
|
- result = self.encode_value(result.to_bytes(length, endianness))
|
|
|
+ else:
|
|
|
+ decoded_value = self.decode_value(raw_current, device)
|
|
|
+
|
|
|
+ if isinstance(decoded_value, int):
|
|
|
+ current_value = decoded_value
|
|
|
+ result = (current_value & ~mask) | (mask & int(result * mask_scale))
|
|
|
+ # Only convert back to bytes if the DP is actually hex/base64
|
|
|
+ if self.rawtype in ["hex", "base64", "utf16b64"]:
|
|
|
+ result = self.encode_value(result.to_bytes(length, endianness))
|
|
|
+ else:
|
|
|
+ # Bytes path (original logic)
|
|
|
+ current_value = int.from_bytes(decoded_value, endianness)
|
|
|
+ result = (current_value & ~mask) | (mask & int(result * mask_scale))
|
|
|
+ result = self.encode_value(result.to_bytes(length, endianness))
|
|
|
|
|
|
dps_map[self.id] = self._correct_type(result)
|
|
|
return dps_map
|