Разбор последовательных данных с помощью записи структуры в Python3 - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь проанализировать данные, полученные с монитора через последовательный порт. Я успешно кодировал сценарий в Python для извлечения данных из монитора в виде байтовой строки и выполнил необходимые преобразования данных в соответствии со стандартом ISO3309 и, наконец, выполнил контрольную сумму для обеспечения целостности данных. Ниже приведены извлеченные данные.

[198, 2, 40, 4, 0, 0, 131, 35, 158, 94, 0, 0, 0, 0, 0, 0, 0, 0, 1, 22, 1, 1, 44, 2, 4, 189, 189, 255, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 131, 35, 158, 94, 51, 58, 0, 0, 0, 18, 2, 128, 10, 129, 1, 128, 1, 128, 1, 128, 1, 0, 0, 0, 1, 0, 2, 128, 2, 128, 2, 128, 1, 128, 1, 0, 0, 0, 2, 0, 2, 128, 2, 128, 2, 128, 1, 128, 0, 0, 0, 0, 11, 0, 1, 128, 1, 128, 1, 128, 1, 128, 0, 0, 0, 0, 3, 0, 1, 128, 1, 128, 1, 128, 1, 128, 3, 0, 0, 0, 3, 1, 1, 128, 1, 128, 1, 128, 1, 128, 3, 0, 0, 0, 11, 0, 4, 128, 3, 0, 0, 0, 12, 0, 4, 128, 0, 0, 0, 0, 13, 0, 1, 128, 0, 0, 0, 0, 14, 0, 1, 128, 3, 0, 0, 0, 0, 0, 1, 128, 2, 128, 2, 128, 1, 128, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 203, 29, 3, 0, 0, 0, 0, 0, 41, 8, 41, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 0, 0, 0, 0, 11, 0, 1, 128, 1, 128, 1, 128, 1, 128, 32, 0, 0, 0, 0, 0, 1, 128, 1, 128, 255, 141, 2, 128, 1, 128, 1, 128, 0, 0, 0, 0, 173, 1, 1, 128, 0, 0, 0, 0, 13, 0, 1, 128, 1, 128, 1, 128, 1, 128, 0, 0, 0, 0, 14, 0, 1, 128, 1, 128, 1, 128, 1, 128, 0, 0, 0, 0, 65, 0, 131, 35, 158, 94, 0, 0, 0, 0, 18, 2, 1, 128, 1, 128, 1, 128, 1, 128, 3, 0, 0, 0, 0, 0, 1, 128, 1, 128, 4, 128, 1, 128, 1, 128, 1, 128, 73, 13, 0, 0, 176, 192, 0, 0, 226, 1, 0, 0, 198, 2, 0, 0, 240, 127, 170, 1, 0, 0, 0, 0, 9, 49, 28, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 3, 0, 0, 0, 0, 0, 0, 0, 0, 195, 165, 0, 0, 195, 165, 1, 128, 72, 8, 160, 15, 32, 78, 208, 7, 208, 7, 112, 23, 80, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 52, 8, 0, 0, 0, 0, 208, 7, 112, 23, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141]

У меня есть запись структуры. Пожалуйста, смотрите прикрепленный. Не помогает, что запись, вероятно, записана в C. Тем не менее, мой вопрос к заголовку. If, Struct: просто пользовательская переменная с несколькими типами данных. Соответствует ли структура заголовка первым целым числам в моем списке данных? Так, например: r_len = 198, r_nbr = 2, r_time = 0? И я продолжаю последовательно перемещаться вниз по списку, чтобы получить дополнительные записи? Если это так, время определяется как количество секунд с 1.1.1970. Так как это может быть из одного целого числа? Я был бы очень благодарен за любые подсказки, которые вы можете предоставить. Спасибо за чтение моего длинного поста. Структура записи для данных Structure Record page 2

1 Ответ

1 голос
/ 21 апреля 2020

Привет, Роберт, и спасибо за задачу, с которой я только что порадовался!

spe c определенно означает, что передает данные в байтах, описанных этой C -подобной структурой. Я не вижу, как вы прочитали данные, но предположил, что вы получили именно список байтов, так как каждое значение здесь меньше 256.

Итак, просматривая структуру, я могу попытайтесь преобразовать это в удобочитаемую форму. Это делается с помощью модуля struct в python:

b = bytes(l)
hdr_data = struct.unpack_from('<hBBHLBBHH', b)
print(hdr_data)

Объяснение

Здесь я рассматриваю l как начальный список байтов. Учитывая структуру предоставленной вами записи, я построил строку формата для заголовка:

hBBHLBBHH означает: короткий, байт, байт, слово, слово, байт, байт, слово, слово.

< в начале означает, что порядок следования байтов имеет порядок байтов

Выводится результат

(710, 40, 4, 0, 1587422083, 0, 0, 0, 0)

Здесь первое значение равно r_len и равно 710. Длина вашего списка len(l) равна 711, так что, скорее всего, мое первоначальное предположение о формате списка и порядке байтов правильное, и в результате в результате несчастного случая вы получите один избыточный байт .

Следующий шаг

Хотя мы в основном покончили с этим однострочником, мы еще не прочитали sr_des c и не установили подходящее совпадение имен.

Давайте изменим также линию распаковки, чтобы она потребляла struct sr_desc[8]:

hdr_data = struct.unpack_from('<hBBHLBBHH' + 'hB'*8, b)

Теперь у нас все будет в одном кортеже.

Очень удобный способ доступа поля namedtuple

from collections import namedtuple
D_O_hdr = namedtuple('D_O_hdr',
                     ('r_len', 'r_nbr', 'dri_level', 'plug_id', 
                      'r_time', 'n_subset', 'res', 'dest_plug_id',
                      'r_maintype',))

header = D_O_hdr(*hdr_data[:9])
print(header)

Теперь вы можете видеть, что вы можете легко получить доступ к o каждое поле, например print(header.r_len) и т. д.

То же самое, но немного сложнее, для sr_data:

struct_sr_desc = namedtuple('sr_desc', ('sr_offset', 'sr_type',))

sr_data = [struct_sr_desc(off, typ) 
           for off, typ in zip(hdr_data[9::2], hdr_data[10::2])]

# Just make sure we've got a list of 8 objects
assert len(sr_data) == 8

Здесь проблема заключалась в том, что нам нужно преобразовать простой список в список структур. hdr_data[9::2] занимает каждое первое поле sr_desc (т.е. sr_offset), а hdr_data[10::2] - каждое второе поле. zip делает пару списков списком пар.

sr_data[3].type содержит 255, что означает, что у вас есть только три подзаписи в структуре, но распаковка их уже на вас! Только не забывайте, что sr_data[i].offset содержит смещение от конца заголовка. Это в основном очевидно, поскольку sr_data[0].offset всегда 0, но в любом случае.

Полный сценарий находится здесь: https://repl.it/@FooBarrior / CreativePartialOpenlook

Удачи!

...