Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration endpoint for local configuration #86

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
267 changes: 160 additions & 107 deletions examples/ONE/ONE.ino
Expand Up @@ -201,104 +201,11 @@ public:
client.end();
Serial.println("Get server config: " + respContent);

/** Parse JSON */
JSONVar root = JSON.parse(respContent);
if (JSON.typeof(root) == "undefined") {
/** JSON invalid */
return false;
}

/** Get "country" */
bool inF = false;
if (JSON.typeof_(root["country"]) == "string") {
String _country = root["country"];
country = _country;

if (country == "US") {
inF = true;
} else {
inF = false;
}
}

/** Get "pmsStandard" */
bool inUSAQI = false;
if (JSON.typeof_(root["pmStandard"]) == "string") {
String standard = root["pmStandard"];
if (standard == "ugm3") {
inUSAQI = false;
} else {
inUSAQI = true;
}
}

/** Get "co2CalibrationRequested" */
if (JSON.typeof_(root["co2CalibrationRequested"]) == "boolean") {
co2Calib = root["co2CalibrationRequested"];
} else {
co2Calib = false;
}

/** Get "ledBarMode" */
uint8_t ledBarMode = UseLedBarOff;
if (JSON.typeof_(root["ledBarMode"]) == "string") {
String mode = root["ledBarMode"];
ledBarMode = parseLedBarMode(mode);
}

/** Get model */
bool _saveConfig = false;
if (JSON.typeof_(root["model"]) == "string") {
String model = root["model"];
if (model.length()) {
int len = model.length() < sizeof(config.models)
? model.length()
: sizeof(config.models);
if (model != String(config.models)) {
memset(config.models, 0, sizeof(config.models));
memcpy(config.models, model.c_str(), len);
_saveConfig = true;
}
}
}

/** Get "mqttBrokerUrl" */
if (JSON.typeof_(root["mqttBrokerUrl"]) == "string") {
String mqtt = root["mqttBrokerUrl"];
if (mqtt.length()) {
int len = mqtt.length() < sizeof(config.mqttBrokers)
? mqtt.length()
: sizeof(config.mqttBrokers);
if (mqtt != String(config.mqttBrokers)) {
memset(config.mqttBrokers, 0, sizeof(config.mqttBrokers));
memcpy(config.mqttBrokers, mqtt.c_str(), len);
_saveConfig = true;
}
}
}

/** Get 'abcDays' */
if (JSON.typeof_(root["abcDays"]) == "number") {
co2AbcCalib = root["abcDays"];
} else {
co2AbcCalib = -1;
}

/** Get "ledBarTestRequested" */
if (JSON.typeof_(root["ledBarTestRequested"]) == "boolean") {
ledBarTestRequested = root["ledBarTestRequested"];
} else {
ledBarTestRequested = false;
}
bool shouldSaveConfig = parseConfiguration(respContent);

/** Show configuration */
showServerConfig();
if (_saveConfig || (inF != config.inF) || (inUSAQI != config.inUSAQI) ||
(ledBarMode != config.useRGBLedBar)) {
config.inF = inF;
config.inUSAQI = inUSAQI;
config.useRGBLedBar = ledBarMode;

if (shouldSaveConfig) {
saveConfig();
}

Expand Down Expand Up @@ -431,6 +338,126 @@ public:
Serial.printf("S8 calibration period: %d\r\n", co2AbcCalib);
}

/**
* @brief Returns the device configuration as Json
*/
String getDeviceConfigurationJson(void) {
JSONVar root;
root["tempFormat"] = config.inF ? "f" : "c";
root["pmStandard"] = config.inUSAQI ? "usaqi" : "ugm3";
root["ledBarMode"] = getLedBarModeName();
root["model"] = config.models;
root["mqttBrokers"] = config.mqttBrokers;
root["abcDays"] = co2AbcCalib;
root["ledBarTestRequested"] = (bool) ledBarTestRequested;
root["co2CalibrationRequested"] = (bool) co2Calib;
return JSON.stringify(root);
}

