Мне удалось найти и подключить Raspberry Pi 4 к термопринтеру Bluetooth 4.0 с помощью BlueZ API.
Чтобы использовать библиотеку python-escpos, мне нужно создать последовательный порт /dev/rfcomm, что я могу сделать с помощью sudo rfcomm bind /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1.
Как я могу сделать это программно на Python (без использования python-subprocess)?






rfcomm был одним из инструментов , устаревших проектом BlueZ в 2017 году. Я бы посоветовал вам избегать использования связанных с этим функций.
Библиотека python-escpos принимает местоположение устройства последовательного порта, поэтому я бы предложил использовать библиотеку Python pty, которая создает два псевдоустройства, pts, эмулируя аппаратное устройство последовательного порта.
Как именно вы хотите это спроектировать, будет зависеть от вашего проекта, но я провел простой тест, в котором у меня был сценарий, создающий псевдопоследовательный порт, который он прослушивал и отправлял на устройство BLE, если данные были получены:
import os
import pty
from time import sleep
import pydbus
dev_addr = 'xx:xx:xx:xx:xx:xx'
ptmx_fd, pts_fd = pty.openpty()
pts_name = os.ttyname(pts_fd)
print(f"Printer port: {pts_name}")
bus = pydbus.SystemBus()
mngr = bus.get('org.bluez', '/')
def get_characteristic_path(dev_path, uuid):
mng_objs = mngr.GetManagedObjects()
for path in mng_objs:
chr_uuid = mng_objs[path].get('org.bluez.GattCharacteristic1', {}).get('UUID')
if path.startswith(dev_path) and chr_uuid == uuid.casefold():
return path
class MyRemoteDevice:
# CHAR_UUID = '0000ff02-0000-1000-8000-00805f9b34fb' # Real printer
CHAR_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E' # my test device
def __init__(self, mac_addr):
device_path = f"/org/bluez/hci0/dev_{mac_addr.replace(':', '_')}"
self.device = bus.get('org.bluez', device_path)
# Placeholder for characteristic details
self.characteristic = None
def _get_gatt_details(self):
char_path = get_characteristic_path(self.device._path,
MyRemoteDevice.CHAR_UUID)
self.characteristic = bus.get('org.bluez', char_path)
def connect(self):
self.device.Connect()
# Check GATT services have been resolved before continuing
while not self.device.ServicesResolved:
sleep(0.25)
self._get_gatt_details()
def disconnect(self):
self.device.Disconnect()
def read(self):
return self.characteristic.ReadValue({})
def write(self, new_value):
self.characteristic.WriteValue(new_value, {})
my_first_dev = MyRemoteDevice(dev_addr)
my_first_dev.connect()
try:
while True:
data = os.read(ptmx_fd, 1000)
if data:
print("data received:", data)
my_first_dev.write(data)
except:
pass
finally:
my_first_dev.disconnect()
Затем в приглашении Python я отправил значения в последовательный порт, используя библиотеку escpos:
from escpos.printer import Serial
# 9600 Baud, 8N1, Flow Control Enabled
p = Serial(devfile='/dev/pts/3',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.00,
p.text("Hello Printer#")
Привет @ukBaz: чтобы подключиться к BT 4.0принтеру, я последовал твоей логике и переправил полученные data на принтер через сокеты: s.send(data). Вы бы сделали это по-другому? Спасибо !
Bluetooth Low Energy был выпущен в 2010 году как часть версии 4.0 спецификации Bluetooth. BLE — это отдельный протокол от Bluetooth (также известный как Bluetooth Classic). Использование BT 4.0 не указывает, какой протокол используется, поскольку оба поддерживаются в 4.0. Я поискал ae3x характеристики и нашел это: werwolv.net/blog/cat_printer. Но есть ли у вашего принтера 00001101-0000-1000-8000-00805f9b34fb, который будет использовать классический протокол?
После того, как вы определили, какой протокол Bluetooth использует ваш принтер, вы можете использовать pty для моста между последовательным портом Python-escpos и Bluetooth.
Привет @ukBaz. Мой «кошачий принтер» имеет только эти UUID: 00001800-0000-1000-8000-00805f9b34fb, 0000ae30-0000-1000-8000-00805f9b34fb и 0000ae3a-0000-1000-8000-00805f9b34fb. Просматривая присланную вами статью, я понял, что этот принтер не поддерживает прямую печать текста, поэтому текст необходимо предварительно преобразовать в изображение, поэтому в моем проекте это недопустимо.
Спасибо большое @ukBaz ! Мне удалось настроить псевдопоследовательный порт и отправлять/читать через него данные! Однако предполагаемый
BLEпринтер, который у меня есть, возможно, вообще неBLE, поскольку он показывает только эти UUID:00001800-0000-1000-8000-00805f9b34fb,0000ae30-0000-1000-8000-00805f9b34fbи0000ae3a-0000-1000-8000-00805f9b34fb— и ни один из них не работает с вашим скриптом.