Created
November 15, 2017 10:22
-
-
Save manchoz/8b0c859fb502074c420ffb2f0025cf56 to your computer and use it in GitHub Desktop.
Use ctypes and some python magic to unpack C/C++ bitfields struct dynamically.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef struct __attribute__ ((packed)) Data { | |
uint32_t temperature_internal: 10; | |
uint32_t temperature: 10; | |
uint32_t pressure: 12; | |
uint32_t humidity: 10; | |
uint32_t temperature_soil: 10; | |
uint32_t battery_level: 7; | |
uint32_t leaf_wetness: 4; | |
uint32_t pad0: 1; | |
uint32_t rainrate: 8; | |
uint32_t pad1: 24; | |
} data_t; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import binascii | |
import json | |
import pprint | |
from ctypes import c_uint32, LittleEndianStructure | |
def ctypes_unpack(fields, data): | |
def _get_fields(): | |
return fields | |
class Frame(LittleEndianStructure): | |
_fields_ = _get_fields() | |
def __init__(self, _): | |
super().__init__() | |
def __new__(cls, buf=None): | |
return cls.from_buffer_copy(buf) | |
def _to_dict(self): | |
return {field[0]: getattr(self, field[0]) for field in self._fields_} | |
@property | |
def fields(self): | |
return self._to_dict() | |
frame = Frame(data) | |
return frame.fields | |
def main(): | |
with open('sensors.json') as f: | |
result = json.loads(f.read()) | |
fields = [(k, eval(v['type']), v['bits']) for k, v in result.items()] | |
# frame = decode(fields, binascii.unhexlify('f514d570c7e5923feb000000')) | |
frame = ctypes_unpack(fields, binascii.unhexlify('fa3025e4e8f4f21b75000000')) | |
pprint.pprint(frame) | |
if __name__ == '__main__': | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"temperature_internal": { "type": "c_uint32", "bits": 10, "max": 50, "min": -30}, | |
"temperature": { "type": "c_uint32", "bits": 10, "max": 50, "min": -30}, | |
"pressure": { "type": "c_uint32", "bits": 12, "max": 1100, "min": 800}, | |
"humidity": { "type": "c_uint32", "bits": 10, "max": 100, "min": 0}, | |
"temperature_soil": { "type": "c_uint32", "bits": 10, "max": 50, "min": -30}, | |
"battery_level": { "type": "c_uint32", "bits": 7, "max": 12, "min": 0}, | |
"leaf_wetness": { "type": "c_uint32", "bits": 4, "max": 15, "min": 0}, | |
"rainrate": { "type": "c_uint32", "bits": 8, "max": 255, "min": 0} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment