Update device_config.py - add support for bitwise masking on integer DPs #4220
+29
−8
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Its been a while since I was this deep in the weeds with Python but here we go...
Feel free to edit however you prefer!
This PR addresses an issue where using the mask parameter on data points of type: integer would result in correctable crashes and incorrect data parsing. This is required due to at least one device (Inkbird IVC-001W) that presents DPs in this fashion but I am sure that there are others out there.
Previously, the masking logic in device_config.py assumed that any masked value was a byte array (hex/base64). This caused two issues for packed integers (e.g., two 16-bit values packed into a 32-bit integer):
On read: The mask was ignored, returning the full raw integer instead of the specific bit range.
On write: The integration crashed with cannot convert 'float' object to bytes because it attempted to pass a numeric value into int.from_bytes.
Changes:
Updated get_value to check if the raw value is an integer. If so, it applies the mask and bit-shift directly without byte conversion.
Updated get_values_to_set to implement a "Read-Modify-Write" cycle for integers. It reads the current device state, clears the masked bits, and merges the new value, ensuring the unmasked parts of the integer remain untouched.
Backwards compatibility notes: The new logic only triggers if mask is defined and the raw value is an integer; existing hex/base64 implementations are unaffected.