интерпретация отдельных битов из кода состояния ESC / POS - PullRequest
0 голосов
/ 12 марта 2019

Я признаю, что этот проект, над которым я работаю, не совсем пример из учебника о том, как сделать первые шаги с Python, но я здесь.

Настройка

ESC/ POS-принтер, локально подключенный (Ethernet, сокет) к RaspberryPi, который получает удаленные задания печати (через AMQP).

Проблема

Подключение к брокеру AMQP и принтеру, а такжепечать работает нормально.С чем я борюсь, так это с кодами состояния принтера с помощью ctypes.

При копании в интернете в поисках наилучшего подхода я наткнулся на статью вики Python (ссылка) что касается манипулирования битами, где было указано, что для использования, как у меня, рекомендуется ctypes.Это действительно показалось отличным и чистым подходом, поэтому я немедленно применил это к своему коду (ниже упрощенная версия).

import socket
import ctypes

class PrinterStatus_bits( ctypes.LittleEndianStructure ):
    _fields_ = [
                ("fix0",        c_uint8, 1 ),  # asByte & 1
                ("fix1",        c_uint8, 1 ),  # asByte & 2
                ("drawer",      c_uint8, 1 ),  # asByte & 4
                ("offline",     c_uint8, 1 ),  # asByte & 8
                ("fix4",        c_uint8, 1 ),  # asByte & 16
                ("recovery",    c_uint8, 1 ),  # asByte & 32
                ("feed",        c_uint8, 1 ),  # asByte & 64
                ("fix7",        c_uint8, 1 ),  # asByte & 128
               ]

class Flags( ctypes.Union ):
    _anonymous_ = ("bit",)
    _fields_ = [
                ("bit",    PrinterStatus_bits),
                ("asByte", c_uint8           )
               ]


sock            = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address  = ('123.123.123.123', 9100)
c_uint8         = ctypes.c_uint8          
flags           = Flags()
msg             = b'\x10\x04\x01'

print('connecting to %s port %s' % server_address)
sock.connect(server_address)

print('requesting printer status')
sock.sendall(msg)
data           = sock.recv(1)
flags.asByte   = ord(data)

длина приема 1 байт устанавливается сознательно, так как это фиксированная длина ответа.Дело, однако, в том, что это только первый (из четырех) общий код состояния.

Я бы хотел, чтобы все эти коды состояния были доступны через объект flags, просто не знаю, как работать с профсоюзами.

Если я сделаю что-то вроде:

class PrinterStatus_bits( ctypes.LittleEndianStructure ):
class PrinterOffline_bits( ctypes.LittleEndianStructure ):
class PrinterError_bits( ctypes.LittleEndianStructure ):
class PrinterPaper_bits( ctypes.LittleEndianStructure ):

class Flags( ctypes.Union ):
    _anonymous_ = ("status",)
    _fields_ = [
                ("status",   PrinterStatus_bits),
                ("offline",  PrinterOffline_bits),
                ("error",    PrinterError_bits),
                ("paper",    PrinterPaper_bits ),
                ("asByte",   c_uint8    )
               ]

как мне даже назначить соответствующие значения соответствующим классам?

ps все 4 кода состояния всегда имеют длину в 1 байт

pps Я не одержим использованием ctypes иесли это не правильный подход в этом случае, я бы с этим согласился, и я просто перебрал бы все 4 ответа и присвоил бы эти значения массиву 0/1, но мое любопытство одолело меня, и я быхотел бы узнать, выполнимо ли это вообще так

1 Ответ

1 голос
/ 13 марта 2019

Вы слишком усложняете это.

flags    = ord(data)
drawer   = (flags & 4) != 0
offline  = (flags & 8) != 0
recovery = (flags & 32) != 0
feed     = (flags & 64) != 0
...