/**
* @brief Parses the configuration Json
*
* @return String true if the configuration has been updated
*/
bool parseConfiguration(String jsonConfig) {
/** Parse JSON */
JSONVar root = JSON.parse(jsonConfig);
if (JSON.typeof(root) == "undefined") {
/** JSON invalid */
return false;
}

/** Get "country" */
bool inF = config.inF;
if (JSON.typeof_(root["country"]) == "string") {
String _country = root["country"];
country = _country;

if (country == "US") {
inF = true;
} else {
inF = false;
}
}

/** Get "pmsStandard" */
bool inUSAQI = config.inUSAQI;
if (JSON.typeof_(root["pmStandard"]) == "string") {
String standard = root["pmStandard"];
if (standard == "ugm3") {
inUSAQI = false;
} else {
inUSAQI = true;
}
}

/** Get "co2CalibrationRequested" */
if (JSON.typeof_(root["co2CalibrationRequested"]) == "boolean") {
co2Calib = root["co2CalibrationRequested"];
}

/** Get "ledBarMode" */
uint8_t ledBarMode = config.useRGBLedBar;
if (JSON.typeof_(root["ledBarMode"]) == "string") {
String mode = root["ledBarMode"];
ledBarMode = parseLedBarMode(mode);
}

/** Get model */
bool _saveConfig = false;
if (JSON.typeof_(root["model"]) == "string") {
String model = root["model"];
if (model.length()) {
int len = model.length() < sizeof(config.models)
? model.length()
: sizeof(config.models);
if (model != String(config.models)) {
memset(config.models, 0, sizeof(config.models));
memcpy(config.models, model.c_str(), len);
_saveConfig = true;
}
}
}

/** Get "mqttBrokerUrl" */
if (JSON.typeof_(root["mqttBrokerUrl"]) == "string") {
String mqtt = root["mqttBrokerUrl"];
if (mqtt.length()) {
int len = mqtt.length() < sizeof(config.mqttBrokers)
? mqtt.length()
: sizeof(config.mqttBrokers);
if (mqtt != String(config.mqttBrokers)) {
memset(config.mqttBrokers, 0, sizeof(config.mqttBrokers));
memcpy(config.mqttBrokers, mqtt.c_str(), len);
_saveConfig = true;
}
}
}

/** Get 'abcDays' */
if (JSON.typeof_(root["abcDays"]) == "number") {
co2AbcCalib = root["abcDays"];
}

/** Get "ledBarTestRequested" */
if (JSON.typeof_(root["ledBarTestRequested"]) == "boolean") {
ledBarTestRequested = root["ledBarTestRequested"];
} else {
ledBarTestRequested = false;
}

if (_saveConfig || (inF != config.inF) || (inUSAQI != config.inUSAQI) ||
(ledBarMode != config.useRGBLedBar)) {
config.inF = inF;
config.inUSAQI = inUSAQI;
config.useRGBLedBar = ledBarMode;

_saveConfig = true;
}

return _saveConfig;
}

/**
* @brief Get server config led bar mode
*
Expand Down Expand Up @@ -463,6 +490,18 @@ public:
*/
String getCountry(void) { return country; }

void saveConfig(void) {
config.checksum = 0;
uint8_t *data = (uint8_t *)&config;
for (int i = 0; i < sizeof(config) - 4; i++) {
config.checksum += data[i];
}

EEPROM.writeBytes(0, &config, sizeof(config));
EEPROM.commit();
Serial.println("Save config");
}

private:
bool configFailed; /** Flag indicate get server configuration failed */
bool serverFailed; /** Flag indicate post data to server failed */
Expand Down Expand Up @@ -515,18 +554,6 @@ private:
showServerConfig();
}

void saveConfig(void) {
config.checksum = 0;
uint8_t *data = (uint8_t *)&config;
for (int i = 0; i < sizeof(config) - 4; i++) {
config.checksum += data[i];
}

EEPROM.writeBytes(0, &config, sizeof(config));
EEPROM.commit();
Serial.println("Save config");
}

UseLedBar parseLedBarMode(String mode) {
UseLedBar ledBarMode = UseLedBarOff;
if (mode == "co2") {
Expand Down Expand Up @@ -981,6 +1008,14 @@ void webServerMeasureCurrentGet(void) {
webServer.send(200, "application/json", getServerSyncData(true));
}

void webServerConfigurationGet(void) {
webServer.send(200, "application/json", agServer.getDeviceConfigurationJson());
}

void webServerConfigurationPatch(void) {
webServer.send(200, "application/json", updateDeviceConfigurationJson());
}

/**
* Sends metrics in Prometheus/OpenMetrics format to the currently connected
* webServer client.
Expand Down Expand Up @@ -1139,6 +1174,8 @@ static void webServerInit(void) {
webServer.on("/measures/current", HTTP_GET, webServerMeasureCurrentGet);
// Make it possible to query this device from Prometheus/OpenMetrics.
webServer.on("/metrics", HTTP_GET, webServerMetricsGet);
webServer.on("/configuration", HTTP_GET, webServerConfigurationGet);
webServer.on("/configuration", HTTP_PATCH, webServerConfigurationPatch);
webServer.begin();
MDNS.addService("_airgradient", "_tcp", 80);
MDNS.addServiceTxt("_airgradient", "_tcp", "model", mdnsModelName);
Expand All @@ -1153,6 +1190,22 @@ static void webServerInit(void) {
Serial.printf("Webserver init: %s.local\r\n", host.c_str());
}

static String updateDeviceConfigurationJson(void) {
if (webServer.hasArg("plain") == false) {
return String("Error: No Content");
}

String respContent = webServer.arg("plain");
Serial.printf("Update device configuration requested: %s\r\n", respContent);

bool saveConfigRequested = agServer.parseConfiguration(respContent);
if (saveConfigRequested) {
agServer.saveConfig();
}

return agServer.getDeviceConfigurationJson();
}

static String getServerSyncData(bool localServer) {
JSONVar root;
root["wifi"] = WiFi.RSSI();
Expand Down