docs(pos): фикс автопоиска весов (Bluetooth) проверен на Win11 + --autofind
- HwCheck: флаг --autofind (автопоиск при старте — для скриншотов/проверки). - docs/pos-scale-2026-10-11: добавлен скриншот автопоиска на VM (COM1 в журнале, без зависания), отчёт обновлён — новый zip hardware-check и его SHA256; полная проверка с эмулятором/зависшим виртуальным портом ждёт com0com (решение владельца). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
f15a12695c
commit
8371ef6683
|
|
@ -88,6 +88,50 @@ Linux-сборку не ломали (System.IO.Ports/System.Management общи
|
|||
тогда уточним смысл флага и control-байта (сейчас они логируются, но не
|
||||
интерпретируются).
|
||||
|
||||
## Исправление бага автопоиска (Bluetooth) — по реальному запуску на кассе 11.10
|
||||
|
||||
**Симптом (sysadmin):** на ноутбуке магазина порты COM7/COM8 (Bluetooth, «The write
|
||||
timed out»), COM15–17 (неопознанные), **COM22 = USB-SERIAL CH340 (там весы)**.
|
||||
«Найти весы» → «Весы не найдены ни на одном порту», хотя ручной выбор
|
||||
COM22/57600/Масса-К-кадр даёт «0,000 кг, стабильно». Причина: автопоиск спотыкался
|
||||
о Bluetooth-порты (Open/Write на них висят) и до COM22 не доходил; по умолчанию в
|
||||
списке стоял COM7 (Bluetooth).
|
||||
|
||||
**Исправлено (и в кассе, и в HwCheck):**
|
||||
- Порты классифицируются по типу (WMI, без открытия): **USB-serial** (CH340/
|
||||
Prolific/FTDI/CP210x), **Bluetooth** (BTHENUM/«по соединению Bluetooth»),
|
||||
неопознанные. Порядок автопоиска: **USB-serial → неопознанные → Bluetooth**.
|
||||
- На каждый порт — **жёсткий таймаут** (Open обёрнут в задачу с гонкой против
|
||||
Task.Delay; при зависании транспорт принудительно закрывается). Порты
|
||||
перебираются **параллельно (до 4)**, общий бюджет ~15 с. Любая ошибка/таймаут
|
||||
на порту → следующий порт, перебор не останавливается.
|
||||
- **Лог по каждому порту** в окне: «COM22 (USB-SERIAL CH340): ENQ→ACK, вес 0.000 кг»,
|
||||
«COM7: пропущен Bluetooth-порт», «COM15: нет ответа». Листинг портов тоже не
|
||||
открывает Bluetooth (помечает «не опрашивается»). По умолчанию выбирается
|
||||
НЕ Bluetooth-порт.
|
||||
- Из zip hardware-check **убран ярлык «(с тестовой печатью).bat»** (печать — только
|
||||
отдельно, по слову владельца).
|
||||
- Юнит-тесты: «зависающий» порт (Open 30 с) **не задерживает поиск дольше таймаута**,
|
||||
живой порт вторым — **найден**; USB-serial проверяется раньше Bluetooth
|
||||
(BT не трогаем). Всего по оборудованию 53/53 зелёных.
|
||||
|
||||
**Проверка на Windows 11 (VM):** «Проверка оборудования» запущена с автопоиском
|
||||
(`--autofind`) — перебрала COM1, записала в журнал «COM1: нет ответа» и **завершилась
|
||||
быстро, без зависания** (на VM нет весов и нет Bluetooth-порта). См.
|
||||
`vm-hwcheck-autofind.png`.
|
||||
|
||||
**НОВЫЙ zip hardware-check (с фиксом):**
|
||||
`~/pos-release/allmarket-pos-win-x64-20261011-0906-hardware-check.zip`
|
||||
SHA256 `ac5cedef0f5dd63e98f0f3044ef453666f71d8c18280107983b1023cbd573623`
|
||||
(один ярлык «Проверка оборудования.bat», без ярлыка печати).
|
||||
|
||||
**Полная проверка с эмулятором весов + «зависающим» виртуальным портом (п. 7) —
|
||||
по-прежнему требует com0com на VM**, установка драйвера которого упирается в доверие
|
||||
издателю (см. выше) — ждёт решения владельца. Поведение «не виснуть на зависшем
|
||||
порту» доказано юнит-тестом детерминированно; на VM показано, что автопоиск логирует
|
||||
по портам и быстро завершается.
|
||||
|
||||
## Файлы
|
||||
- `vm-hwcheck-launch.png` — окно «Проверка оборудования» на Windows 11.
|
||||
- `index.html` — та же сводка со скриншотом.
|
||||
- `vm-hwcheck-autofind.png` — автопоиск с журналом по портам (COM1), без зависания.
|
||||
- `index.html` — сводка со скриншотами.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ code{background:#eef2f7;padding:1px 5px;border-radius:4px;font-size:13px}
|
|||
<li class="ok">✓ Контрольная цифра EAN-13/EAN-8; сканер vs ручной ввод</li>
|
||||
<li class="ok">✓ Юнит-тесты оборудования: 50/50 зелёных</li>
|
||||
<li class="ok">✓ «Проверка оборудования» запускается на реальной Windows 11 (скриншот ниже)</li>
|
||||
<li class="ok">✓ Фикс автопоиска: USB-serial первыми, Bluetooth последними, жёсткий таймаут на порт, параллельно, лог по портам (баг на кассе 11.10 — виснул на Bluetooth, не доходил до CH340)</li>
|
||||
<li class="ok">✓ Тест: «зависающий» порт (Open 30 с) не задерживает поиск; живой порт вторым — найден</li>
|
||||
<li class="no">✗ Живое чтение веса через виртуальную пару COM на VM — НЕ выполнено (драйвер com0com требует доверия издателю; нужно решение владельца)</li>
|
||||
<li class="no">✗ Реальные весы с грузом (гирей) в магазине — НЕ проверялись (нужен человек)</li>
|
||||
</ul>
|
||||
|
|
@ -26,5 +28,9 @@ code{background:#eef2f7;padding:1px 5px;border-radius:4px;font-size:13px}
|
|||
<figcaption>«ALL MARKET — Проверка оборудования» на Win11 (VM): без входа; определены COM1 и принтер; тестовая печать выключена; поле сканера активно.</figcaption>
|
||||
<img src="vm-hwcheck-launch.png" loading="lazy">
|
||||
</figure>
|
||||
<figure>
|
||||
<figcaption>Фикс автопоиска на Win11: перебрал COM1, записал в журнал «COM1: нет ответа», завершился быстро без зависания (на VM нет весов/Bluetooth).</figcaption>
|
||||
<img src="vm-hwcheck-autofind.png" loading="lazy">
|
||||
</figure>
|
||||
|
||||
<p>Подробности, SHA256 сборок и список «нужно решение владельца» — в <code>REPORT.md</code>.</p>
|
||||
|
|
|
|||
BIN
docs/pos-scale-2026-10-11/vm-hwcheck-autofind.png
Normal file
BIN
docs/pos-scale-2026-10-11/vm-hwcheck-autofind.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
|
|
@ -66,6 +66,9 @@ public MainWindow(bool allowTestPrint)
|
|||
|
||||
_timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(350) };
|
||||
_timer.Tick += (_, _) => LiveTick();
|
||||
|
||||
if (Program.AutoFind)
|
||||
Dispatcher.UIThread.Post(() => DiscoverScale(), DispatcherPriority.Background);
|
||||
}
|
||||
|
||||
private Control BuildLayout()
|
||||
|
|
|
|||
|
|
@ -8,15 +8,42 @@ internal static class Program
|
|||
/// (ключ даёт владелец). Без него кнопка «Тестовая печать» выключена и на принтер
|
||||
/// ничего не отправляется.</summary>
|
||||
public static bool AllowTestPrint { get; private set; }
|
||||
/// <summary>Запустить автопоиск весов сразу при открытии (для скриншотов/проверки).</summary>
|
||||
public static bool AutoFind { get; private set; }
|
||||
|
||||
[STAThread]
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
AllowTestPrint = args.Contains("--allow-test-print");
|
||||
AutoFind = args.Contains("--autofind");
|
||||
// Headless-режим для скриптов/интеграционного теста: одно чтение веса и выход.
|
||||
// --read-once <PORT> [BAUD] [MassaKFrame|MassaKAscii|Cas]
|
||||
if (args.Contains("--read-once")) return ReadOnceCli(args);
|
||||
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int ReadOnceCli(string[] args)
|
||||
{
|
||||
int i = Array.IndexOf(args, "--read-once");
|
||||
string port = (i + 1 < args.Length) ? args[i + 1] : "";
|
||||
int baud = (i + 2 < args.Length && int.TryParse(args[i + 2], out var b)) ? b : 57600;
|
||||
var proto = (i + 3 < args.Length && Enum.TryParse<Core.Hardware.ScaleProto>(args[i + 3], out var p))
|
||||
? p : Core.Hardware.ScaleProto.MassaKFrame;
|
||||
if (string.IsNullOrEmpty(port)) { Console.Error.WriteLine("usage: --read-once <PORT> [BAUD] [PROTO]"); return 2; }
|
||||
try
|
||||
{
|
||||
using var t = new Core.Hardware.SystemSerialTransport(port, baud);
|
||||
t.Open();
|
||||
var (r, hex, err) = Core.Hardware.SerialScaleReader.ReadDetailed(t, proto);
|
||||
if (r is null) { Console.Error.WriteLine($"FAIL: {err} hex=[{hex}]"); return 1; }
|
||||
Console.WriteLine($"OK kg={r.Value.Kg:0.000} unit={r.Value.Unit} flag='{r.Value.Flag}' " +
|
||||
$"control={(r.Value.Control is null ? "-" : "0x" + r.Value.Control.Value.ToString("X2"))} hex=[{r.Value.RawHex}]");
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex) { Console.Error.WriteLine("ERR: " + ex.Message); return 3; }
|
||||
}
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
{
|
||||
var b = AppBuilder.Configure<App>().UsePlatformDetect();
|
||||
|
|
|
|||
Loading…
Reference in a new issue