How do I get my returned data to format through a structure?

58 views Asked by At

I'm sending this to the server:

import requests 
response = requests.get('http://SERVER-IP/get.cgi?req=zones')
print(response.content)

I get back a string of data like this:

b'CS\x01\x00\x00\x00\x01\x00MainAuditorium\x00\x00\x00\x00\x01\x00\x03\x00\x00\x00\x01\x00\x00\x00'

On the website it lists a variable length structure

typedef struct ZonesData {
    uint16_t            signature;              // Signature = 'CS'
    int16_t             version;                // Version = 0x0001 (or negative error code)
    uint8_t             reserved[2];            // -
    uint16_t            zoneCount;              // Number of zones
    ZoneRecord          zones[];                // Variable array of zone records
} ZonesData;

#define STACK_NAME_BUF_SIZE     16

typedef struct ZoneRecord {
    char                name[STACK_NAME_BUF_SIZE];  // Name of zone
    uint8_t             playbackIndex;          // Playback index
    uint8_t             joinGroup;              // Join group
    uint16_t            count;                  // Number of PresetID/Status pairs
    uint32_t            data[];                 // Array of PresetID/Status pairs (32 pairs max)
} ZoneRecord;
  1. How can I get python to put the code in Human readable form?

  2. Can a use the returned integers to say update a button on a UI? I'm assuming I can, I'm just not sure if I would reference to integer or the human readable of the integer.

Additonal project context: I am trying to get Qsys and Cueserver integrated so that Qsys touchpad buttons update when a new preset is fired from a Cueserver wall station.

1

There are 1 answers

0
Geoffrey Franklin On

My brother-in-law and I worked on it some this weekend he came up with this.... I am still working out exactly what he did so that i can modify it for additional responses. You can ask the server for a bunch of different strings back (all in the same raw format). Looks like I'll have to code an individual response for each one...

import requests
import struct
from collections import namedtuple

PresetStatusPair = namedtuple('PresetStatusPair', 'preset status')

class ZoneData:
def __init__(self, data, offset):
    self.size = 20

   self.name, self.playback_index, self.join_group, count = struct.unpack_from("16sBBH", data, offset)
    self.name = str(self.name, 'ascii')
    self.data = []
    for i in range(count):
        unpacked = struct.unpack_from("II", data, offset + self.size)
        self.data.append(PresetStatusPair._make(unpacked))
        self.size += 8


class ZonesData:
def __init__(self, data):
    if len(data) == 4:
        raise Exception("CS internal error")

    self.signature, self.version, zone_count_unused = struct.unpack_from("2sHxxH", data)
    self.signature = str(self.signature, 'ascii')
    self.parse_zone_records(data)

def parse_zone_records(self, data):
    self.zone_records = []
    offset = 8
    while offset < len(data):
        zone_data = ZoneData(data, offset)
        offset += zone_data.size
        self.zone_records.append(zone_data)


zones_data = ZonesData(data)
print(f"signature: {zones_data.signature}")
print(f"version  : {zones_data.version}")
print(f"records  :")

for record in zones_data.zone_records:
print(f"    name          : {record.name}")
print(f"    playback_index: {record.playback_index}")
print(f"    join_group    : {record.join_group}")
print(f"    data          : {record.data}")