# LED Mapper LED Mapper — настольное приложение на Python и PySide6 для разметки LED-точек на схеме, распределения их по физическим линиям светодиодных лент и генерации `vm_map.h` для прошивки. Приложение помогает вручную или полуавтоматически собрать адресацию светодиодов: выбрать точки на схеме, создать линии, разбить их на блоки, проверить индексацию и сгенерировать готовые файлы маппинга. ## Возможности - Загрузка карты LED-точек из JSON. - Отображение схемы в реальных координатах. - Выделение точек мышью и работа через таблицу выбранных LED. - До 4 физических линий светодиодных лент. - Нумерация линий и блоков с `0`. - Блоки внутри линий, включая пустые блоки. - Индексация LED отдельно для каждой линии, начиная с `0`. - Индексация внутри каждого блока. - Добавление блоков вручную, из выделения, автоблоками и кистью. - Продолжение существующего блока кистью от последней точки блока. - Предпросмотр зоны действия кисти и точек, которые будут добавлены. - Сетка с настраиваемым шагом (по умолчанию 34 мм) во всех режимах редактирования и генерации. - Настраиваемый абсолютный диаметр LED-точек: визуальный размер не меняется при приближении. - Undo/redo для операций разметки. - Удаление назначений через `Del` и контекстные меню. - Пакетное удаление выбранных блоков через дерево одной операцией с единым Undo. - Сворачивание боковой панели. - Сортировка таблицы выбранных точек по столбцам. - Генерация `vm_map.h`, `ordered_circles.json`, `validation_report.txt` и README для результата. - Сборка самостоятельного Windows EXE через PyInstaller. - Проверка и установка Windows-обновлений из релизов Gitea. ## Структура приложения ```text main.py Точка входа GUI-приложения main_window.py Главное окно, меню, действия, таблица и дерево линий canvas.py Холст схемы, выделение, кисть, сетка и связи models.py Модель карты, линий, блоков и алгоритмы маршрутов panel_mapping_generator.py Генерация файлов маппинга update_service.py Проверка релизов и безопасная установка Windows EXE version.py Базовая версия приложения при запуске из исходников icons.py Встроенные lucide-иконки unfolding.py Описание развертки линий и блоков qa_smoke.py Smoke-тесты приложения requirements.txt Runtime-зависимости LEDMapper.spec PyInstaller-конфигурация для сборки EXE ``` ## Требования - Windows. - Python 3.10 или новее. - PySide6. Для разработки и запуска используется локальное виртуальное окружение проекта. ## Быстрый старт Из корневой папки проекта создайте окружение: ```powershell python -m venv .venv ``` Установите зависимости: ```powershell .\.venv\Scripts\python.exe -m pip install -r app\requirements.txt ``` Запустите приложение: ```powershell .\.venv\Scripts\python.exe app\main.py ``` Если вы находитесь внутри папки `app`, запуск выглядит так: ```powershell ..\.venv\Scripts\python.exe main.py ``` ## Основной сценарий работы 1. Откройте JSON-карту точек через `Файл -> Открыть`. 2. Создайте линию кнопкой `Линия` или через меню `Инструменты -> Новая линия`. 3. Выберите точки на схеме или в таблице. 4. Создайте блок из выбранных точек, автоблоки или включите инструмент `Кисть`. 5. Повторите разметку для остальных линий и блоков. 6. Проверьте счетчики в верхней части боковой панели: количество линий, блоков и назначенных LED. 7. Сгенерируйте скрипт через `Файл -> Сгенерировать скрипт`. Шаг сетки и диаметр точек меняются в `Файл -> Параметры -> Внешний вид`. Для каждого значения рядом есть кнопка `Сбросить`. Шаг сетки сохраняется в JSON текущей схемы, а диаметр точек — в пользовательских параметрах приложения. Изменение шага не перемещает уже существующие LED автоматически. Чтобы удалить несколько блоков, выделите их в дереве с `Ctrl` или `Shift`, затем нажмите `Ctrl+Del` или выберите удаление в контекстном меню. Приложение показывает одно подтверждение и создаёт одну операцию Undo. В режиме редактирования выбранные светодиоды можно скопировать через `Ctrl+C` и вставить через `Ctrl+V`. Вставленные LED остаются свободными, сохраняют взаимное расположение и пользовательские поля исходных точек. Первая копия смещается на один шаг сетки вправо и вниз, а следующие вставки образуют каскад. Вся группа вставляется одной операцией Undo и сразу становится текущим выделением. В собранном Windows EXE приложение проверяет наличие нового стабильного релиза после запуска. В меню `Справка` можно запустить проверку вручную и, если новая версия найдена, выбрать `Установить обновление`. Загружается только артефакт вида `LEDMapper-vX.Y.Z.exe` из репозитория `Robotail/LED-mapper` на `git.robotail.pro`. После проверки размера и формата EXE приложение предлагает сохранить изменённую схему, закрывается, а отдельный процесс заменяет EXE по прежнему пути и запускает новую версию — существующие ярлыки продолжают работать. Версия релизной сборки хранится внутри EXE, поэтому переименование файла не вызывает повторную установку того же обновления. При неудачном запуске старая версия восстанавливается; причина записывается рядом с EXE в `update-error.log`. Для обновления нужны доступ к серверу релизов и право записи в каталог приложения. Из исходников можно проверить наличие версии, но автоустановка недоступна. Если не назначен ни один светодиод, генерация не запускается. Если назначены не все светодиоды, приложение показывает предупреждение и предлагает либо сгенерировать неполный маппинг, либо продолжить редактирование. ## Горячие клавиши | Действие | Клавиши | | --- | --- | | Открыть | `Ctrl+O` | | Сохранить | `Ctrl+S` | | Сохранить как | `Ctrl+Shift+S` | | Сгенерировать скрипт | `Ctrl+G` | | Отменить | `Ctrl+Z` | | Повторить | `Ctrl+Y` | | Копировать выбранные LED | `Ctrl+C` | | Вставить скопированные LED | `Ctrl+V` | | Удалить фиксацию | `Del` | | Удалить выбранные точки или блоки | `Ctrl+Del` | | Удалить все | `Ctrl+Shift+Del` | | Очистить выбор | `Esc` | | Показать всю схему | `Ctrl+0` | | Сетка | `G` | | Стрелки направления | `Ctrl+Shift+A` | | Скрыть/показать боковую панель | `F9` | | Новая линия | `Ctrl+L` | | Автоблоки | `Ctrl+Shift+B` | | Кисть | `B` | ## Генерация файлов маппинга Генератор создает: - `vm_map.h` — основной header для прошивки. - `ordered_circles.json` — нормализованные точки и координаты виртуальной матрицы. - `validation_report.txt` — отчет о проверках маршрутов и ячеек. - `README.md` — краткое описание результата генерации. Устаревший `virtual_matrix_legacy.ino.txt` больше не создаётся. Если файл с этим точным именем остался в выходной папке от прежней версии, следующая успешная генерация удалит его. Другие `.ino`-файлы не затрагиваются. JSON схемы хранит `coordinate_unit`, `grid_step_mm` и `index_base: 0`. При первом открытии старого файла без единицы координат приложение определяет её один раз и затем сохраняет явно. Старые схемы с 1-based ID линий и блоков при загрузке переводятся на 0-based; сохранение записывает маркер `index_base: 0`, чтобы повторная загрузка не сдвигала ID. Сохранение выполняется через временный файл и атомарную замену, поэтому исходный JSON не повреждается при ошибке записи. Если у схемы есть подложка, при сохранении её исходное PNG- или JPEG-изображение встраивается в секцию `background.embedded_image` внутри JSON вместе с именем, MIME-типом и контрольной суммой. После этого схема не зависит от внешнего файла, а размеры и параметры подложки сохраняются при редактировании и переносе JSON. Для уже встроенного и не заменённого изображения диалог `Подложка` показывает в поле пути значение `Встроенная`. Чтобы заменить его, нажмите `Выбрать` и укажите новый файл; новое изображение будет встроено при следующем сохранении схемы. В `vm_map.h` используются физические адреса из GUI: - `strip = line_id` - `led_id = line_index` Неназначенные точки не попадают в рабочий `VM_MAPPINGS`, но исходные точки могут оставаться в служебных метаданных. ## Ориентация виртуальной матрицы Текущий формат явно описывает преобразование координат: ```cpp #define VM_ROW_FROM_GRID_COL(col) (GRID_COL_MAX - (col)) #define VM_COL_FROM_GRID_ROW(row) ((row) - GRID_ROW_MIN) ``` То есть строка виртуальной матрицы получается из исходной колонки с отражением, а колонка виртуальной матрицы получается из исходного ряда. ## Проверка качества Из корня проекта: ```powershell .\.venv\Scripts\python.exe app\qa_smoke.py ``` Проверка компиляции основных модулей: ```powershell .\.venv\Scripts\python.exe -m py_compile app\main.py app\main_window.py app\canvas.py app\models.py app\panel_mapping_generator.py app\qa_smoke.py ``` ## Сборка EXE Установите PyInstaller в `.venv`: ```powershell .\.venv\Scripts\python.exe -m pip install pyinstaller ``` Сборка из корня проекта: ```powershell .\.venv\Scripts\python.exe -m PyInstaller --noconfirm --clean app\LEDMapper.spec ``` В чистой сборке из релизного тега файл будет называться: ```text dist/LEDMapper-vX.Y.Z.exe ``` `build/` и `dist/` не коммитятся, потому что это воспроизводимые артефакты сборки. ## Примечания для разработки - Для работы с приложением использовать только Python из `.venv`. - Не коммитить `.venv`, `build`, `dist`, `output` и `__pycache__`. - Перед коммитом желательно запускать `app\qa_smoke.py`. - Максимальное количество линий светодиодных лент: 4.