Files
templates/c/settings-backup

SettingsBackup

SettingsBackup сохраняет только подтверждённые конфигурации в JSON на SD-карту. Ядро Src/settings_backup.c не включает STM32 HAL, FatFs, Modbus, RTC или AppStorage: календарь и нормализованный снимок передаёт приложение, а файловые операции задаются callbacks структуры SettingsBackupPort.

Размещение

При достоверном RTC используется путь:

niceOne/settings/YYYY-MM_EnglishMonth/settings_YYYY-MM-DD_HH-MM-SS.json

Например:

niceOne/settings/2026-07_July/settings_2026-07-17_14-30-05.json

Названия месяцев фиксированы на английском и состоят только из FAT-безопасных ASCII-символов. При недостоверном RTC файл помещается в invalid_rtc и получает имя settings_invalid_rtc_rev_N.json; это имя не выдаётся за календарную дату. Коллизии разрешаются суффиксами _1, _2 и далее. Проверяются одновременно итоговое имя и .tmp, поэтому незавершённая транзакция после перезапуска не перезаписывается.

Schema v1

Корневые поля: schema, schema_version, snapshot_revision, snapshot_crc32, rtc, storage, units, rooms, sensors и restore_policy. Все 32 комнаты содержат уставку и гистерезис в десятых долях градуса, старт калибровки и время полного открытия в 100 мс, целевое и подтверждённое положение в процентах. Датчик содержит полный 16-символьный HEX ROM: family, шесть serial-байтов и Dallas CRC, а также номер комнаты.

В RoomSettings v1 во Flash фиксируется достигнутый безопасный checkpoint. Поэтому target_position_pct резервной копии равен confirmed_position_pct; ещё не подтверждённая цель Modbus/GUI принципиально не попадает в файл.

Когда создаётся копия

settings_backup_app.c сравнивает номер committed-записи. Только при его изменении он физически перечитывает 512 байт через AppStorage_GetConfirmedSnapshot, где кольцевой журнал повторно проверяет version, длину, commit marker и CRC. На старте та же ревизия ищется во всех месячных каталогах по content CRC; revision остаётся в файле для аудита, но повторный commit тех же настроек не создаёт дубль. Десятиминутный температурный журнал не является trigger backup.

Запись атомарна: уникальный .tmp создаётся с FA_CREATE_NEW, полностью записывается, синхронизируется, закрывается и только затем переименовывается в .json. Старые JSON не удаляются при ошибке open/write/sync/close/rename. Ошибки absent/full/removal переводят автомат в диагностическое состояние и назначают ограниченный retry без задержек и busy wait в main loop.

Retention задаётся SETTINGS_BACKUP_MAXIMUM_COPIES (по умолчанию 24). При превышении лимита сначала удаляется самый старый подтверждённый duplicate hash, затем самый старый уникальный файл; последняя корректная копия не удаляется.

Восстановление

Автоматического восстановления нет. Наличие JSON никогда не вызывает запись в AppStorage. Будущая отдельная команда должна прочитать выбранный файл только для проверки, подтвердить schema/version, UTF-8/JSON, диапазоны 32 комнат, полные ROM и Dallas CRC, content CRC, совместимость backend и получить явное подтверждение оператора. Лишь после этого отдельная реализация может собрать новый AppStorage image и выполнить обычный committed write с обратным чтением.

Перенос на другую платформу

Скопируйте Inc, Src и конфигурацию. Реализуйте callbacks mount, global dedupe scan, collision-safe path resolve, atomic write и retention. Каждая callback-функция должна иметь ограниченный timeout и не выполняться из ISR. FatFs-порт данного проекта находится в Port/FatFs; это единственный модуль библиотеки, который включает ff.h и использует общий том SD logger.

Модельные тесты запускаются так:

python -m unittest discover -s Libraries/SettingsBackup/Tests -p "test_*.py"

Shared source

Canonical source: templates/c/settings-backup. Used by home/climate; its old paths are compatibility includes. Board-specific ports remain in the application. Change this library, not the forwarding files.