diff --git a/src/config.cpp b/src/config.cpp index fc37151..167e616 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,316 +1,316 @@ -/* -MIT License - -Copyright (c) 2021 Magnus - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#include "config.h" -#include "helper.h" -#include - -Config myConfig; - -// -// Create the config class with default settings. -// -Config::Config() { - // Assiging default values - char buf[30]; - sprintf(&buf[0], "%6x", (unsigned int) ESP.getChipId() ); - id = String( &buf[0] ); - sprintf(&buf[0], "" WIFI_MDNS "%s", getID() ); - mDNS = String( &buf[0] ); - - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - Log.verbose(F("CFG : Created config for %s (%s)." CR), id.c_str(), mDNS.c_str() ); - #endif - - setTempFormat('C'); - setGravityFormat('G'); - setSleepInterval(900); // 15 minutes - setVoltageFactor(1.59); // Conversion factor for battery - setTempSensorAdj(0.0); - setGravityTempAdj(false); - gyroCalibration = { 0, 0, 0, 0, 0 ,0 }; - formulaData = {{ 0, 0, 0, 0, 0},{ 1, 1, 1, 1, 1}}; - saveNeeded = false; -} - -// -// Populate the json document with all configuration parameters (used in both web and saving to file) -// -void Config::createJson(DynamicJsonDocument& doc) { - doc[ CFG_PARAM_MDNS ] = getMDNS(); - doc[ CFG_PARAM_ID ] = getID(); - doc[ CFG_PARAM_OTA ] = getOtaURL(); - doc[ CFG_PARAM_SSID ] = getWifiSSID(); - doc[ CFG_PARAM_PASS ] = getWifiPass(); - doc[ CFG_PARAM_TEMPFORMAT ] = String( getTempFormat() ); - doc[ CFG_PARAM_PUSH_BREWFATHER ] = getBrewfatherPushUrl(); - doc[ CFG_PARAM_PUSH_HTTP ] = getHttpPushUrl(); - doc[ CFG_PARAM_PUSH_HTTP2 ] = getHttpPushUrl2(); - doc[ CFG_PARAM_PUSH_INFLUXDB2 ] = getInfluxDb2PushUrl(); - doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ] = getInfluxDb2PushOrg(); - doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ] = getInfluxDb2PushBucket(); - doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ] = getInfluxDb2PushToken(); - doc[ CFG_PARAM_SLEEP_INTERVAL ] = getSleepInterval(); -// doc[ CFG_PARAM_PUSH_INTERVAL ] = getSleepInterval(); // TODO: @deprecated - doc[ CFG_PARAM_VOLTAGEFACTOR ] = getVoltageFactor(); - doc[ CFG_PARAM_GRAVITY_FORMULA ] = getGravityFormula(); - doc[ CFG_PARAM_GRAVITY_FORMAT ] = String(getGravityFormat()); - doc[ CFG_PARAM_TEMP_ADJ ] = getTempSensorAdj(); - doc[ CFG_PARAM_GRAVITY_TEMP_ADJ ] = isGravityTempAdj(); - - JsonObject cal = doc.createNestedObject( CFG_PARAM_GYRO_CALIBRATION ); - cal["ax"] = gyroCalibration.ax; - cal["ay"] = gyroCalibration.ay; - cal["az"] = gyroCalibration.az; - cal["gx"] = gyroCalibration.gx; - cal["gy"] = gyroCalibration.gy; - cal["gz"] = gyroCalibration.gz; - - JsonObject cal2 = doc.createNestedObject( CFG_PARAM_FORMULA_DATA ); - cal2[ "a1" ] = reduceFloatPrecision( formulaData.a[0], 2); - cal2[ "a2" ] = reduceFloatPrecision( formulaData.a[1], 2); - cal2[ "a3" ] = reduceFloatPrecision( formulaData.a[2], 2); - cal2[ "a4" ] = reduceFloatPrecision( formulaData.a[3], 2); - cal2[ "a5" ] = reduceFloatPrecision( formulaData.a[4], 2); - - cal2[ "g1" ] = reduceFloatPrecision( formulaData.g[0], 4); - cal2[ "g2" ] = reduceFloatPrecision( formulaData.g[1], 4); - cal2[ "g3" ] = reduceFloatPrecision( formulaData.g[2], 4); - cal2[ "g4" ] = reduceFloatPrecision( formulaData.g[3], 4); - cal2[ "g5" ] = reduceFloatPrecision( formulaData.g[4], 4); -} - -// -// Save json document to file -// -bool Config::saveFile() { - if( !saveNeeded ) { - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - Log.verbose(F("CFG : Skipping save, not needed." CR)); - #endif - return true; - } - - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - Log.verbose(F("CFG : Saving configuration to file." CR)); - #endif - - File configFile = LittleFS.open(CFG_FILENAME, "w"); - - if (!configFile) { - Log.error(F("CFG : Failed to open file " CFG_FILENAME " for save." CR)); - return false; - } - - DynamicJsonDocument doc(CFG_JSON_BUFSIZE); - createJson( doc ); - - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - serializeJson(doc, Serial); - Serial.print( CR ); - #endif - - serializeJson(doc, configFile); - configFile.flush(); - configFile.close(); - - saveNeeded = false; - myConfig.debug(); - Log.notice(F("CFG : Configuration saved to " CFG_FILENAME "." CR)); - return true; -} - -// -// Load config file from disk -// -bool Config::loadFile() { - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - Log.verbose(F("CFG : Loading configuration from file." CR)); - #endif - - if (!LittleFS.exists(CFG_FILENAME)) { - Log.error(F("CFG : Configuration file does not exist " CFG_FILENAME "." CR)); - return false; - } - - File configFile = LittleFS.open(CFG_FILENAME, "r"); - - if (!configFile) { - Log.error(F("CFG : Failed to open " CFG_FILENAME "." CR)); - return false; - } - - Log.notice(F("CFG : Size of configuration file=%d bytes." CR), configFile.size() ); - - DynamicJsonDocument doc(CFG_JSON_BUFSIZE); - DeserializationError err = deserializeJson(doc, configFile); -#if LOG_LEVEL==6 - serializeJson(doc, Serial); - Serial.print( CR ); -#endif - configFile.close(); - - if( err ) { - Log.error(F("CFG : Failed to parse " CFG_FILENAME " file, Err: %s, %d." CR), err.c_str(), doc.capacity()); - return false; - } - -#if LOG_LEVEL==6 - Log.verbose(F("CFG : Parsed configuration file." CR)); -#endif - if( !doc[ CFG_PARAM_OTA ].isNull() ) - setOtaURL( doc[ CFG_PARAM_OTA ] ); - if( !doc[ CFG_PARAM_MDNS ].isNull() ) - setMDNS( doc[ CFG_PARAM_MDNS ] ); - if( !doc[ CFG_PARAM_SSID ].isNull() ) - setWifiSSID( doc[ CFG_PARAM_SSID ] ); - if( !doc[ CFG_PARAM_PASS ].isNull() ) - setWifiPass( doc[ CFG_PARAM_PASS ] ); - if( !doc[ CFG_PARAM_TEMPFORMAT ].isNull() ) { - String s = doc[ CFG_PARAM_TEMPFORMAT ]; - setTempFormat( s.charAt(0) ); - } - if( !doc[ CFG_PARAM_PUSH_BREWFATHER ].isNull() ) - setBrewfatherPushUrl( doc[ CFG_PARAM_PUSH_BREWFATHER ] ); - if( !doc[ CFG_PARAM_PUSH_HTTP ].isNull() ) - setHttpPushUrl( doc[ CFG_PARAM_PUSH_HTTP ] ); - if( !doc[ CFG_PARAM_PUSH_HTTP2 ].isNull() ) - setHttpPushUrl2( doc[ CFG_PARAM_PUSH_HTTP2 ] ); - if( !doc[ CFG_PARAM_PUSH_INFLUXDB2 ].isNull() ) - setInfluxDb2PushUrl( doc[ CFG_PARAM_PUSH_INFLUXDB2 ] ); - if( !doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ].isNull() ) - setInfluxDb2PushOrg( doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ] ); - if( !doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ].isNull() ) - setInfluxDb2PushBucket( doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ] ); - if( !doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ].isNull() ) - setInfluxDb2PushToken( doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ] ); - if( !doc[ CFG_PARAM_SLEEP_INTERVAL ].isNull() ) - setSleepInterval( doc[ CFG_PARAM_SLEEP_INTERVAL ].as() ); - if( !doc[ CFG_PARAM_PUSH_INTERVAL ].isNull() ) // TODO: @deprecated - setSleepInterval( doc[ CFG_PARAM_PUSH_INTERVAL ].as() ); // TODO: @deprecated - if( !doc[ CFG_PARAM_VOLTAGEFACTOR ].isNull() ) - setVoltageFactor( doc[ CFG_PARAM_VOLTAGEFACTOR ].as() ); - if( !doc[ CFG_PARAM_GRAVITY_FORMULA ].isNull() ) - setGravityFormula( doc[ CFG_PARAM_GRAVITY_FORMULA ] ); - if( !doc[ CFG_PARAM_GRAVITY_TEMP_ADJ ].isNull() ) - setGravityTempAdj( doc[ CFG_PARAM_GRAVITY_TEMP_ADJ ].as() ); - if( !doc[ CFG_PARAM_GRAVITY_FORMAT ].isNull() ) { - String s = doc[ CFG_PARAM_GRAVITY_FORMAT ]; - setGravityFormat( s.charAt(0) ); - } - if( !doc[ CFG_PARAM_TEMP_ADJ ].isNull() ) - setTempSensorAdj( doc[ CFG_PARAM_TEMP_ADJ ].as() ); - - if( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["ax"].isNull() ) - gyroCalibration.ax = doc[ CFG_PARAM_GYRO_CALIBRATION ]["ax"]; - if( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["ay"].isNull() ) - gyroCalibration.ay = doc[ CFG_PARAM_GYRO_CALIBRATION ]["ay"]; - if( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["az"].isNull() ) - gyroCalibration.az = doc[ CFG_PARAM_GYRO_CALIBRATION ]["az"]; - if( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["gx"].isNull() ) - gyroCalibration.gx = doc[ CFG_PARAM_GYRO_CALIBRATION ]["gx"]; - if( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["gy"].isNull() ) - gyroCalibration.gy = doc[ CFG_PARAM_GYRO_CALIBRATION ]["gy"]; - if( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["gz"].isNull() ) - gyroCalibration.gz = doc[ CFG_PARAM_GYRO_CALIBRATION ]["gz"]; - - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "a1" ].isNull() ) - formulaData.a[0] = doc[ CFG_PARAM_FORMULA_DATA ][ "a1" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "a2" ].isNull() ) - formulaData.a[1] = doc[ CFG_PARAM_FORMULA_DATA ][ "a2" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "a3" ].isNull() ) - formulaData.a[2] = doc[ CFG_PARAM_FORMULA_DATA ][ "a3" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "a4" ].isNull() ) - formulaData.a[3] = doc[ CFG_PARAM_FORMULA_DATA ][ "a4" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "a5" ].isNull() ) - formulaData.a[4] = doc[ CFG_PARAM_FORMULA_DATA ][ "a5" ].as(); - - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "g1" ].isNull() ) - formulaData.g[0] = doc[ CFG_PARAM_FORMULA_DATA ][ "g1" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "g2" ].isNull() ) - formulaData.g[1] = doc[ CFG_PARAM_FORMULA_DATA ][ "g2" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "g3" ].isNull() ) - formulaData.g[2] = doc[ CFG_PARAM_FORMULA_DATA ][ "g3" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "g4" ].isNull() ) - formulaData.g[3] = doc[ CFG_PARAM_FORMULA_DATA ][ "g4" ].as(); - if( !doc[ CFG_PARAM_FORMULA_DATA ][ "g5" ].isNull() ) - formulaData.g[4] = doc[ CFG_PARAM_FORMULA_DATA ][ "g5" ]; - - myConfig.debug(); - saveNeeded = false; // Reset save flag - Log.notice(F("CFG : Configuration file " CFG_FILENAME " loaded." CR)); - return true; -} - -// -// Check if file system can be mounted, if not we format it. -// -void Config::formatFileSystem() { - Log.notice(F("CFG : Formating filesystem." CR)); - LittleFS.format(); -} - -// -// Check if file system can be mounted, if not we format it. -// -void Config::checkFileSystem() { - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - Log.verbose(F("CFG : Checking if filesystem is valid." CR)); - #endif - - if (LittleFS.begin()) { - Log.notice(F("CFG : Filesystem mounted." CR)); - } else { - Log.error(F("CFG : Unable to mount file system, formatting..." CR)); - LittleFS.format(); - } -} - -// -// Dump the configuration to the serial port -// -void Config::debug() { - #if LOG_LEVEL==6 && !defined( CFG_DISABLE_LOGGING ) - Log.verbose(F("CFG : Dumping configration " CFG_FILENAME "." CR)); - Log.verbose(F("CFG : ID; '%s'." CR), getID()); - Log.verbose(F("CFG : WIFI; '%s', '%s'." CR), getWifiSSID(), getWifiPass() ); - Log.verbose(F("CFG : mDNS; '%s'." CR), getMDNS() ); - Log.verbose(F("CFG : Sleep interval; %d." CR), getSleepInterval() ); - Log.verbose(F("CFG : OTA; '%s'." CR), getOtaURL() ); - Log.verbose(F("CFG : Temp Format; %c." CR), getTempFormat() ); - Log.verbose(F("CFG : Temp Adj; %F." CR), getTempSensorAdj() ); - Log.verbose(F("CFG : VoltageFactor; %F." CR), getVoltageFactor() ); - Log.verbose(F("CFG : Gravity formula; '%s'." CR), getGravityFormula() ); - Log.verbose(F("CFG : Gravity format; '%c'." CR), getGravityFormat() ); - Log.verbose(F("CFG : Gravity temp adj; %s." CR), isGravityTempAdj()?"true":"false" ); - Log.verbose(F("CFG : Push brewfather; '%s'." CR), getBrewfatherPushUrl() ); - Log.verbose(F("CFG : Push http; '%s'." CR), getHttpPushUrl() ); - Log.verbose(F("CFG : Push http2; '%s'." CR), getHttpPushUrl2() ); - Log.verbose(F("CFG : InfluxDb2; '%s', '%s', '%s', '%s'." CR), getInfluxDb2PushUrl(), getInfluxDb2PushOrg(), - getInfluxDb2PushBucket(), getInfluxDb2PushToken() ); -// Log.verbose(F("CFG : Accel offset\t%d\t%d\t%d" CR), gyroCalibration.ax, gyroCalibration.ay, gyroCalibration.az ); -// Log.verbose(F("CFG : Gyro offset \t%d\t%d\t%d" CR), gyroCalibration.gx, gyroCalibration.gy, gyroCalibration.gz ); - #endif -} - -// EOF \ No newline at end of file +/* +MIT License + +Copyright (c) 2021 Magnus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ +#include "src/config.h" +#include "src/helper.h" +#include + +Config myConfig; + +// +// Create the config class with default settings. +// +Config::Config() { + // Assiging default values + char buf[30]; + snprintf(&buf[0], sizeof(buf) "%6x", (unsigned int) ESP.getChipId()); + id = String(&buf[0]); + snprintf(&buf[0], sizeof(buf), "" WIFI_MDNS "%s", getID()); + mDNS = String(&buf[0]); + + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + Log.verbose(F("CFG : Created config for %s (%s)." CR), id.c_str(), mDNS.c_str() ); + #endif + + setTempFormat('C'); + setGravityFormat('G'); + setSleepInterval(900); // 15 minutes + setVoltageFactor(1.59); // Conversion factor for battery + setTempSensorAdj(0.0); + setGravityTempAdj(false); + gyroCalibration = { 0 , 0 , 0 , 0 , 0 , 0 }; + formulaData = {{ 0 , 0 , 0 , 0 , 0 } , { 1 , 1 , 1 , 1 , 1 }}; + saveNeeded = false; +} + +// +// Populate the json document with all configuration parameters (used in both web and saving to file) +// +void Config::createJson(DynamicJsonDocument& doc) { + doc[ CFG_PARAM_MDNS ] = getMDNS(); + doc[ CFG_PARAM_ID ] = getID(); + doc[ CFG_PARAM_OTA ] = getOtaURL(); + doc[ CFG_PARAM_SSID ] = getWifiSSID(); + doc[ CFG_PARAM_PASS ] = getWifiPass(); + doc[ CFG_PARAM_TEMPFORMAT ] = String(getTempFormat()); + doc[ CFG_PARAM_PUSH_BREWFATHER ] = getBrewfatherPushUrl(); + doc[ CFG_PARAM_PUSH_HTTP ] = getHttpPushUrl(); + doc[ CFG_PARAM_PUSH_HTTP2 ] = getHttpPushUrl2(); + doc[ CFG_PARAM_PUSH_INFLUXDB2 ] = getInfluxDb2PushUrl(); + doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ] = getInfluxDb2PushOrg(); + doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ] = getInfluxDb2PushBucket(); + doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ] = getInfluxDb2PushToken(); + doc[ CFG_PARAM_SLEEP_INTERVAL ] = getSleepInterval(); +// doc[ CFG_PARAM_PUSH_INTERVAL ] = getSleepInterval(); // TODO: @deprecated + doc[ CFG_PARAM_VOLTAGEFACTOR ] = getVoltageFactor(); + doc[ CFG_PARAM_GRAVITY_FORMULA ] = getGravityFormula(); + doc[ CFG_PARAM_GRAVITY_FORMAT ] = String(getGravityFormat()); + doc[ CFG_PARAM_TEMP_ADJ ] = getTempSensorAdj(); + doc[ CFG_PARAM_GRAVITY_TEMP_ADJ ] = isGravityTempAdj(); + + JsonObject cal = doc.createNestedObject(CFG_PARAM_GYRO_CALIBRATION); + cal["ax"] = gyroCalibration.ax; + cal["ay"] = gyroCalibration.ay; + cal["az"] = gyroCalibration.az; + cal["gx"] = gyroCalibration.gx; + cal["gy"] = gyroCalibration.gy; + cal["gz"] = gyroCalibration.gz; + + JsonObject cal2 = doc.createNestedObject(CFG_PARAM_FORMULA_DATA); + cal2[ "a1" ] = reduceFloatPrecision(formulaData.a[0], 2); + cal2[ "a2" ] = reduceFloatPrecision(formulaData.a[1], 2); + cal2[ "a3" ] = reduceFloatPrecision(formulaData.a[2], 2); + cal2[ "a4" ] = reduceFloatPrecision(formulaData.a[3], 2); + cal2[ "a5" ] = reduceFloatPrecision(formulaData.a[4], 2); + + cal2[ "g1" ] = reduceFloatPrecision(formulaData.g[0], 4); + cal2[ "g2" ] = reduceFloatPrecision(formulaData.g[1], 4); + cal2[ "g3" ] = reduceFloatPrecision(formulaData.g[2], 4); + cal2[ "g4" ] = reduceFloatPrecision(formulaData.g[3], 4); + cal2[ "g5" ] = reduceFloatPrecision(formulaData.g[4], 4); +} + +// +// Save json document to file +// +bool Config::saveFile() { + if ( !saveNeeded ) { + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + Log.verbose(F("CFG : Skipping save, not needed." CR)); + #endif + return true; + } + + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + Log.verbose(F("CFG : Saving configuration to file." CR)); + #endif + + File configFile = LittleFS.open(CFG_FILENAME, "w"); + + if ( !configFile ) { + Log.error(F("CFG : Failed to open file " CFG_FILENAME " for save." CR)); + return false; + } + + DynamicJsonDocument doc(CFG_JSON_BUFSIZE); + createJson(doc); + + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + serializeJson(doc, Serial); + Serial.print(CR); + #endif + + serializeJson(doc, configFile); + configFile.flush(); + configFile.close(); + + saveNeeded = false; + myConfig.debug(); + Log.notice(F("CFG : Configuration saved to " CFG_FILENAME "." CR)); + return true; +} + +// +// Load config file from disk +// +bool Config::loadFile() { + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + Log.verbose(F("CFG : Loading configuration from file." CR)); + #endif + + if ( !LittleFS.exists(CFG_FILENAME) ) { + Log.error(F("CFG : Configuration file does not exist " CFG_FILENAME "." CR)); + return false; + } + + File configFile = LittleFS.open(CFG_FILENAME, "r"); + + if ( !configFile ) { + Log.error(F("CFG : Failed to open " CFG_FILENAME "." CR)); + return false; + } + + Log.notice(F("CFG : Size of configuration file=%d bytes." CR), configFile.size() ); + + DynamicJsonDocument doc(CFG_JSON_BUFSIZE); + DeserializationError err = deserializeJson(doc, configFile); + #if LOG_LEVEL == 6 + serializeJson(doc, Serial); + Serial.print(CR); + #endif + configFile.close(); + + if ( err ) { + Log.error(F("CFG : Failed to parse " CFG_FILENAME " file, Err: %s, %d." CR), err.c_str(), doc.capacity()); + return false; + } + +#if LOG_LEVEL == 6 + Log.verbose(F("CFG : Parsed configuration file." CR)); +#endif + if ( !doc[ CFG_PARAM_OTA ].isNull() ) + setOtaURL(doc[ CFG_PARAM_OTA ]); + if ( !doc[ CFG_PARAM_MDNS ].isNull() ) + setMDNS(doc[ CFG_PARAM_MDNS ] ); + if ( !doc[ CFG_PARAM_SSID ].isNull() ) + setWifiSSID(doc[ CFG_PARAM_SSID ]); + if ( !doc[ CFG_PARAM_PASS ].isNull() ) + setWifiPass(doc[ CFG_PARAM_PASS ]); + if ( !doc[ CFG_PARAM_TEMPFORMAT ].isNull() ) { + String s = doc[ CFG_PARAM_TEMPFORMAT ]; + setTempFormat(s.charAt(0)); + } + if ( !doc[ CFG_PARAM_PUSH_BREWFATHER ].isNull() ) + setBrewfatherPushUrl(doc[ CFG_PARAM_PUSH_BREWFATHER ]); + if ( !doc[ CFG_PARAM_PUSH_HTTP ].isNull() ) + setHttpPushUrl(doc[ CFG_PARAM_PUSH_HTTP ]); + if ( !doc[ CFG_PARAM_PUSH_HTTP2 ].isNull() ) + setHttpPushUrl2(doc[ CFG_PARAM_PUSH_HTTP2 ]); + if ( !doc[ CFG_PARAM_PUSH_INFLUXDB2 ].isNull() ) + setInfluxDb2PushUrl(doc[ CFG_PARAM_PUSH_INFLUXDB2 ]); + if ( !doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ].isNull() ) + setInfluxDb2PushOrg(doc[ CFG_PARAM_PUSH_INFLUXDB2_ORG ]); + if ( !doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ].isNull() ) + setInfluxDb2PushBucket(doc[ CFG_PARAM_PUSH_INFLUXDB2_BUCKET ]); + if ( !doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ].isNull() ) + setInfluxDb2PushToken(doc[ CFG_PARAM_PUSH_INFLUXDB2_AUTH ]); + if ( !doc[ CFG_PARAM_SLEEP_INTERVAL ].isNull() ) + setSleepInterval(doc[ CFG_PARAM_SLEEP_INTERVAL ].as()); + if ( !doc[ CFG_PARAM_PUSH_INTERVAL ].isNull() ) // TODO: @deprecated + setSleepInterval(doc[ CFG_PARAM_PUSH_INTERVAL ].as()); // TODO: @deprecated + if ( !doc[ CFG_PARAM_VOLTAGEFACTOR ].isNull() ) + setVoltageFactor(doc[ CFG_PARAM_VOLTAGEFACTOR ].as()); + if ( !doc[ CFG_PARAM_GRAVITY_FORMULA ].isNull() ) + setGravityFormula(doc[ CFG_PARAM_GRAVITY_FORMULA ]); + if ( !doc[ CFG_PARAM_GRAVITY_TEMP_ADJ ].isNull() ) + setGravityTempAdj(doc[ CFG_PARAM_GRAVITY_TEMP_ADJ ].as()); + if ( !doc[ CFG_PARAM_GRAVITY_FORMAT ].isNull() ) { + String s = doc[ CFG_PARAM_GRAVITY_FORMAT ]; + setGravityFormat(s.charAt(0)); + } + if ( !doc[ CFG_PARAM_TEMP_ADJ ].isNull() ) + setTempSensorAdj(doc[ CFG_PARAM_TEMP_ADJ ].as()); + + if ( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["ax"].isNull() ) + gyroCalibration.ax = doc[ CFG_PARAM_GYRO_CALIBRATION ]["ax"]; + if ( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["ay"].isNull() ) + gyroCalibration.ay = doc[ CFG_PARAM_GYRO_CALIBRATION ]["ay"]; + if ( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["az"].isNull() ) + gyroCalibration.az = doc[ CFG_PARAM_GYRO_CALIBRATION ]["az"]; + if ( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["gx"].isNull() ) + gyroCalibration.gx = doc[ CFG_PARAM_GYRO_CALIBRATION ]["gx"]; + if ( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["gy"].isNull() ) + gyroCalibration.gy = doc[ CFG_PARAM_GYRO_CALIBRATION ]["gy"]; + if ( !doc[ CFG_PARAM_GYRO_CALIBRATION ]["gz"].isNull() ) + gyroCalibration.gz = doc[ CFG_PARAM_GYRO_CALIBRATION ]["gz"]; + + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "a1" ].isNull() ) + formulaData.a[0] = doc[ CFG_PARAM_FORMULA_DATA ][ "a1" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "a2" ].isNull() ) + formulaData.a[1] = doc[ CFG_PARAM_FORMULA_DATA ][ "a2" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "a3" ].isNull() ) + formulaData.a[2] = doc[ CFG_PARAM_FORMULA_DATA ][ "a3" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "a4" ].isNull() ) + formulaData.a[3] = doc[ CFG_PARAM_FORMULA_DATA ][ "a4" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "a5" ].isNull() ) + formulaData.a[4] = doc[ CFG_PARAM_FORMULA_DATA ][ "a5" ].as(); + + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "g1" ].isNull() ) + formulaData.g[0] = doc[ CFG_PARAM_FORMULA_DATA ][ "g1" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "g2" ].isNull() ) + formulaData.g[1] = doc[ CFG_PARAM_FORMULA_DATA ][ "g2" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "g3" ].isNull() ) + formulaData.g[2] = doc[ CFG_PARAM_FORMULA_DATA ][ "g3" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "g4" ].isNull() ) + formulaData.g[3] = doc[ CFG_PARAM_FORMULA_DATA ][ "g4" ].as(); + if ( !doc[ CFG_PARAM_FORMULA_DATA ][ "g5" ].isNull() ) + formulaData.g[4] = doc[ CFG_PARAM_FORMULA_DATA ][ "g5" ]; + + myConfig.debug(); + saveNeeded = false; // Reset save flag + Log.notice(F("CFG : Configuration file " CFG_FILENAME " loaded." CR)); + return true; +} + +// +// Check if file system can be mounted, if not we format it. +// +void Config::formatFileSystem() { + Log.notice(F("CFG : Formating filesystem." CR)); + LittleFS.format(); +} + +// +// Check if file system can be mounted, if not we format it. +// +void Config::checkFileSystem() { + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + Log.verbose(F("CFG : Checking if filesystem is valid." CR)); + #endif + + if ( LittleFS.begin() ) { + Log.notice(F("CFG : Filesystem mounted." CR)); + } else { + Log.error(F("CFG : Unable to mount file system, formatting..." CR)); + LittleFS.format(); + } +} + +// +// Dump the configuration to the serial port +// +void Config::debug() { + #if LOG_LEVEL == 6 && !defined( CFG_DISABLE_LOGGING ) + Log.verbose(F("CFG : Dumping configration " CFG_FILENAME "." CR)); + Log.verbose(F("CFG : ID; '%s'." CR), getID()); + Log.verbose(F("CFG : WIFI; '%s', '%s'." CR), getWifiSSID(), getWifiPass() ); + Log.verbose(F("CFG : mDNS; '%s'." CR), getMDNS() ); + Log.verbose(F("CFG : Sleep interval; %d." CR), getSleepInterval() ); + Log.verbose(F("CFG : OTA; '%s'." CR), getOtaURL() ); + Log.verbose(F("CFG : Temp Format; %c." CR), getTempFormat() ); + Log.verbose(F("CFG : Temp Adj; %F." CR), getTempSensorAdj() ); + Log.verbose(F("CFG : VoltageFactor; %F." CR), getVoltageFactor() ); + Log.verbose(F("CFG : Gravity formula; '%s'." CR), getGravityFormula() ); + Log.verbose(F("CFG : Gravity format; '%c'." CR), getGravityFormat() ); + Log.verbose(F("CFG : Gravity temp adj; %s." CR), isGravityTempAdj()?"true":"false" ); + Log.verbose(F("CFG : Push brewfather; '%s'." CR), getBrewfatherPushUrl() ); + Log.verbose(F("CFG : Push http; '%s'." CR), getHttpPushUrl() ); + Log.verbose(F("CFG : Push http2; '%s'." CR), getHttpPushUrl2() ); + Log.verbose(F("CFG : InfluxDb2; '%s', '%s', '%s', '%s'." CR), getInfluxDb2PushUrl(), getInfluxDb2PushOrg(), + getInfluxDb2PushBucket(), getInfluxDb2PushToken() ); +// Log.verbose(F("CFG : Accel offset\t%d\t%d\t%d" CR), gyroCalibration.ax, gyroCalibration.ay, gyroCalibration.az ); +// Log.verbose(F("CFG : Gyro offset \t%d\t%d\t%d" CR), gyroCalibration.gx, gyroCalibration.gy, gyroCalibration.gz ); + #endif +} + +// EOF diff --git a/src/config.h b/src/config.h index 0bd35a4..d33d9bb 100644 --- a/src/config.h +++ b/src/config.h @@ -1,230 +1,230 @@ -/* -MIT License - -Copyright (c) 2021 Magnus - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#ifndef _CONFIG_H -#define _CONFIG_H - -// Includes -#include "helper.h" -#include -#include -#include - -// defintions -#define CFG_JSON_BUFSIZE 3192 - -#define CFG_APPNAME "GravityMon " // Name of firmware -#define CFG_FILENAME "/gravitymon.json" // Name of config file - -#define WIFI_DEFAULT_SSID "GravityMon" // Name of created SSID -#define WIFI_DEFAULT_PWD "password" // Password for created SSID -#define WIFI_MDNS "gravitymon" // Prefix for MDNS name -#define WIFI_PORTAL_TIMEOUT 120 // Number of seconds until the config portal is closed - -// These are used in API + Savefile -#define CFG_PARAM_ID "id" -#define CFG_PARAM_MDNS "mdns" // Device name -#define CFG_PARAM_OTA "ota-url" // Base URL for OTA -#define CFG_PARAM_SSID "wifi-ssid" // WIFI -#define CFG_PARAM_PASS "wifi-pass" // WIFI - -#define CFG_PARAM_PUSH_BREWFATHER "brewfather-push" // URL (brewfather format) -#define CFG_PARAM_PUSH_HTTP "http-push" // URL (iSpindle format) -#define CFG_PARAM_PUSH_HTTP2 "http-push2" // URL (iSpindle format) -#define CFG_PARAM_PUSH_INFLUXDB2 "influxdb2-push" // URL -#define CFG_PARAM_PUSH_INFLUXDB2_ORG "influxdb2-org" // URL -#define CFG_PARAM_PUSH_INFLUXDB2_BUCKET "influxdb2-bucket" // URL -#define CFG_PARAM_PUSH_INFLUXDB2_AUTH "influxdb2-auth" // URL -#define CFG_PARAM_SLEEP_INTERVAL "sleep-interval" // Sleep interval -// TODO: @deprecated setting -#define CFG_PARAM_PUSH_INTERVAL "push-interval" // Time between push -#define CFG_PARAM_TEMPFORMAT "temp-format" // C or F -#define CFG_PARAM_VOLTAGEFACTOR "voltage-factor" // Factor to calculate the battery voltage -#define CFG_PARAM_GRAVITY_FORMULA "gravity-formula" // Formula for calculating gravity -#define CFG_PARAM_GRAVITY_FORMAT "gravity-format" // Gravity format G or P -#define CFG_PARAM_GRAVITY_TEMP_ADJ "gravity-temp-adjustment" // True/False. Adjust gravity for temperature -#define CFG_PARAM_TEMP_ADJ "temp-adjustment-value" // Correction value for temp sensor -#define CFG_PARAM_GYRO_CALIBRATION "gyro-calibration-data" // READ ONLY - -#define CFG_PARAM_FORMULA_DATA "formula-calculation-data" // Raw data for the formula calculation - -// These are used in API's -#define CFG_PARAM_APP_NAME "app-name" -#define CFG_PARAM_APP_VER "app-ver" -#define CFG_PARAM_ANGLE "angle" -#define CFG_PARAM_GRAVITY "gravity" -#define CFG_PARAM_TEMP_C "temp-c" -#define CFG_PARAM_TEMP_F "temp-f" -#define CFG_PARAM_BATTERY "battery" -#define CFG_PARAM_SLEEP_MODE "sleep-mode" -#define CFG_PARAM_RSSI "rssi" - -// Used for holding sensordata or sensoroffsets -struct RawGyroData { - int16_t ax; // Raw Acceleration - int16_t ay; - int16_t az; - - int16_t gx; // Raw Position - int16_t gy; - int16_t gz; - - int16_t temp; // Only for information (temperature of chip) -}; - -// Used for holding formulaData (used for calculating formula on device) -struct RawFormulaData { - double a[5]; - double g[5]; -}; - -// Main configuration class -class Config { - private: - bool saveNeeded; - - // Device configuration - String id; - String mDNS; - String otaURL; - char tempFormat; // C, F - float voltageFactor; - float tempSensorAdj; // This value will be added to the read sensor value - int sleepInterval; - - // Wifi Config - String wifiSSID; - String wifiPASS; - - // Push target settings - String brewfatherPushUrl; // URL For brewfather - - String httpPushUrl; // URL 1 for standard http - String httpPushUrl2; // URL 2 for standard http - - String influxDb2Url; // URL for InfluxDB v2 - String influxDb2Org; // Organisation for InfluxDB v2 - String influxDb2Bucket; // Bucket for InfluxDB v2 - String influxDb2Token; // Auth Token for InfluxDB v2 - - // Gravity and temperature calculations - String gravityFormula; - bool gravityTempAdj; // true, false - char gravityFormat; // G, P - - // Gyro calibration data - RawGyroData gyroCalibration; // Holds the gyro calibration constants (6 * int16_t) - RawFormulaData formulaData; // Used for creating formula - - void debug(); - void formatFileSystem(); - - public: - Config(); - const char* getID() { return id.c_str(); }; - - const char* getMDNS() { return mDNS.c_str(); } - void setMDNS( String s ) { mDNS = s; saveNeeded = true; } - - const char* getOtaURL() { return otaURL.c_str(); } - void setOtaURL( String s ) { otaURL = s; saveNeeded = true; } - bool isOtaActive() { return otaURL.length()?true:false; } - - const char* getWifiSSID() { return wifiSSID.c_str(); } - void setWifiSSID( String s ) { wifiSSID = s; saveNeeded = true; } - const char* getWifiPass() { return wifiPASS.c_str(); } - void setWifiPass( String s ) { wifiPASS = s; saveNeeded = true; } - - // Brewfather - const char* getBrewfatherPushUrl() { return brewfatherPushUrl.c_str(); } - void setBrewfatherPushUrl( String s ) { brewfatherPushUrl = s; saveNeeded = true; } - bool isBrewfatherActive() { return brewfatherPushUrl.length()?true:false; } - - // Standard HTTP - const char* getHttpPushUrl() { return httpPushUrl.c_str(); } - void setHttpPushUrl( String s ) { httpPushUrl = s; saveNeeded = true; } - bool isHttpActive() { return httpPushUrl.length()?true:false; } - const char* getHttpPushUrl2() { return httpPushUrl2.c_str(); } - void setHttpPushUrl2( String s ) { httpPushUrl2 = s; saveNeeded = true; } - bool isHttpActive2() { return httpPushUrl2.length()?true:false; } - - // InfluxDB2 - const char* getInfluxDb2PushUrl() { return influxDb2Url.c_str(); } - void setInfluxDb2PushUrl( String s ) { influxDb2Url = s; saveNeeded = true; } - bool isInfluxDb2Active() { return influxDb2Url.length()?true:false; } - const char* getInfluxDb2PushOrg() { return influxDb2Org.c_str(); } - void setInfluxDb2PushOrg( String s ) { influxDb2Org = s; saveNeeded = true; } - const char* getInfluxDb2PushBucket() { return influxDb2Bucket.c_str(); } - void setInfluxDb2PushBucket( String s ) { influxDb2Bucket = s; saveNeeded = true; } - const char* getInfluxDb2PushToken() { return influxDb2Token.c_str(); } - void setInfluxDb2PushToken( String s ) { influxDb2Token = s; saveNeeded = true; } - - int getSleepInterval() { return sleepInterval; } - void setSleepInterval( int v ) { sleepInterval = v; saveNeeded = true; } - void setSleepInterval( String s ) { sleepInterval = s.toInt(); saveNeeded = true; } - - char getTempFormat() { return tempFormat; } - void setTempFormat( char c ) { tempFormat = c; saveNeeded = true; } - bool isTempC() { return tempFormat=='C'?false:true; }; - bool isTempF() { return tempFormat=='F'?false:true; }; - - float getVoltageFactor() { return voltageFactor; } - void setVoltageFactor( float f ) { voltageFactor = f; saveNeeded = true; } - void setVoltageFactor( String s ) { voltageFactor = s.toFloat(); saveNeeded = true; } - - float getTempSensorAdj() { return tempSensorAdj; } - void setTempSensorAdj( float f ) { tempSensorAdj = f; saveNeeded = true; } - void setTempSensorAdj( String s ) { tempSensorAdj = s.toFloat(); saveNeeded = true; } - - const char* getGravityFormula() { return gravityFormula.c_str(); } - void setGravityFormula( String s ) { gravityFormula = s; saveNeeded = true; } - - bool isGravityTempAdj() { return gravityTempAdj; } - void setGravityTempAdj( bool b ) { gravityTempAdj = b; saveNeeded = true; } - - char getGravityFormat() { return gravityFormat; } - void setGravityFormat( char c ) { gravityFormat = c; saveNeeded = true; } - bool isGravitySG() { return gravityFormat=='G'?false:true; }; - bool isGravityPlato() { return gravityFormat=='P'?false:true; }; - - const RawGyroData& getGyroCalibration() { return gyroCalibration; } - void setGyroCalibration( const RawGyroData &r ) { gyroCalibration = r; saveNeeded = true; } - - const RawFormulaData& getFormulaData() { return formulaData; } - void setFormulaData( const RawFormulaData &r ) { formulaData = r; saveNeeded = true; } - - // IO functions - void createJson(DynamicJsonDocument& doc); - bool saveFile(); - bool loadFile(); - void checkFileSystem(); - bool isSaveNeeded() { return saveNeeded; }; - void setSaveNeeded() { saveNeeded = true; }; -}; - -// Global instance created -extern Config myConfig; - -#endif // _CONFIG_H - -// EOF \ No newline at end of file +/* +MIT License + +Copyright (c) 2021 Magnus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ +#ifndef SRC_CONFIG_H_ +#define SRC_CONFIG_H_ + +// Includes +#include +#include "src/helper.h" +#include +#include + +// defintions +#define CFG_JSON_BUFSIZE 3192 + +#define CFG_APPNAME "GravityMon " // Name of firmware +#define CFG_FILENAME "/gravitymon.json" // Name of config file + +#define WIFI_DEFAULT_SSID "GravityMon" // Name of created SSID +#define WIFI_DEFAULT_PWD "password" // Password for created SSID +#define WIFI_MDNS "gravitymon" // Prefix for MDNS name +#define WIFI_PORTAL_TIMEOUT 120 // Number of seconds until the config portal is closed + +// These are used in API + Savefile +#define CFG_PARAM_ID "id" +#define CFG_PARAM_MDNS "mdns" // Device name +#define CFG_PARAM_OTA "ota-url" // Base URL for OTA +#define CFG_PARAM_SSID "wifi-ssid" // WIFI +#define CFG_PARAM_PASS "wifi-pass" // WIFI + +#define CFG_PARAM_PUSH_BREWFATHER "brewfather-push" // URL (brewfather format) +#define CFG_PARAM_PUSH_HTTP "http-push" // URL (iSpindle format) +#define CFG_PARAM_PUSH_HTTP2 "http-push2" // URL (iSpindle format) +#define CFG_PARAM_PUSH_INFLUXDB2 "influxdb2-push" // URL +#define CFG_PARAM_PUSH_INFLUXDB2_ORG "influxdb2-org" // URL +#define CFG_PARAM_PUSH_INFLUXDB2_BUCKET "influxdb2-bucket" // URL +#define CFG_PARAM_PUSH_INFLUXDB2_AUTH "influxdb2-auth" // URL +#define CFG_PARAM_SLEEP_INTERVAL "sleep-interval" // Sleep interval +// TODO: @deprecated setting +#define CFG_PARAM_PUSH_INTERVAL "push-interval" // Time between push +#define CFG_PARAM_TEMPFORMAT "temp-format" // C or F +#define CFG_PARAM_VOLTAGEFACTOR "voltage-factor" // Factor to calculate the battery voltage +#define CFG_PARAM_GRAVITY_FORMULA "gravity-formula" // Formula for calculating gravity +#define CFG_PARAM_GRAVITY_FORMAT "gravity-format" // Gravity format G or P +#define CFG_PARAM_GRAVITY_TEMP_ADJ "gravity-temp-adjustment" // True/False. Adjust gravity for temperature +#define CFG_PARAM_TEMP_ADJ "temp-adjustment-value" // Correction value for temp sensor +#define CFG_PARAM_GYRO_CALIBRATION "gyro-calibration-data" // READ ONLY + +#define CFG_PARAM_FORMULA_DATA "formula-calculation-data" // Raw data for the formula calculation + +// These are used in API's +#define CFG_PARAM_APP_NAME "app-name" +#define CFG_PARAM_APP_VER "app-ver" +#define CFG_PARAM_ANGLE "angle" +#define CFG_PARAM_GRAVITY "gravity" +#define CFG_PARAM_TEMP_C "temp-c" +#define CFG_PARAM_TEMP_F "temp-f" +#define CFG_PARAM_BATTERY "battery" +#define CFG_PARAM_SLEEP_MODE "sleep-mode" +#define CFG_PARAM_RSSI "rssi" + +// Used for holding sensordata or sensoroffsets +struct RawGyroData { + int16_t ax; // Raw Acceleration + int16_t ay; + int16_t az; + + int16_t gx; // Raw Position + int16_t gy; + int16_t gz; + + int16_t temp; // Only for information (temperature of chip) +}; + +// Used for holding formulaData (used for calculating formula on device) +struct RawFormulaData { + double a[5]; + double g[5]; +}; + +// Main configuration class +class Config { + private: + bool saveNeeded; + + // Device configuration + String id; + String mDNS; + String otaURL; + char tempFormat; // C, F + float voltageFactor; + float tempSensorAdj; // This value will be added to the read sensor value + int sleepInterval; + + // Wifi Config + String wifiSSID; + String wifiPASS; + + // Push target settings + String brewfatherPushUrl; // URL For brewfather + + String httpPushUrl; // URL 1 for standard http + String httpPushUrl2; // URL 2 for standard http + + String influxDb2Url; // URL for InfluxDB v2 + String influxDb2Org; // Organisation for InfluxDB v2 + String influxDb2Bucket; // Bucket for InfluxDB v2 + String influxDb2Token; // Auth Token for InfluxDB v2 + + // Gravity and temperature calculations + String gravityFormula; + bool gravityTempAdj; // true, false + char gravityFormat; // G, P + + // Gyro calibration data + RawGyroData gyroCalibration; // Holds the gyro calibration constants (6 * int16_t) + RawFormulaData formulaData; // Used for creating formula + + void debug(); + void formatFileSystem(); + + public: + Config(); + const char* getID() { return id.c_str(); } + + const char* getMDNS() { return mDNS.c_str(); } + void setMDNS(String s) { mDNS = s; saveNeeded = true; } + + const char* getOtaURL() { return otaURL.c_str(); } + void setOtaURL(String s) { otaURL = s; saveNeeded = true; } + bool isOtaActive() { return otaURL.length() ? true : false; } + + const char* getWifiSSID() { return wifiSSID.c_str(); } + void setWifiSSID(String s) { wifiSSID = s; saveNeeded = true; } + const char* getWifiPass() { return wifiPASS.c_str(); } + void setWifiPass(String s) { wifiPASS = s; saveNeeded = true; } + + // Brewfather + const char* getBrewfatherPushUrl() { return brewfatherPushUrl.c_str(); } + void setBrewfatherPushUrl(String s) { brewfatherPushUrl = s; saveNeeded = true; } + bool isBrewfatherActive() { return brewfatherPushUrl.length()?true:false; } + + // Standard HTTP + const char* getHttpPushUrl() { return httpPushUrl.c_str(); } + void setHttpPushUrl(String s) { httpPushUrl = s; saveNeeded = true; } + bool isHttpActive() { return httpPushUrl.length()?true:false; } + const char* getHttpPushUrl2() { return httpPushUrl2.c_str(); } + void setHttpPushUrl2(String s) { httpPushUrl2 = s; saveNeeded = true; } + bool isHttpActive2() { return httpPushUrl2.length()?true:false; } + + // InfluxDB2 + const char* getInfluxDb2PushUrl() { return influxDb2Url.c_str(); } + void setInfluxDb2PushUrl(String s) { influxDb2Url = s; saveNeeded = true; } + bool isInfluxDb2Active() { return influxDb2Url.length()?true:false; } + const char* getInfluxDb2PushOrg() { return influxDb2Org.c_str(); } + void setInfluxDb2PushOrg(String s) { influxDb2Org = s; saveNeeded = true; } + const char* getInfluxDb2PushBucket() { return influxDb2Bucket.c_str(); } + void setInfluxDb2PushBucket(String s) { influxDb2Bucket = s; saveNeeded = true; } + const char* getInfluxDb2PushToken() { return influxDb2Token.c_str(); } + void setInfluxDb2PushToken(String s) { influxDb2Token = s; saveNeeded = true; } + + int getSleepInterval() { return sleepInterval; } + void setSleepInterval(int v) { sleepInterval = v; saveNeeded = true; } + void setSleepInterval(String s) { sleepInterval = s.toInt(); saveNeeded = true; } + + char getTempFormat() { return tempFormat; } + void setTempFormat(char c) { tempFormat = c; saveNeeded = true; } + bool isTempC() { return tempFormat == 'C' ? false : true; } + bool isTempF() { return tempFormat == 'F' ? false : true; } + + float getVoltageFactor() { return voltageFactor; } + void setVoltageFactor(float f) { voltageFactor = f; saveNeeded = true; } + void setVoltageFactor(String s) { voltageFactor = s.toFloat(); saveNeeded = true; } + + float getTempSensorAdj() { return tempSensorAdj; } + void setTempSensorAdj(float f) { tempSensorAdj = f; saveNeeded = true; } + void setTempSensorAdj(String s) { tempSensorAdj = s.toFloat(); saveNeeded = true; } + + const char* getGravityFormula() { return gravityFormula.c_str(); } + void setGravityFormula(String s) { gravityFormula = s; saveNeeded = true; } + + bool isGravityTempAdj() { return gravityTempAdj; } + void setGravityTempAdj(bool b) { gravityTempAdj = b; saveNeeded = true; } + + char getGravityFormat() { return gravityFormat; } + void setGravityFormat(char c) { gravityFormat = c; saveNeeded = true; } + bool isGravitySG() { return gravityFormat == 'G' ? false : true; } + bool isGravityPlato() { return gravityFormat == 'P' ? false : true; } + + const RawGyroData& getGyroCalibration() { return gyroCalibration; } + void setGyroCalibration(const RawGyroData &r) { gyroCalibration = r; saveNeeded = true; } + + const RawFormulaData& getFormulaData() { return formulaData; } + void setFormulaData(const RawFormulaData &r) { formulaData = r; saveNeeded = true; } + + // IO functions + void createJson(DynamicJsonDocument& doc); + bool saveFile(); + bool loadFile(); + void checkFileSystem(); + bool isSaveNeeded() { return saveNeeded; } + void setSaveNeeded() { saveNeeded = true; } +}; + +// Global instance created +extern Config myConfig; + +#endif // SRC_CONFIG_H_ + +// EOF