Reputation: 894
I have a class with all sorts of data in it, like:
class UARTMessage:
Identification1 = int(0) #byte 0
Timestamp1 = int(0) #bytes [1:5]
Voltage1 = int(0) #bytes [6:7]
Current1 = int(0) #bytes [8:9]
Signal1= int(0) #bytes [10:11]
Identification2 = int(0) #byte 12
Timestamp2 = int(0) #bytes [13:17]
Voltage2 = int(0) #bytes [18:19]
Current2 = int(0) #bytes [20:21]
Signal = int(0) #bytes [22:23]
Identification3 = int(0) #byte 24
The data to fill this structure up will come from a serial. I need to deserialize the data coming from the serial in the shape of this structure. I am reading from serial 40 bytes data chunks and I need to split itit. I tried pickle library but it seems that it's not fitted exactly for deserializing this type of data. I found struct but I cannot understand how to use it proprely in this case.
As the comments in the struct, I need to desearilize the chunks of data like: first byte is Identificator, bytes from 1 to 5 included is the timestamp and so on....
DO you have any ideea how can I achieve this?
Thanks
Upvotes: 4
Views: 6888
Reputation: 2925
First of all, we need to declare format of incoming bytes according to this list: https://docs.python.org/3/library/struct.html?highlight=struct#format-characters.
import struct
import sys
class UARTMessage:
fmt = '@B5shhhB5shhhB'
def __init__(self, data_bytes):
fields = struct.unpack(self.fmt, data_bytes)
(self.Identification1,
self.Timestamp1,
self.Voltage1,
self.Current1,
self.Signal1,
self.Identification2,
self.Timestamp2,
self.Voltage2,
self.Current2,
self.Signal2,
self.Identification3) = fields
self.Timestamp1 = int.from_bytes(self.Timestamp1, sys.byteorder)
self.Timestamp2 = int.from_bytes(self.Timestamp2, sys.byteorder)
self.Timestamp3 = int.from_bytes(self.Timestamp3, sys.byteorder)
First character of the fmt
is byte order. @
is python default (usually little endian), if you need to use network big-endian put !
. Each subsequent character represents a data type which comes from the bytes stream.
Next, in the initializer, I unpack bytes according to the recipe in fmt
into a fields
tuple. Next, I assign the values of the tuple to object attributes. Timestamp has unusual length of 5 bytes, so it requires special treatment. It is fetched as 5-bytes string (5s
in fmt) and converted to int using int.from_bytes
function with system default bytes order (if you need a different bytes order enter 'big'
or 'little'
as a second argument).
When you want to create your structure, pass the sequence of bytes to the constructor.
Upvotes: 7