1

I am working on an mqtt project where I subscribe to a broker that returns data to me in bytes string. I have to convert that data into protobuf then in dict. Here is an example of the data I receive.

b'\n\x108cf9572000023509\x10\x03\x1a\x06uplink \xd4\xc9\xc6\xea\x9a/*\x10b827ebfffebce2d30\xbe\xff\xff\xff\xff\xff\xff\xff\xff\x01=\x00\x00\x18AE4\x13YDH\x05P\x01Z\x01C`\x8c\x06h\x08z \x02\x05e!\x08\x01\x00f\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x0f\x00\x82\x01"\n\x10b827ebfffebce2d3\x10\xbe\xff\xff\xff\xff\xff\xff\xff\xff\x01\x1d\x00\x00\x18A'

Structure of my .proto file

    message RXInfoSimplified {
        string ID = 1;
        int32 RSSI = 2;
        float SNR = 3;
    }
    
message DeviceUplink {
    string DevEUI = 1;
    int64 ApplicationID = 2;
    string MsgType = 3;
    int64 Timestamp = 4;
    string GatewayID = 5;
    int32 RSSI = 6;
    float SNR = 7;
    float Frequency = 8;
    int32 DataRate = 9;
    bool ADR = 10;
    string Class = 11;
    uint32 FCnt = 12;
    int32 FPort = 13;
    bool Confirm = 14;
    bytes Data = 15;
    repeated RXInfoSimplified Gateways = 16;
}

I tried this in my callback:

m = sub_message.DeviceUplink()
def on_message(client, userdata, msg):  
    m.ParseFromString(msg.payload)
    print(m)

I got :

DevEUI: "8cf9572000023509"
ApplicationID: 3
MsgType: "uplink"
Timestamp: 1622117284775
GatewayID: "b827ebfffebce2d3"
RSSI: -61
SNR: 10.25
Frequency: 868.1
DataRate: 5
ADR: true
Class: "C"
FCnt: 796
FPort: 8
Data: "\002\005\220!\023\004\000p\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\335\016\000"
Gateways {
  ID: "b827ebfffebce2d3"
  RSSI: -61
  SNR: 10.25
}

how can i convert Data value in string ?

YaLeaura
  • 61
  • 3
  • 9

1 Answers1

0

Since Data has a bytes type in the proto definition, it has a bytes type in Python 3+. There isn't any further information in the .proto file on how to interpret the field, as far as the Protocol Buffers library is concerned it's a raw byte string and that's it.

It's up to you to know what to do with the field value. What's supposed to be in the Data field? Perhaps a serialized message of some type that you know? In that case, just use ParseFromString again.

Rafael Lerm
  • 1,340
  • 7
  • 10
  • In fact I have to convert the Data field to hexadecimal. – YaLeaura Jul 06 '21 at 11:09
  • 1
    In that case, this is not really a protobuf question: the Data field is a bytestring. You want to find a way to display a bytestring as hexadecimal: https://stackoverflow.com/questions/6624453/whats-the-correct-way-to-convert-bytes-to-a-hex-string-in-python-3 – Rafael Lerm Jul 15 '21 at 13:14