Как работать с динамической распаковкой и пониманием байт-структур

В ходе моего текущего проекта я получаю данные от набора датчиков дальнего действия, которые отправляют данные в виде серии байтов. Как правило, из-за наличия нескольких типов датчиков, структуры байтов и содержащиеся в них данные отличаются, поэтому необходимо сделать функциональность более динамичной, чтобы избежать необходимости жестко кодировать каждую отдельную настройку в будущем (что нецелесообразно).

На сервере будет использоваться Django, который, на мой взгляд, не имеет отношения к рассматриваемому вопросу, но я упомянул его на всякий случай, вдруг в нем есть что-то, что можно использовать.

Данные байтов, которые я получаю, выглядят следующим образом:

b'B\x10Vu\x87%\x00x\r\x0f\x04\x01\x00\x00\x00\x00\x1e\x00\x00\x00\x00ad;l'

А мой текущий процесс выглядит следующим образом:

  • Возьмите первые байты для получения идентификатора устройства (deviceID = val[0:6].hex())
  • Поищите формат, который будет использоваться в struct.unpack() (здесь: >BBHBBhBHhHL после удаления первых байтов для идентификатора.

Теперь проблема заключается в следующем шаге. Многие из имеющихся у меня данных имеют различные формы предварительной обработки, которую необходимо выполнить. Например, некоторые значения нужно объединить с помощью оператора join (например, ".".join(str(values[2])), в то время как другие требуют некоторых простых математических изменений (-113 + 2 * values[4]) и, наконец, другие требуют простой логической проверки (values[7]==0x80), чтобы вернуть булево значение.

Мой вопрос в том, как лучше всего закодировать эти методы? Я бы очень хотел избежать их жесткого кодирования, но это почти кажется лучшей идеей. Другая идея, которую я видел, это хранить функции в виде строки и выполнять их, как показано here, но я читал, что это очень плохая идея, и что это также замедляет выполнение. Последняя идея, которая у меня была - это жестко закодировать только некоторые общие функции и использовать что-то похожее на here, но это не решает проблему необходимости жестко кодировать каждый новый тип датчика, что нереально в живой установке. Есть ли более эффективные методы достижения того же самого?

Приложение: Минимальный код, который можно использовать для демонстрации и тестирования различных методов:

import struct

def decode(input):
    val = bytearray(input)
    deviceID = val[0:6].hex()
    del(val[0:6])
    print(deviceID)
    values = list(struct.unpack('>BBHBBhBHhHL', val))
    print(values)
    # Now what?

decode(b'B\x10Vu\x87%\x00x\r\x0f\x04\x01\x00\x00\x00\x00\x1e\x00\x00\x00\x00ad;l')
Вернуться на верх