mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
NTPSettings::apply() waited up to 5 s in getLocalTime() for a clock that can't be set before the network is up, then returned before it set TZ. Every cold boot was 5 s slower and ran without its time zone. It now calls configTzTime(), which sets the zone and starts SNTP without waiting, and save() goes through apply(). /setgeneral checked ntpServer twice, so a request that changed only the zone was ignored. A restore ignored the result of ShadeConfigFile::restore() and rebooted either way, so a bad file failed with no word to the user. The /restore reply now validates the file and answers 400, which the restore dialog shows, and an incomplete upload gets a 400 instead of no reply. A failed restore changes nothing, so loop() no longer reboots after one. /shades.tmp, a full copy of the backup with its rolling codes, is deleted after every restore and after /updateShadeConfig. The 6 extra bytes in the 2026-10-18 backup: TRANS_REC_SIZE stayed 74 when noiseDetection was added to the 80-byte transceiver record, so every backup since declares it short. It is 80 now. The size check stays a warning so those backups still restore, and the sum moves to expectedFileBytes() with tests. The repeater record length is checked as a warning only, since validate() also runs on shades.cfg at boot. Commands for an unknown shade, tilt or group now log a warning, and a socket that never pinged says so. KNOWN_ISSUES.md is updated, including the real cause of the ~365 ms loop stall (radio_tx busy-waits each frame on loop()'s core). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45 lines
2.1 KiB
C
45 lines
2.1 KiB
C
#ifndef CONFIG_HEADER_H
|
|
#define CONFIG_HEADER_H
|
|
#include <stdint.h>
|
|
|
|
// The header of a shades.cfg file: its version and how many records of each
|
|
// kind follow, and their sizes. Kept free of the file system so it can be
|
|
// unit tested on the PC (pio test -e native).
|
|
struct config_header_t {
|
|
uint8_t version = 1;
|
|
uint8_t repeaterRecords = 0;
|
|
uint8_t repeaterRecordSize = 0;
|
|
uint8_t roomRecords = 0;
|
|
uint16_t roomRecordSize = 0;
|
|
uint16_t shadeRecordSize = 0;
|
|
uint8_t shadeRecords = 0;
|
|
uint16_t groupRecordSize = 0;
|
|
uint8_t groupRecords = 0;
|
|
uint16_t settingsRecordSize = 0;
|
|
uint16_t netRecordSize = 0;
|
|
uint16_t transRecordSize = 0;
|
|
char serverId[10] = ""; // This must match the server id size in the ConfigSettings.
|
|
int8_t length = 0;
|
|
};
|
|
|
|
// The bytes of the shade model's records, which follow the header in this
|
|
// order: rooms, shades, groups. A restore that leaves the shades out skips
|
|
// this many bytes.
|
|
inline uint32_t shadeModelBytes(const config_header_t &header) {
|
|
return static_cast<uint32_t>(header.roomRecords) * header.roomRecordSize
|
|
+ static_cast<uint32_t>(header.shadeRecords) * header.shadeRecordSize
|
|
+ static_cast<uint32_t>(header.groupRecords) * header.groupRecordSize;
|
|
}
|
|
// The file size the header adds up to, counting only the records its version
|
|
// has. Backups written before the transceiver record's size was corrected
|
|
// declare it 6 bytes short, so a mismatch alone doesn't make a file invalid.
|
|
inline uint32_t expectedFileBytes(const config_header_t &header) {
|
|
uint32_t bytes = static_cast<uint32_t>(header.length)
|
|
+ static_cast<uint32_t>(header.shadeRecords) * header.shadeRecordSize;
|
|
if(header.version > 10) bytes += static_cast<uint32_t>(header.groupRecords) * header.groupRecordSize;
|
|
if(header.version >= 19) bytes += static_cast<uint32_t>(header.roomRecords) * header.roomRecordSize;
|
|
if(header.version > 13) bytes += header.settingsRecordSize + header.netRecordSize + header.transRecordSize;
|
|
if(header.version >= 21) bytes += static_cast<uint32_t>(header.repeaterRecords) * header.repeaterRecordSize;
|
|
return bytes;
|
|
}
|
|
#endif
|