Я признаю, что этот проект, над которым я работаю, не совсем пример из учебника о том, как сделать первые шаги с 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, но мое любопытство одолело меня, и я быхотел бы узнать, выполнимо ли это вообще так