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-байта (сейчас они логируются, но не
|
тогда уточним смысл флага и 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.
|
- `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">✓ Контрольная цифра EAN-13/EAN-8; сканер vs ручной ввод</li>
|
||||||
<li class="ok">✓ Юнит-тесты оборудования: 50/50 зелёных</li>
|
<li class="ok">✓ Юнит-тесты оборудования: 50/50 зелёных</li>
|
||||||
<li class="ok">✓ «Проверка оборудования» запускается на реальной Windows 11 (скриншот ниже)</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">✗ Живое чтение веса через виртуальную пару COM на VM — НЕ выполнено (драйвер com0com требует доверия издателю; нужно решение владельца)</li>
|
||||||
<li class="no">✗ Реальные весы с грузом (гирей) в магазине — НЕ проверялись (нужен человек)</li>
|
<li class="no">✗ Реальные весы с грузом (гирей) в магазине — НЕ проверялись (нужен человек)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -26,5 +28,9 @@ code{background:#eef2f7;padding:1px 5px;border-radius:4px;font-size:13px}
|
||||||
<figcaption>«ALL MARKET — Проверка оборудования» на Win11 (VM): без входа; определены COM1 и принтер; тестовая печать выключена; поле сканера активно.</figcaption>
|
<figcaption>«ALL MARKET — Проверка оборудования» на Win11 (VM): без входа; определены COM1 и принтер; тестовая печать выключена; поле сканера активно.</figcaption>
|
||||||
<img src="vm-hwcheck-launch.png" loading="lazy">
|
<img src="vm-hwcheck-launch.png" loading="lazy">
|
||||||
</figure>
|
</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>
|
<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 = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(350) };
|
||||||
_timer.Tick += (_, _) => LiveTick();
|
_timer.Tick += (_, _) => LiveTick();
|
||||||
|
|
||||||
|
if (Program.AutoFind)
|
||||||
|
Dispatcher.UIThread.Post(() => DiscoverScale(), DispatcherPriority.Background);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Control BuildLayout()
|
private Control BuildLayout()
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,42 @@ internal static class Program
|
||||||
/// (ключ даёт владелец). Без него кнопка «Тестовая печать» выключена и на принтер
|
/// (ключ даёт владелец). Без него кнопка «Тестовая печать» выключена и на принтер
|
||||||
/// ничего не отправляется.</summary>
|
/// ничего не отправляется.</summary>
|
||||||
public static bool AllowTestPrint { get; private set; }
|
public static bool AllowTestPrint { get; private set; }
|
||||||
|
/// <summary>Запустить автопоиск весов сразу при открытии (для скриншотов/проверки).</summary>
|
||||||
|
public static bool AutoFind { get; private set; }
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
AllowTestPrint = args.Contains("--allow-test-print");
|
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);
|
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||||
return 0;
|
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()
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
{
|
{
|
||||||
var b = AppBuilder.Configure<App>().UsePlatformDetect();
|
var b = AppBuilder.Configure<App>().UsePlatformDetect();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue