Merge branch 'pr2360' into dev
This commit is contained in:
commit
74e3947cb2
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "PinMapping.h"
|
#include "PinMapping.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#define CONFIG_FILENAME "/config.json"
|
#define CONFIG_FILENAME "/config.json"
|
||||||
#define CONFIG_VERSION 0x00011d00 // 0.1.29 // make sure to clean all after change
|
#define CONFIG_VERSION 0x00011d00 // 0.1.29 // make sure to clean all after change
|
||||||
@ -162,15 +165,32 @@ struct CONFIG_T {
|
|||||||
|
|
||||||
class ConfigurationClass {
|
class ConfigurationClass {
|
||||||
public:
|
public:
|
||||||
void init();
|
void init(Scheduler& scheduler);
|
||||||
bool read();
|
bool read();
|
||||||
bool write();
|
bool write();
|
||||||
void migrate();
|
void migrate();
|
||||||
CONFIG_T& get();
|
CONFIG_T const& get();
|
||||||
|
|
||||||
|
class WriteGuard {
|
||||||
|
public:
|
||||||
|
WriteGuard();
|
||||||
|
CONFIG_T& getConfig();
|
||||||
|
~WriteGuard();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_lock<std::mutex> _lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
WriteGuard getWriteGuard();
|
||||||
|
|
||||||
INVERTER_CONFIG_T* getFreeInverterSlot();
|
INVERTER_CONFIG_T* getFreeInverterSlot();
|
||||||
INVERTER_CONFIG_T* getInverterConfig(const uint64_t serial);
|
INVERTER_CONFIG_T* getInverterConfig(const uint64_t serial);
|
||||||
void deleteInverterById(const uint8_t id);
|
void deleteInverterById(const uint8_t id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
Task _loopTask;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ConfigurationClass Configuration;
|
extern ConfigurationClass Configuration;
|
||||||
|
|||||||
@ -13,8 +13,17 @@
|
|||||||
|
|
||||||
CONFIG_T config;
|
CONFIG_T config;
|
||||||
|
|
||||||
void ConfigurationClass::init()
|
static std::condition_variable sWriterCv;
|
||||||
|
static std::mutex sWriterMutex;
|
||||||
|
static unsigned sWriterCount = 0;
|
||||||
|
|
||||||
|
void ConfigurationClass::init(Scheduler& scheduler)
|
||||||
{
|
{
|
||||||
|
scheduler.addTask(_loopTask);
|
||||||
|
_loopTask.setCallback(std::bind(&ConfigurationClass::loop, this));
|
||||||
|
_loopTask.setIterations(TASK_FOREVER);
|
||||||
|
_loopTask.enable();
|
||||||
|
|
||||||
memset(&config, 0x0, sizeof(config));
|
memset(&config, 0x0, sizeof(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +328,20 @@ bool ConfigurationClass::read()
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
|
// Check for default DTU serial
|
||||||
|
MessageOutput.print("Check for default DTU serial... ");
|
||||||
|
if (config.Dtu.Serial == DTU_SERIAL) {
|
||||||
|
MessageOutput.print("generate serial based on ESP chip id: ");
|
||||||
|
const uint64_t dtuId = Utils::generateDtuSerial();
|
||||||
|
MessageOutput.printf("%0" PRIx32 "%08" PRIx32 "... ",
|
||||||
|
((uint32_t)((dtuId >> 32) & 0xFFFFFFFF)),
|
||||||
|
((uint32_t)(dtuId & 0xFFFFFFFF)));
|
||||||
|
config.Dtu.Serial = dtuId;
|
||||||
|
write();
|
||||||
|
}
|
||||||
|
MessageOutput.println("done");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,11 +430,16 @@ void ConfigurationClass::migrate()
|
|||||||
read();
|
read();
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& ConfigurationClass::get()
|
CONFIG_T const& ConfigurationClass::get()
|
||||||
{
|
{
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigurationClass::WriteGuard ConfigurationClass::getWriteGuard()
|
||||||
|
{
|
||||||
|
return WriteGuard();
|
||||||
|
}
|
||||||
|
|
||||||
INVERTER_CONFIG_T* ConfigurationClass::getFreeInverterSlot()
|
INVERTER_CONFIG_T* ConfigurationClass::getFreeInverterSlot()
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
|
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
|
||||||
@ -456,4 +484,30 @@ void ConfigurationClass::deleteInverterById(const uint8_t id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigurationClass::loop()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(sWriterMutex);
|
||||||
|
if (sWriterCount == 0) { return; }
|
||||||
|
|
||||||
|
sWriterCv.notify_all();
|
||||||
|
sWriterCv.wait(lock, [] { return sWriterCount == 0; });
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG_T& ConfigurationClass::WriteGuard::getConfig()
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationClass::WriteGuard::WriteGuard()
|
||||||
|
: _lock(sWriterMutex)
|
||||||
|
{
|
||||||
|
sWriterCount++;
|
||||||
|
sWriterCv.wait(_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationClass::WriteGuard::~WriteGuard() {
|
||||||
|
sWriterCount--;
|
||||||
|
if (sWriterCount == 0) { sWriterCv.notify_all(); }
|
||||||
|
}
|
||||||
|
|
||||||
ConfigurationClass Configuration;
|
ConfigurationClass Configuration;
|
||||||
|
|||||||
@ -48,7 +48,7 @@ void WebApiClass::reload()
|
|||||||
|
|
||||||
bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
CONFIG_T& config = Configuration.get();
|
auto const& config = Configuration.get();
|
||||||
if (request->authenticate(AUTH_USERNAME, config.Security.Password)) {
|
if (request->authenticate(AUTH_USERNAME, config.Security.Password)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ bool WebApiClass::checkCredentials(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
bool WebApiClass::checkCredentialsReadonly(AsyncWebServerRequest* request)
|
bool WebApiClass::checkCredentialsReadonly(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
CONFIG_T& config = Configuration.get();
|
auto const& config = Configuration.get();
|
||||||
if (config.Security.AllowReadonly) {
|
if (config.Security.AllowReadonly) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -129,8 +129,9 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
{
|
||||||
bool performRestart = root["curPin"]["name"].as<String>() != config.Dev_PinMapping;
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
strlcpy(config.Dev_PinMapping, root["curPin"]["name"].as<String>().c_str(), sizeof(config.Dev_PinMapping));
|
strlcpy(config.Dev_PinMapping, root["curPin"]["name"].as<String>().c_str(), sizeof(config.Dev_PinMapping));
|
||||||
config.Display.Rotation = root["display"]["rotation"].as<uint8_t>();
|
config.Display.Rotation = root["display"]["rotation"].as<uint8_t>();
|
||||||
@ -145,6 +146,10 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
|||||||
config.Led_Single[i].Brightness = root["led"][i]["brightness"].as<uint8_t>();
|
config.Led_Single[i].Brightness = root["led"][i]["brightness"].as<uint8_t>();
|
||||||
config.Led_Single[i].Brightness = min<uint8_t>(100, config.Led_Single[i].Brightness);
|
config.Led_Single[i].Brightness = min<uint8_t>(100, config.Led_Single[i].Brightness);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const& config = Configuration.get();
|
||||||
|
bool performRestart = root["curPin"]["name"].as<String>() != config.Dev_PinMapping;
|
||||||
|
|
||||||
Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
|
Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
|
||||||
Display.setOrientation(config.Display.Rotation);
|
Display.setOrientation(config.Display.Rotation);
|
||||||
|
|||||||
@ -27,7 +27,7 @@ void WebApiDtuClass::init(AsyncWebServer& server, Scheduler& scheduler)
|
|||||||
void WebApiDtuClass::applyDataTaskCb()
|
void WebApiDtuClass::applyDataTaskCb()
|
||||||
{
|
{
|
||||||
// Execute stuff in main thread to avoid busy SPI bus
|
// Execute stuff in main thread to avoid busy SPI bus
|
||||||
CONFIG_T& config = Configuration.get();
|
auto const& config = Configuration.get();
|
||||||
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu.Nrf.PaLevel);
|
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu.Nrf.PaLevel);
|
||||||
Hoymiles.getRadioCmt()->setPALevel(config.Dtu.Cmt.PaLevel);
|
Hoymiles.getRadioCmt()->setPALevel(config.Dtu.Cmt.PaLevel);
|
||||||
Hoymiles.getRadioNrf()->setDtuSerial(config.Dtu.Serial);
|
Hoymiles.getRadioNrf()->setDtuSerial(config.Dtu.Serial);
|
||||||
@ -153,14 +153,16 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
{
|
||||||
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
config.Dtu.Serial = serial;
|
config.Dtu.Serial = serial;
|
||||||
config.Dtu.PollInterval = root["pollinterval"].as<uint32_t>();
|
config.Dtu.PollInterval = root["pollinterval"].as<uint32_t>();
|
||||||
config.Dtu.Nrf.PaLevel = root["nrf_palevel"].as<uint8_t>();
|
config.Dtu.Nrf.PaLevel = root["nrf_palevel"].as<uint8_t>();
|
||||||
config.Dtu.Cmt.PaLevel = root["cmt_palevel"].as<int8_t>();
|
config.Dtu.Cmt.PaLevel = root["cmt_palevel"].as<int8_t>();
|
||||||
config.Dtu.Cmt.Frequency = root["cmt_frequency"].as<uint32_t>();
|
config.Dtu.Cmt.Frequency = root["cmt_frequency"].as<uint32_t>();
|
||||||
config.Dtu.Cmt.CountryMode = root["cmt_country"].as<CountryModeId_t>();
|
config.Dtu.Cmt.CountryMode = root["cmt_country"].as<CountryModeId_t>();
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
|
|||||||
@ -184,9 +184,9 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Interpret the string as a hex value and convert it to uint64_t
|
// Interpret the string as a hex value and convert it to uint64_t
|
||||||
const uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
const uint64_t new_serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||||
|
|
||||||
if (serial == 0) {
|
if (new_serial == 0) {
|
||||||
retMsg["message"] = "Serial must be a number > 0!";
|
retMsg["message"] = "Serial must be a number > 0!";
|
||||||
retMsg["code"] = WebApiError::InverterSerialZero;
|
retMsg["code"] = WebApiError::InverterSerialZero;
|
||||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||||
@ -209,12 +209,15 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
INVERTER_CONFIG_T& inverter = Configuration.get().Inverter[root["id"].as<uint8_t>()];
|
uint64_t old_serial = 0;
|
||||||
|
|
||||||
uint64_t new_serial = serial;
|
{
|
||||||
uint64_t old_serial = inverter.Serial;
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
// Interpret the string as a hex value and convert it to uint64_t
|
INVERTER_CONFIG_T& inverter = config.Inverter[root["id"].as<uint8_t>()];
|
||||||
|
|
||||||
|
old_serial = inverter.Serial;
|
||||||
inverter.Serial = new_serial;
|
inverter.Serial = new_serial;
|
||||||
strncpy(inverter.Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
strncpy(inverter.Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
||||||
|
|
||||||
@ -235,11 +238,13 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
|||||||
strncpy(inverter.channel[arrayCount].Name, channel["name"] | "", sizeof(inverter.channel[arrayCount].Name));
|
strncpy(inverter.channel[arrayCount].Name, channel["name"] | "", sizeof(inverter.channel[arrayCount].Name));
|
||||||
arrayCount++;
|
arrayCount++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg, WebApiError::InverterChanged, "Inverter changed!");
|
WebApi.writeConfig(retMsg, WebApiError::InverterChanged, "Inverter changed!");
|
||||||
|
|
||||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
INVERTER_CONFIG_T const& inverter = Configuration.get().Inverter[root["id"].as<uint8_t>()];
|
||||||
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(old_serial);
|
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(old_serial);
|
||||||
|
|
||||||
if (inv != nullptr && new_serial != old_serial) {
|
if (inv != nullptr && new_serial != old_serial) {
|
||||||
@ -300,7 +305,7 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t inverter_id = root["id"].as<uint8_t>();
|
uint8_t inverter_id = root["id"].as<uint8_t>();
|
||||||
INVERTER_CONFIG_T& inverter = Configuration.get().Inverter[inverter_id];
|
INVERTER_CONFIG_T const& inverter = Configuration.get().Inverter[inverter_id];
|
||||||
|
|
||||||
Hoymiles.removeInverterBySerial(inverter.Serial);
|
Hoymiles.removeInverterBySerial(inverter.Serial);
|
||||||
|
|
||||||
@ -337,14 +342,19 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request)
|
|||||||
// The order array contains list or id in the right order
|
// The order array contains list or id in the right order
|
||||||
JsonArray orderArray = root["order"].as<JsonArray>();
|
JsonArray orderArray = root["order"].as<JsonArray>();
|
||||||
uint8_t order = 0;
|
uint8_t order = 0;
|
||||||
|
{
|
||||||
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
for (JsonVariant id : orderArray) {
|
for (JsonVariant id : orderArray) {
|
||||||
uint8_t inverter_id = id.as<uint8_t>();
|
uint8_t inverter_id = id.as<uint8_t>();
|
||||||
if (inverter_id < INV_MAX_COUNT) {
|
if (inverter_id < INV_MAX_COUNT) {
|
||||||
INVERTER_CONFIG_T& inverter = Configuration.get().Inverter[inverter_id];
|
INVERTER_CONFIG_T& inverter = config.Inverter[inverter_id];
|
||||||
inverter.Order = order;
|
inverter.Order = order;
|
||||||
}
|
}
|
||||||
order++;
|
order++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg, WebApiError::InverterOrdered, "Inverter order saved!");
|
WebApi.writeConfig(retMsg, WebApiError::InverterOrdered, "Inverter order saved!");
|
||||||
|
|
||||||
|
|||||||
@ -271,7 +271,10 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
{
|
||||||
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
config.Mqtt.Enabled = root["mqtt_enabled"].as<bool>();
|
config.Mqtt.Enabled = root["mqtt_enabled"].as<bool>();
|
||||||
config.Mqtt.Retain = root["mqtt_retain"].as<bool>();
|
config.Mqtt.Retain = root["mqtt_retain"].as<bool>();
|
||||||
config.Mqtt.Tls.Enabled = root["mqtt_tls"].as<bool>();
|
config.Mqtt.Tls.Enabled = root["mqtt_tls"].as<bool>();
|
||||||
@ -302,6 +305,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
strlcpy(config.Mqtt.Topic, root["mqtt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Topic));
|
strlcpy(config.Mqtt.Topic, root["mqtt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Topic));
|
||||||
MqttHandleInverter.subscribeTopics();
|
MqttHandleInverter.subscribeTopics();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
|
|||||||
@ -164,7 +164,10 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
{
|
||||||
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
config.WiFi.Ip[0] = ipaddress[0];
|
config.WiFi.Ip[0] = ipaddress[0];
|
||||||
config.WiFi.Ip[1] = ipaddress[1];
|
config.WiFi.Ip[1] = ipaddress[1];
|
||||||
config.WiFi.Ip[2] = ipaddress[2];
|
config.WiFi.Ip[2] = ipaddress[2];
|
||||||
@ -195,6 +198,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request)
|
|||||||
}
|
}
|
||||||
config.WiFi.ApTimeout = root["aptimeout"].as<uint>();
|
config.WiFi.ApTimeout = root["aptimeout"].as<uint>();
|
||||||
config.Mdns.Enabled = root["mdnsenabled"].as<bool>();
|
config.Mdns.Enabled = root["mdnsenabled"].as<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
|
|||||||
@ -135,13 +135,17 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
{
|
||||||
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
strlcpy(config.Ntp.Server, root["ntp_server"].as<String>().c_str(), sizeof(config.Ntp.Server));
|
strlcpy(config.Ntp.Server, root["ntp_server"].as<String>().c_str(), sizeof(config.Ntp.Server));
|
||||||
strlcpy(config.Ntp.Timezone, root["ntp_timezone"].as<String>().c_str(), sizeof(config.Ntp.Timezone));
|
strlcpy(config.Ntp.Timezone, root["ntp_timezone"].as<String>().c_str(), sizeof(config.Ntp.Timezone));
|
||||||
strlcpy(config.Ntp.TimezoneDescr, root["ntp_timezone_descr"].as<String>().c_str(), sizeof(config.Ntp.TimezoneDescr));
|
strlcpy(config.Ntp.TimezoneDescr, root["ntp_timezone_descr"].as<String>().c_str(), sizeof(config.Ntp.TimezoneDescr));
|
||||||
config.Ntp.Latitude = root["latitude"].as<double>();
|
config.Ntp.Latitude = root["latitude"].as<double>();
|
||||||
config.Ntp.Longitude = root["longitude"].as<double>();
|
config.Ntp.Longitude = root["longitude"].as<double>();
|
||||||
config.Ntp.SunsetType = root["sunsettype"].as<uint8_t>();
|
config.Ntp.SunsetType = root["sunsettype"].as<uint8_t>();
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
|
|||||||
@ -64,9 +64,13 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
{
|
||||||
|
auto guard = Configuration.getWriteGuard();
|
||||||
|
auto& config = guard.getConfig();
|
||||||
|
|
||||||
strlcpy(config.Security.Password, root["password"].as<String>().c_str(), sizeof(config.Security.Password));
|
strlcpy(config.Security.Password, root["password"].as<String>().c_str(), sizeof(config.Security.Password));
|
||||||
config.Security.AllowReadonly = root["allow_readonly"].as<bool>();
|
config.Security.AllowReadonly = root["allow_readonly"].as<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|
||||||
|
|||||||
16
src/main.cpp
16
src/main.cpp
@ -65,10 +65,9 @@ void setup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read configuration values
|
// Read configuration values
|
||||||
|
Configuration.init(scheduler);
|
||||||
MessageOutput.print("Reading configuration... ");
|
MessageOutput.print("Reading configuration... ");
|
||||||
if (!Configuration.read()) {
|
if (!Configuration.read()) {
|
||||||
MessageOutput.print("initializing... ");
|
|
||||||
Configuration.init();
|
|
||||||
if (Configuration.write()) {
|
if (Configuration.write()) {
|
||||||
MessageOutput.print("written... ");
|
MessageOutput.print("written... ");
|
||||||
} else {
|
} else {
|
||||||
@ -150,19 +149,6 @@ void setup()
|
|||||||
LedSingle.init(scheduler);
|
LedSingle.init(scheduler);
|
||||||
MessageOutput.println("done");
|
MessageOutput.println("done");
|
||||||
|
|
||||||
// Check for default DTU serial
|
|
||||||
MessageOutput.print("Check for default DTU serial... ");
|
|
||||||
if (config.Dtu.Serial == DTU_SERIAL) {
|
|
||||||
MessageOutput.print("generate serial based on ESP chip id: ");
|
|
||||||
const uint64_t dtuId = Utils::generateDtuSerial();
|
|
||||||
MessageOutput.printf("%0" PRIx32 "%08" PRIx32 "... ",
|
|
||||||
static_cast<uint32_t>((dtuId >> 32) & 0xFFFFFFFF),
|
|
||||||
static_cast<uint32_t>(dtuId & 0xFFFFFFFF));
|
|
||||||
config.Dtu.Serial = dtuId;
|
|
||||||
Configuration.write();
|
|
||||||
}
|
|
||||||
MessageOutput.println("done");
|
|
||||||
|
|
||||||
InverterSettings.init(scheduler);
|
InverterSettings.init(scheduler);
|
||||||
|
|
||||||
Datastore.init(scheduler);
|
Datastore.init(scheduler);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user