131 lines
3.2 KiB
C++
131 lines
3.2 KiB
C++
#include "hardware_config.hpp"
|
|
#include <pb_encode.h>
|
|
#include <pb_decode.h>
|
|
#include <Arduino.h>
|
|
#include <logger.hpp>
|
|
|
|
HardwareConfigRepo::HardwareConfigRepo() {
|
|
setDefaults();
|
|
}
|
|
|
|
HardwareConfigRepo::~HardwareConfigRepo() {
|
|
// Cleanup if needed
|
|
}
|
|
|
|
void HardwareConfigRepo::setChangeCallback(std::function<void(const hardware_HardwareConfig&)> callback) {
|
|
changeCallback_ = callback;
|
|
}
|
|
|
|
void HardwareConfigRepo::setDefaults() {
|
|
data_.hold_duration_ms = DEFAULT_HOLD_DURATION_MS;
|
|
data_.override = DEFAULT_OVERRIDE;
|
|
data_.relay_pin = DEFAULT_RELAY_PIN;
|
|
data_.sensor_rx_pin = DEFAULT_SENSOR_RX_PIN;
|
|
data_.sensor_tx_pin = DEFAULT_SENSOR_TX_PIN;
|
|
|
|
// Initialize LedConfig to defaults (empty)
|
|
// Nanopb initializes to zero, so ok
|
|
}
|
|
|
|
bool HardwareConfigRepo::fileExists() {
|
|
return LittleFS.exists(filename_);
|
|
}
|
|
|
|
bool HardwareConfigRepo::load() {
|
|
if (!LittleFS.begin()) {
|
|
LOG_ERROR("HardwareConfigRepo: LittleFS mount failed");
|
|
setDefaults();
|
|
return false;
|
|
}
|
|
|
|
if (!fileExists()) {
|
|
// File doesn't exist, use defaults
|
|
setDefaults();
|
|
runCallback();
|
|
return true;
|
|
}
|
|
|
|
File file = LittleFS.open(filename_, "r");
|
|
if (!file) {
|
|
LOG_ERROR("Failed to open hardware config file for reading");
|
|
setDefaults();
|
|
return false;
|
|
}
|
|
|
|
// Read file into buffer
|
|
size_t fileSize = file.size();
|
|
uint8_t buffer[fileSize];
|
|
file.read(buffer, fileSize);
|
|
file.close();
|
|
|
|
// Decode protobuf
|
|
pb_istream_t stream = pb_istream_from_buffer(buffer, fileSize);
|
|
bool status = pb_decode(&stream, hardware_HardwareConfig_fields, &data_);
|
|
|
|
if (!status) {
|
|
LOG_ERROR("Failed to decode hardware config protobuf");
|
|
setDefaults();
|
|
return false;
|
|
}
|
|
|
|
runCallback();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool HardwareConfigRepo::save() {
|
|
if (!LittleFS.begin()) {
|
|
LOG_ERROR("HardwareConfigRepo: LittleFS mount failed");
|
|
return false;
|
|
}
|
|
|
|
// Encode to buffer first to get size
|
|
size_t bufferSize = 0;
|
|
pb_get_encoded_size(&bufferSize, hardware_HardwareConfig_fields, &data_);
|
|
|
|
uint8_t buffer[bufferSize];
|
|
pb_ostream_t stream = pb_ostream_from_buffer(buffer, bufferSize);
|
|
|
|
bool status = pb_encode(&stream, hardware_HardwareConfig_fields, &data_);
|
|
if (!status) {
|
|
LOG_ERROR("Failed to encode hardware config protobuf");
|
|
return false;
|
|
}
|
|
|
|
// Write to file
|
|
File file = LittleFS.open(filename_, "w");
|
|
if (!file) {
|
|
LOG_ERROR("Failed to open hardware config file for writing");
|
|
return false;
|
|
}
|
|
|
|
size_t bytesWritten = file.write(buffer, bufferSize);
|
|
file.close();
|
|
|
|
if (bytesWritten != bufferSize) {
|
|
LOG_ERROR("Failed to write complete hardware config file");
|
|
return false;
|
|
}
|
|
|
|
runCallback();
|
|
|
|
return true;
|
|
}
|
|
|
|
void HardwareConfigRepo::setData(const hardware_HardwareConfig& newData) {
|
|
data_ = newData;
|
|
save(); // Persist immediately
|
|
}
|
|
|
|
void HardwareConfigRepo::resetToDefaults() {
|
|
setDefaults();
|
|
save();
|
|
}
|
|
|
|
void HardwareConfigRepo::runCallback() {
|
|
if (changeCallback_) {
|
|
changeCallback_(data_);
|
|
}
|
|
}
|
|
|
|
HardwareConfigRepo hardwareConfigRepo; |