240 lines
16 KiB
Markdown
240 lines
16 KiB
Markdown
# Техническая конфигурация Exchanger
|
||
|
||
## Назначение и расположение
|
||
|
||
Монтажные параметры автомата хранятся отдельно от настроек владельца и не выводятся ни в одной
|
||
доступной вкладке приложения. Технический специалист меняет TOML при установке или обслуживании
|
||
автомата.
|
||
|
||
Встроенный шаблон:
|
||
|
||
```text
|
||
res://config/technical_settings.toml
|
||
```
|
||
|
||
Рабочий файл конкретного автомата:
|
||
|
||
```text
|
||
user://config/technical_settings.toml
|
||
```
|
||
|
||
Для текущей Windows-сборки это обычно
|
||
`%APPDATA%\Godot\app_userdata\Exchanger\config\technical_settings.toml`.
|
||
|
||
Для Linux-сборки это обычно
|
||
`~/.local/share/godot/app_userdata/Exchanger/config/technical_settings.toml`.
|
||
|
||
При первом запуске приложение копирует встроенный шаблон в `user://config/`. Дальше рабочий файл
|
||
не перезаписывается автоматически, поэтому комментарии и монтажные значения сохраняются.
|
||
|
||
## Порядок применения
|
||
|
||
При старте приложение:
|
||
|
||
1. загружает обычные настройки владельца из `appsettings.json`;
|
||
2. читает и полностью проверяет `technical_settings.toml`;
|
||
3. применяет аппаратные значения и optional `[theme]` из TOML поверх обычных JSON-настроек;
|
||
4. применяет явные аргументы `--theme-dlc`, `--no-theme-dlc` и `--mock-hardware` последними;
|
||
5. загружает выбранную тему и создаёт mock- или COM-транспорт.
|
||
|
||
Изменение TOML во время работы ничего не переключает. После редактирования приложение необходимо
|
||
полностью перезапустить.
|
||
|
||
## Полный пример
|
||
|
||
```toml
|
||
version = 1
|
||
|
||
[theme]
|
||
enabled = true
|
||
directory = "user://theme_dlc"
|
||
file_name = "active_theme"
|
||
|
||
[controller]
|
||
use_mock = true
|
||
port = "COM3"
|
||
baud_rate = 115200
|
||
reconnect_interval_seconds = 30
|
||
handshake_timeout_ms = 2000
|
||
frame_timeout_ms = 100
|
||
max_frame_length = 1024
|
||
cashless_keep_alive_seconds = 120
|
||
|
||
[hopper_1]
|
||
enabled = true
|
||
stock_sensor_input = 1
|
||
stock_low_active_high = false
|
||
dispense_sensor_input = 24
|
||
dispense_pulse_active_high = false
|
||
|
||
[hopper_2]
|
||
enabled = true
|
||
stock_sensor_input = 4
|
||
stock_low_active_high = false
|
||
dispense_sensor_input = 25
|
||
dispense_pulse_active_high = false
|
||
|
||
[service]
|
||
button_input = 8
|
||
button_active_high = false
|
||
|
||
[polling]
|
||
input_poll_ms = 100
|
||
stock_poll_seconds = 5
|
||
```
|
||
|
||
## Каталог и выбор темы
|
||
|
||
Необязательный раздел `[theme]` позволяет монтажнику выбрать PCK без изменения настроек владельца:
|
||
|
||
```toml
|
||
[theme]
|
||
enabled = true
|
||
directory = "/opt/exchanger/themes"
|
||
file_name = "space-pixel"
|
||
```
|
||
|
||
Приложение загрузит `/opt/exchanger/themes/space-pixel.pck`. `directory` принимает `user://` либо
|
||
абсолютный локальный путь текущей ОС; относительные пути, `res://` и сегменты `..` запрещены.
|
||
`file_name` содержит только имя файла без каталога и расширения `.pck`. На Windows поддерживаются
|
||
оба обычных представления:
|
||
|
||
```toml
|
||
# Рекомендуемый вариант с literal-строкой: обратные слеши не экранируются.
|
||
directory = 'D:\Exchanger\themes'
|
||
|
||
# Либо путь с прямыми слешами.
|
||
directory = "D:/Exchanger/themes"
|
||
```
|
||
|
||
Если Windows-путь записывается в двойных кавычках с обратными слешами, каждый `\` по правилам
|
||
TOML необходимо удвоить: `directory = "D:\\Exchanger\\themes"`.
|
||
|
||
`enabled = false` отключает внешний PCK. Раздел является авторитетным относительно полей Themes
|
||
в `appsettings.json`, но разовый аргумент `--theme-dlc=<полный путь>` или `--no-theme-dlc` имеет
|
||
более высокий приоритет. Старые файлы версии 1 без `[theme]` остаются совместимыми: тогда выбор
|
||
темы по-прежнему берётся из `appsettings.json`.
|
||
|
||
## Основной контроллер
|
||
|
||
| Параметр | Назначение | Допустимое значение |
|
||
|---|---|---|
|
||
| `use_mock` | Программный имитатор вместо платы | `true` или `false` |
|
||
| `port` | Порт основного контроллера | Windows: `COM1`…`COM256` или `COM` для автопоиска; Linux: `/dev/ttyUSB*`, `/dev/ttyACM*`, `/dev/serial/by-id/*` или `ttyUSB`/`/dev/ttyUSB` для автопоиска |
|
||
| `baud_rate` | Скорость последовательного порта | 9600, 19200, 38400, 57600, 115200, 230400, 460800 или 921600 |
|
||
| `reconnect_interval_seconds` | Пауза перед повторным подключением | 1…60 с |
|
||
| `handshake_timeout_ms` | Общий предел ожидания авторизации платы | 1000…60000 мс |
|
||
| `frame_timeout_ms` | Ожидание продолжения неполного кадра | 10…5000 мс |
|
||
| `max_frame_length` | Максимальная длина входного кадра | 2…65536 байт |
|
||
| `cashless_keep_alive_seconds` | Интервал keep-alive Вендиста | 30…170 с; штатно 120 с |
|
||
|
||
Первое открытие порта выполняется сразу при запуске. Если платы нет или открыть устройство не
|
||
удалось, следующая попытка выполняется через `reconnect_interval_seconds`, после чего повторяется
|
||
с тем же интервалом. При физическом отключении уже работавшей платы новый полный интервал
|
||
отсчитывается от обнаруженного обрыва: старый дедлайн запуска не используется. Штатное значение —
|
||
30 секунд. Автоматически повторяются только подключение и авторизация; команда оплаты или выдачи
|
||
после обрыва не отправляется повторно. Полное имя (`COM3`, `/dev/ttyUSB0`, `ttyUSB0` и т. п.)
|
||
всегда открывается как один заданный порт. Значение `COM` включает автопоиск: на каждом
|
||
начальном подключении и каждом reconnect приложение получает список доступных COM-портов,
|
||
сортирует их по номеру от `COM0` и последовательно пробует до успешной авторизации. Значение
|
||
`ttyUSB` (также допустимо `/dev/ttyUSB`) аналогично перебирает `/dev/ttyUSB0`,
|
||
`/dev/ttyUSB1` и далее. Открытие чужого последовательного устройства или ошибка/таймаут
|
||
авторизации не считаются успешным подключением: поиск продолжается со следующим номером.
|
||
|
||
Безопасный шаблон содержит `use_mock = true`: простого копирования файла недостаточно для выхода
|
||
на реальную плату. При вводе автомата в эксплуатацию нужно задать правильный порт, проверить
|
||
остальные разделы и только затем изменить значение на `false`.
|
||
|
||
Формат `port` проверяется по ОС, на которой запущено приложение. Windows-сборка с реальной платой
|
||
принимает строгие имена `COM1`…`COM256` или префикс `COM`; Linux-сборка — `/dev/ttyUSB*`,
|
||
`/dev/ttyACM*`, стабильные udev-ссылки `by-id`, префикс `ttyUSB` (с необязательным `/dev/`) и короткие точные имена `ttyUSB0`, `ttyUSB1` и т. д.
|
||
При `use_mock = true` имя порта не используется и не проверяется,
|
||
поэтому общий безопасный шаблон с `COM3` запускается и в Linux.
|
||
|
||
Для Silicon Labs CP210x после подключения обычно используется:
|
||
|
||
```toml
|
||
[controller]
|
||
use_mock = false
|
||
port = "/dev/ttyUSB0"
|
||
```
|
||
|
||
Если каталог `/dev/serial/by-id/` создан udev, предпочтительнее указать находящуюся в нём
|
||
постоянную ссылку: она не меняется при перестановке USB-устройств. Отсутствие самого каталога
|
||
не является ошибкой — тогда используется `/dev/ttyUSB0` или другой фактически назначенный номер.
|
||
Каталог `/dev/usb/` не является заменой узла последовательного порта.
|
||
|
||
## Хопперы
|
||
|
||
Разделы `hopper_1` и `hopper_2` имеют одинаковую структуру:
|
||
|
||
| Параметр | Назначение |
|
||
|---|---|
|
||
| `enabled` | Установлен ли хоппер |
|
||
| `stock_sensor_input` | Индекс входа датчика малого остатка |
|
||
| `stock_low_active_high` | `true`, если высокий уровень означает «мало жетонов» |
|
||
| `dispense_sensor_input` | Индекс отдельного физического датчика выдачи |
|
||
| `dispense_pulse_active_high` | `true`, если высокий уровень означает импульс выдачи |
|
||
|
||
Индекс входа задаётся числом 0…25. Значение `-1` означает, что отдельный физический вход не
|
||
назначен. Для текущей разводки первый датчик выдачи использует `IN24`, второй — `IN25`.
|
||
Обычная выдача подтверждается ответами `HOPPER1/2 OK`, а сервисный пересчёт — ответами
|
||
`HOPPER1/2 PULSE=1`, поэтому физические входы не создают двойной программный учёт.
|
||
|
||
По `enabled` автоматически выбирается профиль команд:
|
||
|
||
| Хоппер 1 | Хоппер 2 | Профиль |
|
||
|---|---|---|
|
||
| включён | включён | `DualHopperAuto` — команды `30X` и `40X` |
|
||
| включён | выключен | `Hopper1Auto` — команды `30X` |
|
||
| выключен | включён | `Hopper2Auto` — команды `40X` |
|
||
| выключен | выключен | выдача не поддерживается |
|
||
|
||
У отключённого хоппера его входы принудительно становятся неактивными независимо от записанных
|
||
чисел. Так узел можно временно отключить, не удаляя его монтажную схему из файла.
|
||
|
||
Если включён только один хоппер, приложение работает как одноканальное: выдача, сервисный
|
||
пересчёт, ручное пополнение, доступный покупателю остаток и mock-режим используют только этот
|
||
хоппер. Строка и кнопки отключённого хоппера скрываются в разделе «Сервис». Его сохранённый
|
||
учётный остаток не удаляется и снова станет доступен, если хоппер вернуть в конфигурацию.
|
||
|
||
## Сервисная кнопка и опрос
|
||
|
||
`service.button_input` задаёт индекс сервисной кнопки, 0…25 либо `-1`, если физическая кнопка
|
||
отключена. `service.button_active_high` задаёт полярность. Для текущей разводки используются
|
||
`IN8` и `false`.
|
||
|
||
`polling.input_poll_ms` задаёт частоту резервного чтения входов в диапазоне 50…1000 мс.
|
||
`polling.stock_poll_seconds` задаёт медленный опрос запаса в диапазоне 1…60 с.
|
||
|
||
## Проверка и безопасное восстановление
|
||
|
||
Все прежние разделы и поля обязательны; новый `[theme]` целиком необязателен для совместимости.
|
||
Если `[theme]` присутствует, обязательны все три его поля. Приложение отклоняет файл целиком, если:
|
||
|
||
- TOML имеет синтаксическую ошибку;
|
||
- отсутствует поле или раздел;
|
||
- версия схемы не равна 1;
|
||
- значение вышло за разрешённый диапазон;
|
||
- один неотрицательный индекс `IN` назначен нескольким активным функциям.
|
||
- каталог темы не является `user://` или абсолютным локальным путём;
|
||
- `file_name` содержит путь либо расширение.
|
||
|
||
Некорректный пользовательский файл не исправляется и не перезаписывается автоматически. Приложение
|
||
выдаёт предупреждение и запускается со встроенным профилем, где `use_mock = true`. Ошибочный
|
||
монтажный файл поэтому не может случайно включить реальное оборудование.
|
||
|
||
AES-ключ, платёжные секреты, PIN владельца, сырые команды и ответы платы в TOML не добавляются.
|
||
|
||
## Чек-лист технической настройки
|
||
|
||
1. Остановить приложение.
|
||
2. Открыть рабочий `user://config/technical_settings.toml`.
|
||
3. Проверить имя последовательного порта текущей ОС и наличие каждого хоппера.
|
||
4. Проверить `reconnect_interval_seconds = 30` либо установить другой допустимый интервал.
|
||
5. Сверить индексы и полярности подключённых входов.
|
||
6. Проверить `[theme].directory` и указать `[theme].file_name` без `.pck`.
|
||
7. Оставить `use_mock = true` для первой проверки интерфейса.
|
||
8. После проверки платы изменить `use_mock` на `false`.
|
||
9. Полностью запустить приложение заново и выполнить отдельный приёмочный прогон оборудования.
|