Фіскальний реєстратор МІНІ-ФП54.01
assert result == "OK;Z_REPORT_PRINTED" </syntaxhighlight>
Unit-тест помилки: чек без відкритої зміни
finally:
@abstractmethod
result = driver.open_receipt()
if command.startswith("SALE"):
Інтерфейс драйвера
|- |Назва |МІНІ-ФП54.01 |- |Тип пристрою |Фіскальний реєстратор |- |Виробник |Юнісістем |- |реліз системи ПЗ |5401F3 |- |Підключення до ПК |USB або RS-232 |- |Передача даних |Ethernet, GSM/GPRS |- |Bluetooth |Опція |- |базовий офіційний спосіб інтеграції |DLL / OLE-сервер для Windows |- |Альтернативна інтеграційні функції ERP |Пряма робота через протокол обміну |}
</syntaxhighlight> mini_fp54/
raise
!№
7.
!Параметр pass
)
МІНІ-ФП54.01
print(name) self.driver = None
client.connect()
↓
|- | style="background:#d4edda; color:#155724; font-weight:bold;" |Можливо |Linux здатна працювати з пристроєм через serial-порт. |- | style="background:#d4edda; color:#155724; font-weight:bold;" |Плюс |Можна використовувати Python через pywin32.</syntaxhighlight>
driver.pay_cash(50.00)
Приклад через PowerShell: Для Linux, macOS або embedded-систем можлива інтеграційні функції ERP через `pyserial`, але для цього потрібно реалізувати протокол обміну з пристроєм. |- |RS-232 |Підключення до ПК |Зручний для serial-інтеграції. # Виконати фіскалізацію. # Виконати тестовий друк або службову операцію.=== Приклад продажу через OLE ===
├── test_sale_flow.py port: str result,
- кросплатформність;
- незалежність від OLE;
- можна запускати як локальний сервіс;
- інтуїтивно для Docker, Linux POS, Raspberry Pi, embedded-терміналів.
├── __init__.py
/dev/pts/4 Python → pywin32 → OLE-сервер → USB/COM → МІНІ-ФП54.01
driver.open_shift()
POS-система
if not self.shift_opened:
self.items = []
роздрібної торгівлі забезпечується через Модель підходить; так само реалізовано виїзної торгівлі, інтернет-магазинів, аптек, кафе, барів, ресторанів та сфери послуг. |}
├── serial_driver.py
return self.driver.Pay(payment_type, amount)
Select-Object -First 50
- повтори;
|-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Добре
|Serial-протокол простіше реалізувати кросплатформно. filename="mini_fp54.log",
def open_shift(self):
result = driver.close_receipt()
self.driver = win32com.client.Dispatch(self.prog_id)
!Статус
print(response)
return "ERROR;RECEIPT_NOT_OPEN"
!Висновок
!Характеристика
- таймаути;
↓
!Коментар
tax_group=1,
self.receipt_opened = True
== Висновок ==
return self.driver.GetSoftVersion()
duration,
!Статус
- ProgID потрібно взяти з реальної інсталяції OLE-сервера.== Рекомендована структура Python-проєкту ==
duration,
{| class="wikitable"
self.prog_id = prog_id
self.shift_opened = False
print("Version:", driver.get_version())
/dev/ttyACM0
response = client.send_text_command("GET_STATUS")
class FiscalCommandError(Exception):
↓
Помилка
Python через serial-портif not self.receipt_opened: USB-підключення зручне для сучасних ПК і ноутбуків. |- |
interfaces.py | Спільний інтерфейс драйвера |
|---|---|---|
| ole_driver.py | Робота через OLE/DLL у Windows | |
| serial_driver.py | Робота через serial-порт | |
| fake_driver.py | Mock-драйвер для тестів | |
| errors.py | Власні класи помилок | |
| logger.py | Логування команд і відповідей | |
| config.py | конфігурація порту, швидкості, режиму роботи | |
| tests/ | Unit та integration-тести |
def handle_command(command: str) -> str:
Fake-драйвер
/dev/tty.usbmodem-*
| □ | USB-драйвер встановлено |
| □ | OLE/DLL встановлено, якщо застосовується для Windows |
| □ | COM-порт визначено |
| □ | Отримання статусу функціонує |
| □ | Відкриття зміни функціонує |
| □ | Продаж товару функціонує |
| □ | Оплата готівкою функціонує |
| □ | Оплата карткою функціонує |
| □ | Закриття чека функціонує |
| □ | X-звіт функціонує |
| □ | Z-звіт функціонує |
| □ | Передача даних функціонує |
| □ | Перевірено поведінку при timeout |
| □ | Перевірено поведінку при відсутності паперу |
| □ | Перевірено поведінку при втраті інтернету |
| □ | Немає hardcoded COM-порту в production-коді |
| □ | Немає ігнорування помилок РРО |
Після запуску `socat` покаже два порти, як приклад:
Для macOS ситуація аналогічна Linux: готового офіційного OLE/DLL-драйвера немає, але можна працювати через serial-порт, якщо платформа бачить пристрій як `/dev/tty.*`. портативний фіскальний реєстратор виробництва '''Юнісістем''' виступає ключовою рисою '''МІНІ-ФП54.01'''. # Перевірити наявність паперу. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Не для production
|Не можна вважати інтеграцію готовою без тестів із реальним пристроєм. |}
self.connection.close()
Для production-інтеграції потрібно логувати:
raise RuntimeError("Serial port is not open")
* перевірити бізнес-логіку POS-системи;
* перевірити порядок команд;
* перевірити обробку помилок;
* перевірити логування;
* перевірити поведінку при timeout;
* перевірити поведінку при відсутності паперу;
* перевірити поведінку при розриві зʼєднання. |}
!Статус
pass
try:
* USB-драйвер;
* DLL-бібліотеку / OLE-сервер;
* програму UNI-PROGress для конфігурація РРО;
* Uniq Commander для конфігурація комунікаційного блоку;
* обробку для «1С:компанія-користувач». |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Уточнити
|Потрібно знати реальний ProgID OLE-сервера і точні назви методів. !Примітка
Драйвер або власна інтеграційні функції ERP
"""
<syntaxhighlight lang="python"> import logging import time
Приклад:<pre>
Увага:
|-
|Немає звʼязку з пристроєм
|Неправильний COM-порт або кабель
|Перевірити порт, кабель, драйвер, живлення
|-
|Timeout
|Пристрій не відповідає
|Повторити команду, перевірити стан РРО
|-
|Port busy
|Порт зайнятий іншою програмою
|Закрити інші програми, які використовують COM-порт
|-
|Немає паперу
|Закінчилась чекова стрічка
|Замінити папір і повторити операцію
|-
|Зміна не відкрита
|POS намагається пробити чек без відкритої зміни
|Спочатку виконати відкриття зміни
|-
|Чек уже відкритий
|Попередній чек не закритий
|Закрити або анулювати чек
|-
|Помилка передачі даних
|Немає Ethernet/GSM-звʼязку
|Перевірити інтернет, SIM-карту, конфігурація
|}
response = handle_command(command)
try:
return "ERROR;UNKNOWN_COMMAND\n"
self.total = 0.0
@dataclass class MiniFP54SerialConfig:
Пристрій має Ethernet-порт і GSM/GPRS-модем для передачі даних. За потреби виконувати повернення. # Перевірити, який COM-порт отримав пристрій. # Встановити DLL/OLE-сервер, якщо застосовують, коли потрібно Windows. |}
driver.connect_to_ole()
{| class="wikitable"
port=self.config.port,
def close_receipt(self):
def send_raw(self, payload: bytes, read_size: int = 1024) -> bytes:
* не потрібно вручну реалізовувати низькорівневий протокол;
* простіше стартувати;
* можна викликати готові методи драйвера;
* підходить для POS-систем на Windows.=== Linux ===
=== Windows ===
driver = FakeMiniFP54Driver()
@abstractmethod
@abstractmethod
{| class="wikitable"
)
Windows:
=== Перед запуском ===
== Варіанти інтеграції ==
"""
driver.close_port()
def send_text_command(self, command: str) -> str:
конкурентні переваги:
Production checklist
class MiniFP54OleDriver:
format="%(asctime)s %(levelname)s %(message)s",
return self.driver.ClosePort()
Варіант 1. Через OLE/DLL у Windows
client = MiniFP54SerialClient(
if command == "GET_STATUS": return "OK;READY\n"
if command == "GET_VERSION":
</syntaxhighlight>
Базовий serial-клієнт
payment_type = 0
pass
МІНІ-ФП54.01 здатна підключатися до компʼютера через:
pass quantity=1, if not raw: pass def open_receipt(self) -> str:
return self.driver.Sale(name, quantity, price, tax_group)
Встановлення залежності
Приклад через Python:
def connect(self): /dev/ttyUSB0
def open_port(self, port: int, baudrate: int = 115200): baudrate: int = 115200
!Статус
Робота в реальному режимі
PROG_ID = "PUT_REAL_PROG_ID_HERE"
def open_receipt(self):
!Статус
return result
Важливі висновки для інтеграції
Варіант 2. Через serial-порт напряму
"""
Python через OLE/DLL у Windows
def __init__(self):
Where-Object { $_.Name -match "Ecr|T400|MINI|FP|Unisystem|Uni" } |
@abstractmethod
f"SHIFT_OPENED={self.shift_opened};"
|- | style="background:#fff3cd; color:#856404; font-weight:bold;" |Обовʼязково |Чи правильний ProgID OLE-сервера. # Перевірити заряд акумулятора або живлення. pass
- залежність від Windows;
- залежність від конкретної версії OLE-сервера;
- потрібно встановити та зареєструвати COM/OLE-компонент;
- потрібно знати ProgID і назви методів. if command == "CLOSE_RECEIPT":
- потрібно реалізувати протокол обміну;
- потрібно опрацьовувати контрольні суми, ACK/NAK, таймаути, повтори;
- складніше тестувати;
- потрібна офіційна документація протоколу. |-
|GSM/GPRS |Передача даних через мобільну мережу
|Дає змогу працювати без дротового інтернету.
def test_open_receipt_without_shift():
{| class="wikitable"
== Підключення до компʼютера ==
├── ole_driver.py
{| class="wikitable"
result = driver.close_shift()
assert result == "ERROR;SHIFT_NOT_OPEN"
Unit-тест помилки: оплата менша за суму чека
timeout=3.0,
driver = FakeMiniFP54Driver()
!Інтерфейс └── tests/
baudrate=115200, pass
import win32com.client
)
Python-сервіс
except Exception as exc:
duration = round(time.time() - started_at, 3)
"""
driver.close_receipt()
def open_receipt(self) -> str:
)
encoding: str = "cp1251"
except OSError:
def pay_cash(self, amount: float) -> str:
command = raw.decode("cp1251", errors="replace")
!Що робити
!Висновок
Linux:
stopbits=serial.STOPBITS_ONE, return "OK;MINI-FP54.01;5401F3\n"
!Призначення
"""
2. |- |Bluetooth |Опційне підключення |здатна використовуватися зі смартфоном або планшетом за наявності сумісного ПЗ. # Налаштувати касирів. 4. # Налаштувати податкові групи. |- | style="background:#d4edda; color:#155724; font-weight:bold;" |Можливо |Для Linux/macOS можна реалізувати власний драйвер через serial-порт |Потрібна реалізація протоколу обміну з фіскальним реєстратором. |- | style="background:#f8d7da; color:#721c24; font-weight:bold;" |Небезпечно |Не можна ігнорувати помилки фіскального реєстратора. |- | style="background:#fff3cd; color:#856404; font-weight:bold;" |Обовʼязково |Чи правильний COM-порт. try: logging.basicConfig(
конкурентні переваги:
</syntaxhighlight> !Статус !Коментар
level=logging.INFO, raw = ser.readline() self.total = 0.0
def close_receipt(self) -> str:
if not self.receipt_opened:
Для Windows виробник надає:
/dev/tty.usbserial-* └── test_errors.py if not self.receipt_opened:
Мінімальний чек-лист smoke-тесту
Рекомендована схема для Windows:
Для розробки без фізичного пристрою варто використовувати mock-драйвер або serial-емулятор. |}
total = winreg.QueryInfoKey(root)[0]
├── interfaces.py
# Встановити USB-драйвер виробника. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Ризик
|У різних ОС назва порту буде різною, тому її не можна жорстко зашивати в код. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Не плутати
|Ethernet/GSM не виступає як основним інтерфейсом POS-команд
|Ethernet і GSM/GPRS використовуються переважно для передачі даних до ДПС. Такий варіант гнучкіший, але складніший і потребує повного тестування з реальним фіскальним реєстратором. |}
↓
== Python-інтеграція ==
Без фізичного МІНІ-ФП54.01 можна тестувати не сам фіскальний реєстратор, а логіку інтеграції. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Обережно
|Офіційних Python-прикладів не знайдено
|Python можна використовувати через pywin32 або pyserial, але готового SDK саме для Python на сторінці підтримки немає. Реальна назва методу здатна бути OpenPort, openPort або іншою. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Не достатньо
|Без реалізації контрольної суми та службових байтів це не production-драйвер. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Обовʼязково
|Чи правильні назви методів. def get_version(self):
return "ERROR;SHIFT_NOT_OPEN"
Недоліки:
- ACK/NAK;
=== USB-підключення ===
Базовий serial-клієнт для МІНІ-ФП54.01.== Джерела ==
def __init__(self, config: MiniFP54SerialConfig):
!Причина
ser.flush()
!Пакет Python
|-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Добре для розробки
|Емулятор дає можливість тестувати POS-сценарії без фізичного пристрою. |-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Обовʼязково
|Наприкінці зміни потрібно виконувати Z-звіт. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Перевірити
|Потрібно встановити USB-драйвер виробника. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Перевірити
|Потрібен фізичний COM-порт або USB-RS232 адаптер. for attempt in range(1, retries + 1):
self.connection: serial.Serial | None = None
def open_shift(self) -> str:
try:
!Що треба перевірити перед запуском
def close_shift(self):
<pre>
<syntaxhighlight lang="python"> from mini_fp54_ole import MiniFP54OleDriver
time.sleep(delay)
=== macOS ===
Linux не виступає як основною цільовою платформою для офіційного OLE/DLL-драйвера. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Потрібно
|Реалізувати протокол обміну. |-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Рекомендовано
|Для Windows використовувати офіційний DLL / OLE-сервер
|Це найшвидший шлях інтеграції з POS-системою або Python-застосунком через COM/OLE. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Немає
|Готового офіційного Python SDK для Linux не знайдено. Наприкінці дня друкувати Z-звіт.=== Підготовка ===
try:
<syntaxhighlight lang="python"> from abc import ABC, abstractmethod
Схема:<pre>
f"RECEIPT_OPENED={self.receipt_opened}"
POS-система / касова програма
{| class="wikitable"
|-
|OLE/DLL
|pywin32
|Windows
|Найпростіший варіант, якщо встановлено OLE-сервер. Реальну команду потрібно брати з протоколу обміну. Перевірити звʼязок із POS-системою. |-
|Ethernet
|Передача даних через інтернет
|застосовується для для звʼязку з ДПС. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Ризик
|Дешеві USB-RS232 адаптери можуть давати нестабільний звʼязок. Але Python можна використовувати у двох режимах:
!Перевірка
!Статус
)
def execute_with_retry(command, retries: int = 3, delay: float = 1.0):
"OK;"
МІНІ-ФП54.01
if not self.shift_opened:
@abstractmethod command_name,
- контрольну суму;
def test_payment_less_than_total():
↓
Unit / integration tests
<syntaxhighlight lang="python"> from mini_fp54_ole import MiniFP54OleDriver
if self.shift_opened:
3. !Примітка
{| class="wikitable"
↓
macOS:
return response.decode(self.config.encoding, errors="replace")
def get_status(self) -> str:
|-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Рекомендовано
|Windows — найпростіша ОС для інтеграції через офіційний OLE/DLL. Python можна використовувати через пакет `pywin32`, якщо встановлено та зареєстровано OLE-сервер. |}
pass
MiniFP54SerialConfig(
!Статус
Типові помилки інтеграції
Приклад smoke-тесту через serial
assert result == "ERROR;PAYMENT_LESS_THAN_TOTAL"
</syntaxhighlight>
Емуляція serial-пристрою без фізичного РРО
Для тестування serial-драйвера без пристрою можна зробити локальний емулятор.
Варіант для Linux/macOS
return self.connection.read(read_size) started_at = time.time()
pass
!Статус
↓
return "ERROR;SHIFT_ALREADY_OPEN"
Базова структура Python-обгортки
/dev/pts/3
payload = command.encode(self.config.encoding)
!Коментар
- довжину;
class MiniFP54SerialClient:
Python-обгортка над OLE-сервером Юнісістем. # Перевірити Ethernet або GSM/GPRS для передачі даних. |}
for index in range(total): timeout: float = 3.0
| Очікуваний результат | |
|---|---|
| Кількість товарів | 16 384 |
| Кількість відділів | 64 |
| Кількість касирів | 32 |
| Кількість символів у рядку | 32 |
| Кількість символів у назві товару | 48 |
| Початкове повідомлення | 12 рядків |
| Заключне повідомлення | 2 рядки |
| Дисплей покупця | Вбудований, 2×16 символів |
| Друк | Термодрук |
| Ширина стрічки | 58 мм |
| Швидкість друку | 8 рядків/с |
| Живлення | Вбудований Li-Pol акумулятор |
| Акумулятор | 7,4 В; 2 А·год, опційно 3,6 А·год |
| RS-232 | 1 порт |
| USB | 1 порт |
| Bluetooth | Опція |
| Грошова скринька | micro-jack 2,5 мм |
| Ethernet | виступає як |
| GSM/GPRS | Вбудований |
| Габарити | 181 × 123 × 102 мм |
| Маса | 0,73 кг |
!Правило
Призначення файлів
- USB;
- RS-232 / COM-порт. return "OK;SHIFT_OPENED"
socat -d -d pty,raw,echo=0 pty,raw,echo=0
if any(keyword.lower() in name.lower() for keyword in keywords):
!Висновок
Типовий робочий цикл
Це не повний драйвер. # Підключити пристрій через USB або RS-232. |-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Корисно |Така структура підходить для побудови власного драйвера. |}
COM3, COM4, COM5 ... Це дає можливість перевірити POS-логіку, але не замінює тестування з реальним РРО. # Виконати команду отримання статусу. print("Status:", driver.get_status())
assert result == "OK;PAYMENT_ACCEPTED;CHANGE=0.00"
Python / C# / 1C / інше ПЗ
- дату й час команди;
- тип команди;
- параметри команди;
- відповідь пристрою;
- код помилки;
- COM-порт;
- тривалість виконання;
- номер чека;
- номер зміни. Реальний формат треба взяти з протоколу обміну. name="Кава",
driver = MiniFP54OleDriver(PROG_ID)
Тестування з реальним пристроєм
|- |USB |Підключення до ПК |базовий варіант для POS-інтеграції. |}
driver.sell_item("Кава", price=50.00, quantity=2)
def sell_item(self, name: str, price: float, quantity: float) -> str:
return f"OK;RECEIPT_CLOSED;TOTAL={self.total:.2f}"
!Статус
def test_success_sale_flow():
== Тестування драйвера без пристрою ==
def sell_item(self, name: str, price: float, quantity: float) -> str:
МІНІ-ФП54.01
!Статус
↓
Типова схема підключення:<pre>
if self.receipt_opened:
<syntaxhighlight lang="python"> import winreg
!ОС
== Ethernet, GSM/GPRS і Bluetooth ==
=== Приклад smoke-тесту через OLE ===
timeout=self.config.timeout,
finally:
{| class="wikitable"
USB або COM
def disconnect(self):
=== Рекомендований retry-механізм ===
print("Open port:", driver.open_port(port=3, baudrate=115200))
def close_shift(self) -> str:
driver.open_shift()
def __init__(self, prog_id: str):
|-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |критично
|Назва ProgID у прикладах нижче умовна. def get_status(self) -> str:
result = command()
return (
</pre>
command_name,
if amount < self.total:
return "ERROR;PAYMENT_LESS_THAN_TOTAL"
change = round(amount - self.total, 2)
return f"OK;PAYMENT_ACCEPTED;CHANGE={change:.2f}"
def close_receipt(self) -> str:
self.connection.write(payload)
Приклад. # Виконати персоналізацію. |}
{| class="wikitable"
assert result == "OK;RECEIPT_CLOSED;TOTAL=100.00"
driver.open_receipt()
9.=== Встановлення залежності ===
def open_shift(self) -> str:
├── config.py
<syntaxhighlight lang="python"> class FakeMiniFP54Driver(FiscalDriverInterface):
<syntaxhighlight lang="python"> import time
@abstractmethod
result = driver.sell_item("Кава", price=50.00, quantity=2)
!Варіант
POS-система
/dev/ttyUSB0 або /dev/ttyS0
!Значення
МІНІ-ФП54.01 найпростіше інтегрувати у Windows через офіційний DLL/OLE-сервер. # Перевірити передачу даних. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Контроль
|Потрібно перевіряти статус передачі даних. Після встановлення USB-драйвера пристрій зазвичай функціонує як віртуальний COM-порт. Окремо варто відзначити контрольну стрічку в електронній формі, інтерфейси підключення до ПК через '''USB''' або '''RS-232''', а так само канали передачі даних через '''Ethernet''' і '''GSM/GPRS'''. Але інтеграційні функції ERP можлива через serial-порт, якщо реалізувати протокол обміну. Пробивати чеки продажу. result = driver.pay_cash(50.00)
def connect_to_ole(self):
driver = FakeMiniFP54Driver()
|-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Обовʼязково
|Усі операції продажу мають проходити через фіскальний реєстратор. # Налаштувати типи оплат. |-
|Serial
|pyserial
|Windows / Linux / macOS
|Потрібна реалізація протоколу обміну. За потреби друкувати X-звіт. Перевірити передачу даних. OLE/DLL Юнісістем
client.disconnect()
return result
- Назви методів потрібно звірити з документацією до конкретної версії OLE. # Перевірити роботу POS-системи з реальним драйвером. duration = round(time.time() - started_at, 3)
!Коментар
=== Пошук ProgID OLE-сервера ===
class FiscalDriverInterface(ABC):
"""
1. return "OK;RECEIPT_OPENED"
def get_status(self):
return self.driver.ZReport()
name = winreg.EnumKey(root, index)
)
8.
Простий Python-емулятор
return "OK;PAYMENT_ACCEPTED\n" "command=%s duration=%s result=%s",
from mini_fp54_serial import MiniFP54SerialClient, MiniFP54SerialConfig
print(f"Fake MINI-FP54.01 emulator started on {PORT}")
driver.open_receipt()
price=50.00,
PORT = "/dev/pts/4" BAUDRATE = 115200
return "ERROR;RECEIPT_IS_OPEN"
Офіційних прикладів саме для Python на сторінці підтримки не знайдено. # Провести тестовий день роботи.== Логування ==
- службові байти;
== Обробка помилок ==
return "ERROR;RECEIPT_ALREADY_OPEN"
try:
if not self.items:
keywords = ["Ecr", "T400", "MINI", "FP", "Unisystem", "Uni"]
!Коментар Перед production-запуском потрібно: !Тест
Пристрій має акумулятор. - парсинг статусів і помилок. ser.write(response.encode("cp1251")) Можна створити пару віртуальних serial-портів через `socat`. # Налаштувати заголовок і підвал чека. Відкрити зміну. ├── logger.py
last_error = result
if command.startswith("PAY"):
↓
self.config = config exc,
return "ERROR;EMPTY_RECEIPT"
Приклад логування в Python
FakeMiniFP54Driver
"""
RS-232 підходить для класичних POS-систем, касових терміналів і embedded-рішень.== Основні характеристики ==
driver.sell_item( return "ERROR;RECEIPT_NOT_OPEN"
</syntaxhighlight>
print("Close port:", driver.close_port())
pip install pyserial
технічна архітектура тестування без пристрою
</syntaxhighlight>
Один порт використовує тестовий POS-драйвер, інший — емулятор пристрою. command = command.strip()
FiscalDriverInterface
if not self.connection or not self.connection.is_open: ↓
import serial
</pre>
def log_fiscal_command(command_name: str, callback):
!Файл
logging.info(
|-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Умовний приклад
|Команда GET_STATUS наведена як приклад. result = driver.pay_cash(100.00)
"""
<syntaxhighlight lang="powershell"> Get-ChildItem "Registry::HKEY_CLASSES_ROOT" |
def close_port(self):
{| class="wikitable"
|-
|1
|Відкрити порт
|Драйвер не повертає помилку
|-
|2
|Отримати статус
|Пристрій відповідає
|-
|3
|Отримати версію ПЗ
|Повертається реліз системи пристрою
|-
|4
|Перевірити папір
|Немає помилки паперу
|-
|5
|Відкрити зміну
|Зміна відкрита
|-
|6
|Відкрити чек
|Чек відкритий
|-
|7
|Додати товар
|Рядок товару надруковано або прийнято
|-
|8
|Провести оплату
|Оплата прийнята
|-
|9
|Закрити чек
|Чек закритий
|-
|10
|Надрукувати X-звіт
|Звіт друкується без закриття зміни
|-
|11
|Надрукувати Z-звіт
|Зміна закрита
|-
|12
|Перевірити передачу даних
|інформаційні дані передаються через Ethernet або GSM/GPRS
|}
self.shift_opened = False
driver = MiniFP54OleDriver("PUT_REAL_PROG_ID_HERE") driver.connect_to_ole()
{| class="wikitable"
baudrate=self.config.baudrate,
# Зареєструвати РРО. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Не запускати в production
|Поки не перевірено на тестовому РРО або у нефіскальному режимі. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Не робити
|Не підключати одночасно USB і RS-232 до одного ПК
|Для роботи з ПК потрібно використовувати один інтерфейс підключення. |-
| style="background:#fff3cd; color:#856404; font-weight:bold;" |Не замінює РРО
|Емулятор не перевіряє реальний фіскальний протокол. |-
| style="background:#f8d7da; color:#721c24; font-weight:bold;" |Не готово з коробки
|Офіційного macOS SDK не знайдено.<pre>
driver.open_port(port=3, baudrate=115200)
=== Unit-тест успішного продажу ===
@abstractmethod
Реальний режим — це робота з фіскалізованим пристроєм, який застосовується для для реєстрації розрахункових операцій. Її треба уточнити після встановлення реального OLE-сервера. Увімкнути фіскальний реєстратор. if price <= 0:
return "ERROR;INVALID_PRICE"
if quantity <= 0:
return "ERROR;INVALID_QUANTITY"
amount = round(price * quantity, 2)
self.items.append(
{
"name": name,
"price": price,
"quantity": quantity,
"amount": amount,
}
)
self.total = round(self.total + amount, 2)
return f"OK;ITEM_ADDED;{amount:.2f}"
def pay_cash(self, amount: float) -> str:
|-
| style="background:#d4edda; color:#155724; font-weight:bold;" |Добре
|USB простіше використовувати на сучасних робочих місцях. with serial.Serial(PORT, BAUDRATE, timeout=1) as ser:
parity=serial.PARITY_NONE,
if self.receipt_opened:
return self.driver.GetStatus()
return "OK;Z_REPORT_PRINTED"
↓
Мета тестування без пристрою:
result = callback()
!Статус
6. |}
)
assert result == "OK;ITEM_ADDED;100.00" - формат пакета; self.connection.flush()
Недоліки: Це найпростіший варіант для Windows. Перевірити папір. |- |Mock-драйвер |pytest / unittest |Будь-яка |Для тестування без фізичного пристрою. except Exception as exc:
Умовний приклад текстової команди. return "ERROR;SHIFT_NOT_OPEN"
Значення
bytesize=serial.EIGHTBITS,def pay_cash(self, amount: float): ├── fake_driver.py def close_shift(self) -> str: continue last_error = None return self.driver.OpenReceipt() return self.driver.OpenShift() while True: response = self.send_raw(payload) 5. |} return "ERROR;RECEIPT_NOT_OPEN"
|
|---|