# Восстановление Orange Pi на новой SD-карте Runbook на случай, когда карта деградировала и устройство надо поднять с нуля. Составлен во время инцидента 22.07.2026: ФС ушла в read-only — захват кадра и SSH отвалились, при этом heartbeat и публикация веса в MQTT продолжали работать. ## Что взять на пост - новая SD-карта, **high-endurance** (Samsung PRO Endurance / SanDisk Max Endurance); 32 ГБ хватает с запасом — занято ~12% - образ Armbian для Orange Pi PC, записанный заранее - `orange_pi/scales.py`, `orange_pi/outbox.py`, `orange_pi/scales.service` из этого репозитория - старую карту НЕ выбрасывать: с неё может понадобиться вытащить остатки очереди outbox ## 1. Система apt update apt install -y python3 python3-pip ffmpeg pip3 install paho-mqtt # на свежих Debian/Armbian добавить --break-system-packages Больше внешних зависимостей нет — всё остальное в скрипте из stdlib. ## 2. Файлы Рабочий файл на устройстве — именно `/root/scales.py`; репозиторий на OPi не клонируется, файл доставляется вручную. `outbox.py` кладётся рядом, в `/root`. cp scales.py outbox.py /root/ Актуальную версию можно скачать прямо с сервера: curl -s -o /root/scales.py https://scales.zeroday.su/testphotos/scales.py ## 3. Сервис cp scales.service /etc/systemd/system/scales.service systemctl daemon-reload systemctl enable --now scales.service systemctl status scales.service --no-pager ## 4. Проверки после старта # в логе должны появиться MQTT1/MQTT2, GPIO, OUTBOX, HEARTBEAT journalctl -u scales.service -n 30 --no-pager # весовой терминал ls -l /dev/ttyUSB0 # камера — тот же вызов, что внутри grab_frame() ffmpeg -y -loglevel error -rtsp_transport tcp -i "" \ -frames:v 1 -update 1 -q:v 2 -f image2 /tmp/scale_frame.jpg && ls -l /tmp/scale_frame.jpg # офлайн-распознавание на боксе curl -s http://192.168.20.4:5010/health # сервер принимает (ожидаемый ответ: {"error":"event_id required"}) curl -s -X POST -H "Content-Type: application/json" -d '{}' https://scales.zeroday.su/api/local-plate Финальная проверка — кнопка «Тест-снимок» в панели: фото должно появиться в заездах. ## 5. Чтобы карта прожила дольше Главный убийца SD-карт — постоянная запись логов. mkdir -p /etc/systemd/journald.conf.d printf '[Journal]\nStorage=volatile\nRuntimeMaxUse=32M\n' > /etc/systemd/journald.conf.d/volatile.conf systemctl restart systemd-journald Убедиться, что `/tmp` — tmpfs (туда пишется кадр перед отправкой): findmnt /tmp Если нет — добавить в `/etc/fstab`: tmpfs /tmp tmpfs defaults,nosuid,nodev,size=128M 0 0 На перспективу: перенос системы на USB-SSD или eMMC снимает проблему целиком. ## Диагностика без SSH Устройство управляется через MQTT-брокер даже когда SSH недоступен (на сервере: `localhost:1883`, пользователь `scales-server`). # живой heartbeat раз в 30 с — значит процесс жив mosquitto_sub -h 127.0.0.1 -p 1883 -u scales-server -P '<пароль>' -t 'scale/device/status' -v # команды: ping (мгновенный статус), test-shot (проверка камеры), reboot mosquitto_pub -h 127.0.0.1 -p 1883 -u scales-server -P '<пароль>' -t 'scale/device/cmd' -m '{"cmd":"ping"}' Как читать симптомы: | признак | что значит | |---|---| | heartbeat идёт, на `ping` отвечает мгновенно | процесс жив, ресурсы в порядке | | `outbox_pending: 0`, но заездов на сервере нет | `capture_and_send` вышел до постановки в очередь — не получен кадр | | `test-shot` не даёт фото, а RTSP из VLC играет | причина локальная на OPi: запись в `/tmp` или ffmpeg | | SSH рвёт соединение на key exchange | sshd не может создать сессию — характерно для read-only ФС | Совпадение последних трёх — почти наверняка карта. ## Известная недоработка `capture_and_send()` при неудачном захвате кадра выходит по `return` **до** постановки события в очередь. Значит отказ камеры теряет не фото, а всю запись о взвешивании — именно так были потеряны заезды 20.07.2026. Вес должен доезжать до сервера и без фото; поправить при ближайшем доступе к устройству.