Десериализация байтовой строки с учетом нулевых значений в полях - PullRequest
1 голос
/ 26 апреля 2019

Я собираю сообщение согласно моему протофилу (указанному ниже). Затем я сериализую его в байтовую строку, используя метод SerializeToString (). Затем я получаю сообщение строки байта и десериализацию в объект прото с использованием метода ParseFromString (). Но если я заполняю некоторые поля нулевыми значениями и выполняю приведенный выше алгоритм так:

def test():
    fdm = device_pb2.FromDeviceMessage()
    fdm.deveui = bytes.fromhex('1122334455667788')
    fdm.fcntup = 0
    fdm.battery = 3.5999999046325684
    fdm.mode = 0
    fdm.event = 1
    port = fdm.data.add()
    port.port = 1 #device_pb2.PortData.Name(0)
    port.value = 0
    c = fdm.SerializeToString()
    return c

def parse_test(data):
    print(data)
    res = device_pb2.FromDeviceMessage()
    res.ParseFromString(data)
    return res

print(parse_test(test()))

, тогда консоль python покажет мне:

deveui: "\021\"3DUfw\210"
battery: 3.5999999046325684
event: PERIOD_EVENT
data {
  port: VIBR2
}

без полей значения равны нулю.

Но я хочу увидеть:

deveui: "\021\"3DUfw\210"
fcntup: 0
battery: 3.5999999046325684
mode: BOUNDARY
event: PERIOD_EVENT
data {
  port: VIBR2
  value: 0
}

Почему это происходит, и если это исправлено, как я могу это исправить?

============= Proto_File ================

message FromDeviceMessage{
    bytes deveui = 1; 
    uint32 ts = 2; 
    int32 fcntup = 3; 
    float battery = 4;
    int32 period = 5; 
    Mode mode = 6; 
    Event event = 7; 
    repeated PortData data = 8; 
}

message PortData{
    DevicePort port = 1;
    int32 value = 2;
}

enum Mode{
    BOUNDARY = 0;
    PERIOD = 1;
    BOUNDARY_PERIOD = 2;
}

enum Event{
    BOUNDARY_EVENT = 0;
    PERIOD_EVENT = 1;
}

enum DevicePort{
    VIBR1  = 0;
    VIBR2  = 1;
    TEMPL2 = 3;
}

1 Ответ

0 голосов
/ 29 апреля 2019

Итак, я думаю, я угадал причину.В случае enum type (DevicePort, Event, Mode): значением по умолчанию является первое определенное значение перечисления, которое должно быть 0. Поэтому я установлю 1 значение, чтобы увидеть обязательные поля.В других случаях: поля с нулевыми значениями не отображаются, чтобы уменьшить объем памяти пакета.Но если я перейду к нужному полю, используя этот способ: res.data[0].valuedef parse_test(data)), он покажет мне 0, если я, например, установлю значение 0 в поле value.И это правило работает во всех случаях.

...