diff --git a/bin/d32_pro_tft_firmware.bin b/bin/d32_pro_tft_firmware.bin index 18394fa..309f47a 100644 Binary files a/bin/d32_pro_tft_firmware.bin and b/bin/d32_pro_tft_firmware.bin differ diff --git a/bin/d32_pro_tft_spiffs.bin b/bin/d32_pro_tft_spiffs.bin index b1bd236..535b577 100644 Binary files a/bin/d32_pro_tft_spiffs.bin and b/bin/d32_pro_tft_spiffs.bin differ diff --git a/bin/lcd_ssd1306_firmware.bin b/bin/lcd_ssd1306_firmware.bin index 44757e9..e84d294 100644 Binary files a/bin/lcd_ssd1306_firmware.bin and b/bin/lcd_ssd1306_firmware.bin differ diff --git a/bin/lcd_ssd1306_spiffs.bin b/bin/lcd_ssd1306_spiffs.bin index 87ff65f..c773243 100644 Binary files a/bin/lcd_ssd1306_spiffs.bin and b/bin/lcd_ssd1306_spiffs.bin differ diff --git a/bin/tft_espi_firmware.bin b/bin/tft_espi_firmware.bin index 9be2dca..354d114 100644 Binary files a/bin/tft_espi_firmware.bin and b/bin/tft_espi_firmware.bin differ diff --git a/bin/tft_espi_spiffs.bin b/bin/tft_espi_spiffs.bin index 87ff65f..c773243 100644 Binary files a/bin/tft_espi_spiffs.bin and b/bin/tft_espi_spiffs.bin differ diff --git a/data/settings.js b/data/settings.js index fa848a6..24629f0 100644 --- a/data/settings.js +++ b/data/settings.js @@ -140,14 +140,14 @@ function populateConfig(callback = null) { // Get configuration settings, popula // Google Sheets Tab $('input[name="scriptsURL"]').val(config.scriptsURL); $('input[name="scriptsEmail"]').val(config.scriptsEmail); - $('input[name="sheetName_red"]').val(config.sheetName_red); - $('input[name="sheetName_green"]').val(config.sheetName_green); - $('input[name="sheetName_black"]').val(config.sheetName_black); - $('input[name="sheetName_purple"]').val(config.sheetName_purple); - $('input[name="sheetName_orange"]').val(config.sheetName_orange); - $('input[name="sheetName_blue"]').val(config.sheetName_blue); - $('input[name="sheetName_yellow"]').val(config.sheetName_yellow); - $('input[name="sheetName_pink"]').val(config.sheetName_pink); + $('input[name="sheetName_red"]').val(config.Red.name); + $('input[name="sheetName_green"]').val(config.Green.name); + $('input[name="sheetName_black"]').val(config.Black.name); + $('input[name="sheetName_purple"]').val(config.Purple.name); + $('input[name="sheetName_orange"]').val(config.Orange.name); + $('input[name="sheetName_blue"]').val(config.Blue.name); + $('input[name="sheetName_yellow"]').val(config.Yellow.name); + $('input[name="sheetName_pink"]').val(config.Pink.name); // Brewer's Friend Tab $('input[name="brewersFriendKey"]').val(config.brewersFriendKey); diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index a5a8b1a..2e55689 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -2,6 +2,15 @@ Changelog ######### +v1.0.1 - Feb 16, 2021 - Bugfixes & Configuration Tweaks +------------------------------------------------------- + +- Rewrite code for storing/loading Google Sheets configuration +- Fix issue that can cause Google Sheets posts to periodically fail +- Corrected delay timers for Google Sheets, Brewer's Friend, and BrewFather +- Other behind-the-scenes cleanup + + v1.0.0 - Feb 12, 2021 - UI Overhaul, Scanner Overhaul, and loads more --------------------------------------------------------------------- diff --git a/platformio.ini b/platformio.ini index be43524..2227115 100644 --- a/platformio.ini +++ b/platformio.ini @@ -35,16 +35,17 @@ monitor_rts = 1 ; -D_GLIBCXX_USE_C99 is to fix an issue with the xtensa toolchain that precludes the use of std::to_string ; See: https://github.com/espressif/esp-idf/issues/1445 build_flags = ; Do not use spaces around the "=" here, will give you a builder not found error - -D_GLIBCXX_USE_C99=1 ; See above + ;-D_GLIBCXX_USE_C99=1 ; See above !python tools/git_rev.py ; Pick up git information for version (disabled), branch, and commit (in version.cpp) - -D PIO_SRC_TAG=1.0.0 ; Increment versions shown in about.htm page (from version.cpp) + -D PIO_SRC_TAG=1.0.1 ; Increment versions shown in about.htm page (from version.cpp) ; Async TCP Settings: -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 ; per: https://github.com/me-no-dev/ESPAsyncWebServer/issues/731#issuecomment-628163515 -D CONFIG_ASYNC_TCP_USE_WDT=1 ; BLE Settings: - -D CONFIG_SW_COEXIST_ENABLE=1 -D CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=1 - -D CONFIG_SW_COEXIST_PREFERENCE_BALANCED=1 + ;-D CONFIG_SW_COEXIST_PREFERENCE_BALANCED=1 + -D CONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED=1 ; Disable NimBLE Server + -D CONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED=1 ; Disable NimBLE Broadcaster ; Debug logging -D PRINT_GRAV_UPDATES=0 ; Turn on and off gravity printing to serial log -D CORE_DEBUG_LEVEL=0 ; Set core Arduino log level (5 = high) @@ -54,10 +55,10 @@ build_flags = ; Do not use spaces around the "=" here, -D BAUD=${common.monitor_speed} ; Serial monitor baud setting -D FILESYSTEM=SPIFFS ; Define filesystem in use -D DISABLE_OTA_UPDATES=1 - ;-D DOTELNET=0 ; Allow Telnet serial logging + ;-D DOTELNET=1 ; Allow Telnet serial logging ;-D TELNETPORT=23 -D WEBPORT=80 - ; -D FSEDIT=0 ; Use a filesystem editor + ; -D FSEDIT=1 ; Use a filesystem editor extra_scripts = tools/get_port.py ; Pick up port information based on OS lib_deps = bblanchon/ArduinoJson @ 6.17.2 @@ -69,7 +70,6 @@ lib_deps = 256dpi/MQTT @ 2.4.8 https://github.com/tzapu/WiFiManager.git https://github.com/lbussy/LCBUrl.git#devel - https://github.com/bblanchon/ArduinoStreamUtils.git ; This is used to allow stream processing, can be turned off later. build_type = release ; debug ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -139,13 +139,14 @@ build_flags = -D LOAD_GFXFF=1 -D GFXFF=1 -D TOUCH_CS=1 + ;-D CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=1 ; Use PSRAM for NimBLE lib_deps = ${common.lib_deps} bodmer/TFT_eSPI @ 2.3.59 ; https://github.com/Bodmer/TFT_eSPI.git build_type = ${common.build_type} -[env:tft_espi] ; TTGO +[env:tft_espi] ; TTGO TFT (USB-C) Board ; This is configured for a TTGO T-Display using the tft_espi drivers ; it should work for other tft_espi compatible displays, if you tweak ; the defines appropriately. See the documentation for TFT_eSPI at diff --git a/src/bridge_lcd.cpp b/src/bridge_lcd.cpp index d733056..f2541a3 100644 --- a/src/bridge_lcd.cpp +++ b/src/bridge_lcd.cpp @@ -299,7 +299,7 @@ void bridge_lcd::print_line(const char *left_text, const char *middle_text, cons } void bridge_lcd::check_screen() { - if (! onResetScreen && next_screen_at < millis()) { + if (!onResetScreen && next_screen_at < millis()) { next_screen_at = display_next() * 1000 + millis(); } } @@ -431,15 +431,15 @@ void bridge_lcd::print_tilt_to_line(tiltHydrometer *tilt, uint8_t line) { sprintf(temp, "%s %s", tilt->converted_temp(false).c_str(), tilt->is_celsius() ? "C" : "F"); #ifdef LCD_TFT_ESPI - tft->setTextColor(tilt->text_color()); + tft->setTextColor(tilt_text_colors[tilt->m_color]); #endif // Print line with gutter for the color block for TFT screens - print_line(tilt->color_name().c_str(), temp, gravity, line, true); + print_line(tilt_color_names[tilt->m_color], temp, gravity, line, true); #ifdef LCD_TFT uint16_t fHeight = tft->fontHeight(GFXFF); - if (tilt->text_color() == 0xFFFF) { // White outline, black square + if (tilt_text_colors[tilt->m_color] == 0xFFFF) { // White outline, black square tft->fillRect( // White square 0, fHeight * (line - 1) + 2, @@ -459,7 +459,7 @@ void bridge_lcd::print_tilt_to_line(tiltHydrometer *tilt, uint8_t line) { fHeight * (line - 1) + 2, 15, fHeight - 8, - tilt->text_color()); + tilt_text_colors[tilt->m_color]); } #elif defined(LCD_TFT_ESPI) tft->setTextColor(TFT_WHITE); diff --git a/src/http_server.cpp b/src/http_server.cpp index c0869d5..a1d70b1 100644 --- a/src/http_server.cpp +++ b/src/http_server.cpp @@ -24,7 +24,7 @@ void redirectToCalibration(AsyncWebServerRequest *request) { } void processCalibrationError(AsyncWebServerRequest *request) { - Log.error(F("Error in processCalibration." CR)); + Log.error(F("Error in processCalibration.\r\n")); redirectToCalibration(request); } @@ -40,7 +40,7 @@ bool processTiltBridgeSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Controller settings // @@ -48,13 +48,13 @@ bool processTiltBridgeSettings(AsyncWebServerRequest *request) { // Set hostname LCBUrl url; if (!url.isValidLabel(value)) { - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); failCount++; } else { if (strcmp(config.mdnsID, value) != 0) { hostnamechanged = true; } - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); strlcpy(config.mdnsID, value, 32); } } @@ -62,20 +62,20 @@ bool processTiltBridgeSettings(AsyncWebServerRequest *request) { // Set the timezone offset const int val = atof(value); if ((val <= -12) || (val >= 14)) { - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); failCount++; } else { - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); config.TZoffset = val; } } if (strcmp(name, "tempUnit") == 0) { // Set temp unit if ((strcmp(value, "F") == 1) && (strcmp(value, "F") == 1)) { - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); failCount++; } else { - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); strlcpy(config.tempUnit, value, 2); } } @@ -83,10 +83,10 @@ bool processTiltBridgeSettings(AsyncWebServerRequest *request) { // Set the smoothing factor const int val = atof(value); if ((val < 0) || (val > 99)) { - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); failCount++; } else { - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); config.smoothFactor = val; } } @@ -97,22 +97,22 @@ bool processTiltBridgeSettings(AsyncWebServerRequest *request) { config.invertTFT = true; http_server.lcd_reinit_rqd = true; } - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "false") == 0) { if (config.invertTFT) { config.invertTFT = false; http_server.lcd_reinit_rqd = true; } - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else { - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); failCount++; } } } } if (failCount) { - Log.error(F("Error: Invalid controller configuration." CR)); + Log.error(F("Error: Invalid controller configuration.\r\n")); return false; } else { if (saveConfig()) { @@ -120,11 +120,11 @@ bool processTiltBridgeSettings(AsyncWebServerRequest *request) { // We reset hostname, process hostnamechanged = false; http_server.name_reset_requested = true; - Log.notice(F("POSTed new mDNSid, queued network reset." CR)); + Log.notice(F("POSTed new mDNSid, queued network reset.\r\n")); } return true; } else { - Log.error(F("Error: Unable to save controller configuration data." CR)); + Log.error(F("Error: Unable to save controller configuration data.\r\n")); return false; } } @@ -140,7 +140,7 @@ bool processCalibrationSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Calibration settings // @@ -148,38 +148,38 @@ bool processCalibrationSettings(AsyncWebServerRequest *request) { // Set apply calibration if (strcmp(value, "true") == 0) { config.applyCalibration = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "false") == 0) { config.applyCalibration = false; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if (strcmp(name, "tempCorrect") == 0) { // Set apply temperature correction if (strcmp(value, "true") == 0) { config.tempCorrect = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "false") == 0) { config.tempCorrect = false; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } } } if (failCount) { - Log.error(F("Error: Invalid Local Target configuration." CR)); + Log.error(F("Error: Invalid Local Target configuration.\r\n")); return false; } else { if (saveConfig()) { return true; } else { - Log.error(F("Error: Unable to save Local Target configuration data." CR)); + Log.error(F("Error: Unable to save Local Target configuration data.\r\n")); return false; } } @@ -195,7 +195,7 @@ bool processLocalTargetSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Local target settings // @@ -203,16 +203,16 @@ bool processLocalTargetSettings(AsyncWebServerRequest *request) { // Set target URL String isURL = value; if ((strlen(value) > 3) && (strlen(value) < 255) && isURL.startsWith("http")) { - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); strlcpy(config.localTargetURL, value, 256); // Trigger a send to Fermentrack/BPR in 5 seconds using the updated URL sendNowTicker.once(5, [](){send_localTarget = true;}); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); strlcpy(config.localTargetURL, value, 256); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if (strcmp(name, "localTargetPushEvery") == 0) { @@ -220,22 +220,22 @@ bool processLocalTargetSettings(AsyncWebServerRequest *request) { const double val = atof(value); if ((val < 15) || (val > 3600)) { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } else { - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); config.localTargetPushEvery = val; } } } } if (failCount) { - Log.error(F("Error: Invalid Local Target configuration." CR)); + Log.error(F("Error: Invalid Local Target configuration.\r\n")); return false; } else { if (saveConfig()) { return true; } else { - Log.error(F("Error: Unable to save Local Target configuration data." CR)); + Log.error(F("Error: Unable to save Local Target configuration data.\r\n")); return false; } } @@ -251,7 +251,7 @@ bool processGoogleSheetsSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Google Sheets settings // @@ -259,67 +259,71 @@ bool processGoogleSheetsSettings(AsyncWebServerRequest *request) { // Set Google Sheets URL if (strlen(value) > 3 && strlen(value) < 255 && strncmp(value, "https://script.google.com/", 26) == 0) { strlcpy(config.scriptsURL, value, 256); - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); // Trigger a send in 5 seconds using the updated GSheets URL sendNowTicker.once(5, [](){send_gSheets = true;}); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.scriptsURL, value, 256); - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if (strcmp(name, "scriptsEmail") == 0) { // Set Google Sheets Email if (strlen(value) > 7 && strlen(value) < 255) { strlcpy(config.scriptsEmail, value, 256); - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.scriptsEmail, value, 256); - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if(strstr(name, "sheetName_") != NULL) { // Set sheet name if (strlen(value) < 25) { + int to_color = TILT_COLORS; // Basically, we're switching on color here and writing to the appropriate config variable - if(strstr(name, "_red") != NULL) strlcpy(config.sheetName_red, value, 25); - else if(strstr(name, "_green") != NULL) strlcpy(config.sheetName_green, value, 25); - else if(strstr(name, "_black") != NULL) strlcpy(config.sheetName_black, value, 25); - else if(strstr(name, "_purple") != NULL) strlcpy(config.sheetName_purple, value, 25); - else if(strstr(name, "_orange") != NULL) strlcpy(config.sheetName_orange, value, 25); - else if(strstr(name, "_yellow") != NULL) strlcpy(config.sheetName_yellow, value, 25); - else if(strstr(name, "_blue") != NULL) strlcpy(config.sheetName_blue, value, 25); - else if(strstr(name, "_pink") != NULL) strlcpy(config.sheetName_pink, value, 25); - else { + if(strstr(name, "_red") != NULL) to_color = TILT_COLOR_RED; + else if(strstr(name, "_green") != NULL) to_color = TILT_COLOR_GREEN; + else if(strstr(name, "_black") != NULL) to_color = TILT_COLOR_BLACK; + else if(strstr(name, "_purple") != NULL) to_color = TILT_COLOR_PURPLE; + else if(strstr(name, "_orange") != NULL) to_color = TILT_COLOR_ORANGE; + else if(strstr(name, "_yellow") != NULL) to_color = TILT_COLOR_YELLOW; + else if(strstr(name, "_blue") != NULL) to_color = TILT_COLOR_BLUE; + else if(strstr(name, "_pink") != NULL) to_color = TILT_COLOR_PINK; + + if(to_color == TILT_COLORS) { failCount++; - Log.warning(F("Settings update error, invalid color [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, invalid color [%s]:(%s) not valid.\r\n"), name, value); + } else { + strlcpy(config.gsheets_config[to_color].name, value, 25); } // Technically this will appear after a successful application of a color above. This could be // skipped by doing different logical routing/using bools, but that seems more trouble than its // worth - Log.notice(F("Settings updated if color valid [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings updated if color valid [%s]:(%s) applied.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } } } if (failCount) { - Log.error(F("Error: Invalid Google Sheets configuration." CR)); + Log.error(F("Error: Invalid Google Sheets configuration.\r\n")); return false; } else { if (saveConfig()) { return true; } else { - Log.error(F("Error: Unable to save Google Sheets configuration data." CR)); + Log.error(F("Error: Unable to save Google Sheets configuration data.\r\n")); return false; } } @@ -335,7 +339,7 @@ bool processBrewersFriendSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Brewer's Friend settings // @@ -343,27 +347,27 @@ bool processBrewersFriendSettings(AsyncWebServerRequest *request) { // Set Brewer's Friend Key if (BREWERS_FRIEND_MIN_KEY_LENGTH < strlen(value) && strlen(value) < 255) { strlcpy(config.brewersFriendKey, value, 65); - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); // Trigger a send to Brewers Friend in 5 seconds using the updated key sendNowTicker.once(5, [](){send_brewersFriend = true;}); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.brewersFriendKey, value, 65); - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } } } if (failCount) { - Log.error(F("Error: Invalid Brewer's Friend configuration." CR)); + Log.error(F("Error: Invalid Brewer's Friend configuration.\r\n")); return false; } else { if (saveConfig()) { return true; } else { - Log.error(F("Error: Unable to save Brewer's configuration data." CR)); + Log.error(F("Error: Unable to save Brewer's configuration data.\r\n")); return false; } } @@ -380,7 +384,7 @@ bool processBrewfatherSettings(AsyncWebServerRequest *request) // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Brewfather settings // @@ -388,27 +392,27 @@ bool processBrewfatherSettings(AsyncWebServerRequest *request) // Set Brewfather Key if (strlen(value) > BREWERS_FRIEND_MIN_KEY_LENGTH && strlen(value) < 255 ) { strlcpy(config.brewfatherKey, value, 65); - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); // Trigger a send to Brewfather in 5 seconds using the updated key sendNowTicker.once(5, [](){send_brewfather = true;}); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.brewfatherKey, value, 65); - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } } } if (failCount) { - Log.error(F("Error: Invalid Brewfather configuration." CR)); + Log.error(F("Error: Invalid Brewfather configuration.\r\n")); return false; } else { if (saveConfig()) { return true; } else { - Log.error(F("Error: Unable to save Brewfather configuration data." CR)); + Log.error(F("Error: Unable to save Brewfather configuration data.\r\n")); return false; } } @@ -424,7 +428,7 @@ bool processBrewstatusSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // Brewstatus settings // @@ -432,15 +436,15 @@ bool processBrewstatusSettings(AsyncWebServerRequest *request) { // Set Brewstatus Key if (strlen(value) > BREWSTATUS_MIN_KEY_LENGTH && strlen(value) < 255) { strlcpy(config.brewstatusURL, value, 256); - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); // Trigger a send to Brewstatus in 5 seconds using the updated key sendNowTicker.once(5, [](){send_brewStatus = true;}); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.brewstatusURL, value, 256); - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if (strcmp(name, "brewstatusPushEvery") == 0) { @@ -448,22 +452,22 @@ bool processBrewstatusSettings(AsyncWebServerRequest *request) { const double val = atof(value); if ((val < 30) || (val > 3600)) { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } else { - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); config.brewstatusPushEvery = val; } } } } if (failCount) { - Log.error(F("Error: Invalid Brewstatus configuration." CR)); + Log.error(F("Error: Invalid Brewstatus configuration.\r\n")); return false; } else { if (saveConfig()) { return true; } else { - Log.error(F("Error: Unable to save Brewstatus configuration data." CR)); + Log.error(F("Error: Unable to save Brewstatus configuration data.\r\n")); return false; } } @@ -479,7 +483,7 @@ bool processMqttSettings(AsyncWebServerRequest *request) { // Process any p->name().c_str() / p->value().c_str() pairs const char *name = p->name().c_str(); const char *value = p->value().c_str(); - Log.verbose(F("Processing [%s]:(%s) pair." CR), name, value); + Log.verbose(F("Processing [%s]:(%s) pair.\r\n"), name, value); // MQTT settings // @@ -489,14 +493,14 @@ bool processMqttSettings(AsyncWebServerRequest *request) { if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.mqttBrokerHost, value, 256); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else if (!url.isValidHostName(value) || (strlen(value) < 3 || strlen(value) > 254)) { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } else { strlcpy(config.mqttBrokerHost, value, 256); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } } if (strcmp(name, "mqttBrokerPort") == 0) { @@ -504,11 +508,11 @@ bool processMqttSettings(AsyncWebServerRequest *request) { const double val = atof(value); if ((val <= 1024) || (val >= 65535)) { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } else { config.mqttBrokerPort = val; http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } } if (strcmp(name, "mqttPushEvery") == 0) { @@ -516,11 +520,11 @@ bool processMqttSettings(AsyncWebServerRequest *request) { const double val = atof(value); if ((val < 30) || (val > 3600)) { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } else { config.mqttPushEvery = val; http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } } if (strcmp(name, "mqttUsername") == 0) { @@ -528,14 +532,14 @@ bool processMqttSettings(AsyncWebServerRequest *request) { if (strlen(value) > 3 && strlen(value) < 50) { strlcpy(config.mqttUsername, value, 51); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.mqttUsername, value, 51); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if (strcmp(name, "mqttPassword") == 0) { @@ -543,14 +547,14 @@ bool processMqttSettings(AsyncWebServerRequest *request) { if (strlen(value) < 64) { strlcpy(config.mqttPassword, value, 65); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.mqttPassword, value, 65); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } if (strcmp(name, "mqttTopic") == 0) { @@ -558,20 +562,20 @@ bool processMqttSettings(AsyncWebServerRequest *request) { if (strlen(value) > 3 && strlen(value) < 30) { strlcpy(config.mqttTopic, value, 31); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) applied." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) applied.\r\n"), name, value); } else if (strcmp(value, "") == 0 || strlen(value) == 0) { strlcpy(config.mqttTopic, "tiltbridge", 31); http_server.mqtt_init_rqd = true; - Log.notice(F("Settings update, [%s]:(%s) cleared." CR), name, value); + Log.notice(F("Settings update, [%s]:(%s) cleared.\r\n"), name, value); } else { failCount++; - Log.warning(F("Settings update error, [%s]:(%s) not valid." CR), name, value); + Log.warning(F("Settings update error, [%s]:(%s) not valid.\r\n"), name, value); } } } } if (failCount) { - Log.error(F("Error: Invalid MQTT configuration." CR)); + Log.error(F("Error: Invalid MQTT configuration.\r\n")); return false; } else { if (saveConfig()) { @@ -579,7 +583,7 @@ bool processMqttSettings(AsyncWebServerRequest *request) { sendNowTicker.once(5, [](){send_mqtt = true;}); return true; } else { - Log.error(F("Error: Unable to save MQTT configuration data." CR)); + Log.error(F("Error: Unable to save MQTT configuration data.\r\n")); return false; } } @@ -592,19 +596,19 @@ constexpr unsigned int str2int(const char *str, int h = 0) { // we don't need to do much input checking on the calibration data as we are // looking at numbers generated by the javascript and not a human void processCalibration(AsyncWebServerRequest *request) { - int tilt_name = 0; + int tilt_color_no = 0; int degree; double x0, x1, x2, x3; if (request->hasArg("clearTiltColor")) { - tilt_name = str2int(request->arg("clearTiltColor").c_str()); + tilt_color_no = str2int(request->arg("clearTiltColor").c_str()); degree = 1; x1 = 1.0; x0 = x2 = x3 = 0.0; } if (request->hasArg("updateTiltColor")) { - tilt_name = str2int(request->arg("updateTiltColor").c_str()); + tilt_color_no = str2int(request->arg("updateTiltColor").c_str()); if (request->hasArg("linear")) { degree = 1; x0 = strtod(request->arg("linearFitx0").c_str(), nullptr); @@ -627,65 +631,13 @@ void processCalibration(AsyncWebServerRequest *request) { } } - switch (tilt_name) - { - case str2int("red"): - config.cal_red_degree = degree; - config.cal_red_x0 = x0; - config.cal_red_x1 = x1; - config.cal_red_x2 = x2; - config.cal_red_x3 = x3; - break; - case str2int("green"): - config.cal_green_degree = degree; - config.cal_green_x0 = x0; - config.cal_green_x1 = x1; - config.cal_green_x2 = x2; - config.cal_green_x3 = x3; - break; - case str2int("black"): - config.cal_black_degree = degree; - config.cal_black_x0 = x0; - config.cal_black_x1 = x1; - config.cal_black_x2 = x2; - config.cal_black_x3 = x3; - break; - case str2int("purple"): - config.cal_purple_degree = degree; - config.cal_purple_x0 = x0; - config.cal_purple_x1 = x1; - config.cal_purple_x2 = x2; - config.cal_purple_x3 = x3; - break; - case str2int("orange"): - config.cal_orange_degree = degree; - config.cal_orange_x0 = x0; - config.cal_orange_x1 = x1; - config.cal_orange_x2 = x2; - config.cal_orange_x3 = x3; - break; - case str2int("blue"): - config.cal_blue_degree = degree; - config.cal_blue_x0 = x0; - config.cal_blue_x1 = x1; - config.cal_blue_x2 = x2; - config.cal_blue_x3 = x3; - break; - case str2int("yellow"): - config.cal_yellow_degree = degree; - config.cal_yellow_x0 = x0; - config.cal_yellow_x1 = x1; - config.cal_yellow_x2 = x2; - config.cal_yellow_x3 = x3; - break; - case str2int("pink"): - config.cal_pink_degree = degree; - config.cal_pink_x0 = x0; - config.cal_pink_x1 = x1; - config.cal_pink_x2 = x2; - config.cal_pink_x3 = x3; - break; - default: + if(0 <= tilt_color_no && tilt_color_no < TILT_COLORS) { + config.tilt_calibration[tilt_color_no].degree = degree; + config.tilt_calibration[tilt_color_no].x0 = x0; + config.tilt_calibration[tilt_color_no].x1 = x1; + config.tilt_calibration[tilt_color_no].x2 = x2; + config.tilt_calibration[tilt_color_no].x3 = x3; + } else { processCalibrationError(request); } @@ -706,7 +658,7 @@ void trigger_OTA(AsyncWebServerRequest *request) { #endif void http_json(AsyncWebServerRequest *request) { - Log.verbose(F("Serving Tilt JSON." CR)); + Log.verbose(F("Serving Tilt JSON.\r\n")); char tilt_data[TILT_ALL_DATA_SIZE]; tilt_scanner.tilt_to_json_string(tilt_data, false); AsyncWebServerResponse *response = request->beginResponse(200, "application/json", tilt_data); @@ -714,7 +666,7 @@ void http_json(AsyncWebServerRequest *request) { } void settings_json(AsyncWebServerRequest *request) { - Log.verbose(F("Serving settings JSON." CR)); + Log.verbose(F("Serving settings JSON.\r\n")); DynamicJsonDocument doc(capacitySerial); JsonObject root = doc.to(); config.save(root); @@ -729,7 +681,7 @@ void settings_json(AsyncWebServerRequest *request) { // void this_version(AsyncWebServerRequest *request) { - Log.verbose(F("Serving version." CR)); + Log.verbose(F("Serving version.\r\n")); StaticJsonDocument<96> doc; doc["version"] = version(); @@ -743,7 +695,7 @@ void this_version(AsyncWebServerRequest *request) { } void uptime(AsyncWebServerRequest *request) { - Log.verbose(F("Serving uptime." CR)); + Log.verbose(F("Serving uptime.\r\n")); StaticJsonDocument<96> doc; const int days = uptimeDays(); @@ -765,7 +717,7 @@ void uptime(AsyncWebServerRequest *request) { } void heap(AsyncWebServerRequest *request) { - Log.verbose(F("Serving heap information." CR)); + Log.verbose(F("Serving heap information.\r\n")); StaticJsonDocument<48> doc; const uint32_t free = ESP.getFreeHeap(); @@ -783,7 +735,7 @@ void heap(AsyncWebServerRequest *request) { } void reset_reason(AsyncWebServerRequest *request) { - Log.verbose(F("Serving reset reason." CR)); + Log.verbose(F("Serving reset reason.\r\n")); StaticJsonDocument<128> doc; const int reset = (int)esp_reset_reason(); @@ -814,7 +766,7 @@ void setStaticPages() { void setPostPages() { // Settings Page Handlers server.on("/settings/controller/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/controller/." CR)); + Log.verbose(F("Processing post to /settings/controller/.\r\n")); if (processTiltBridgeSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -822,7 +774,7 @@ void setPostPages() { } }); server.on("/settings/calibration/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/calibration/." CR)); + Log.verbose(F("Processing post to /settings/calibration/.\r\n")); if (processCalibrationSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -830,7 +782,7 @@ void setPostPages() { } }); server.on("/settings/localtarget/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/localtarget/." CR)); + Log.verbose(F("Processing post to /settings/localtarget/.\r\n")); if (processLocalTargetSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -838,7 +790,7 @@ void setPostPages() { } }); server.on("/settings/googlesheets/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/googlesheets/." CR)); + Log.verbose(F("Processing post to /settings/googlesheets/.\r\n")); if (processGoogleSheetsSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -846,7 +798,7 @@ void setPostPages() { } }); server.on("/settings/brewersfriend/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/brewersfriend/." CR)); + Log.verbose(F("Processing post to /settings/brewersfriend/.\r\n")); if (processBrewersFriendSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -854,7 +806,7 @@ void setPostPages() { } }); server.on("/settings/brewfather/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/brewfather/." CR)); + Log.verbose(F("Processing post to /settings/brewfather/.\r\n")); if (processBrewfatherSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -862,7 +814,7 @@ void setPostPages() { } }); server.on("/settings/brewstatus/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/brewstatus/." CR)); + Log.verbose(F("Processing post to /settings/brewstatus/.\r\n")); if (processBrewstatusSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -870,7 +822,7 @@ void setPostPages() { } }); server.on("/settings/mqtt/", HTTP_POST, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing post to /settings/mqtt/." CR)); + Log.verbose(F("Processing post to /settings/mqtt/.\r\n")); if (processMqttSettings(request)) { request->send(200, F("text/plain"), F("Ok")); } else { @@ -914,25 +866,25 @@ void setActionPages() { #endif server.on("/resetwifi/", HTTP_GET, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing /resetwifi/." CR)); + Log.verbose(F("Processing /resetwifi/.\r\n")); request->send(200, F("text/plain"), F("Ok.")); http_server.wifi_reset_requested = true; }); server.on("/resetapp/", HTTP_GET, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing /resetapp/." CR)); + Log.verbose(F("Processing /resetapp/.\r\n")); request->send(200, F("text/plain"), F("Ok.")); http_server.factoryreset_requested = true; }); server.on("/oktoreset/", HTTP_GET, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing /oktoreset/." CR)); + Log.verbose(F("Processing /oktoreset/.\r\n")); request->send(200, F("text/plain"), F("Ok.")); http_server.restart_requested = true; }); server.on("/ping/", HTTP_ANY, [](AsyncWebServerRequest *request) { - Log.verbose(F("Processing /ping/." CR)); + Log.verbose(F("Processing /ping/.\r\n")); request->send(200, F("text/plain"), F("Ok.")); }); } @@ -963,7 +915,7 @@ void httpServer::init() { if (request->method() == HTTP_OPTIONS) { request->send(200); } else { - Log.verbose(F("Serving 404 for request to %s." CR), request->url().c_str()); + Log.verbose(F("Serving 404 for request to %s.\r\n"), request->url().c_str()); request->redirect("/404/"); } }); @@ -971,5 +923,5 @@ void httpServer::init() { DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); server.begin(); - Log.notice(F("HTTP server started. Open: http://%s.local/ to view application." CR), WiFi.getHostname()); + Log.notice(F("HTTP server started. Open: http://%s.local/ to view application.\r\n"), WiFi.getHostname()); } diff --git a/src/jsonconfig.cpp b/src/jsonconfig.cpp index e392ba8..9ac6424 100644 --- a/src/jsonconfig.cpp +++ b/src/jsonconfig.cpp @@ -184,59 +184,17 @@ void Config::save(JsonObject obj) const obj["applyCalibration"] = applyCalibration; obj["tempCorrect"] = tempCorrect; - obj["cal_red_degree"] = cal_red_degree; - obj["cal_red_x0"] = cal_red_x0; - obj["cal_red_x1"] = cal_red_x1; - obj["cal_red_x2"] = cal_red_x2; - obj["cal_red_x3"] = cal_red_x3; - obj["cal_black_degree"] = cal_black_degree; - obj["cal_black_x0"] = cal_black_x0; - obj["cal_black_x1"] = cal_black_x1; - obj["cal_black_x2"] = cal_black_x2; - obj["cal_black_x3"] = cal_black_x3; - obj["cal_purple_degree"] = cal_purple_degree; - obj["cal_purple_x0"] = cal_purple_x0; - obj["cal_purple_x1"] = cal_purple_x1; - obj["cal_purple_x2"] = cal_purple_x2; - obj["cal_purple_x3"] = cal_purple_x3; - obj["cal_orange_degree"] = cal_orange_degree; - obj["cal_orange_x0"] = cal_orange_x0; - obj["cal_orange_x1"] = cal_orange_x1; - obj["cal_orange_x2"] = cal_orange_x2; - obj["cal_orange_x3"] = cal_orange_x3; - obj["cal_blue_degree"] = cal_blue_degree; - obj["cal_blue_x0"] = cal_blue_x0; - obj["cal_blue_x1"] = cal_blue_x1; - obj["cal_blue_x2"] = cal_blue_x2; - obj["cal_blue_x3"] = cal_blue_x3; - obj["cal_yellow_degree"] = cal_yellow_degree; - obj["cal_yellow_x0"] = cal_yellow_x0; - obj["cal_yellow_x1"] = cal_yellow_x1; - obj["cal_yellow_x2"] = cal_yellow_x2; - obj["cal_yellow_x3"] = cal_yellow_x3; - obj["cal_pink_degree"] = cal_pink_degree; - obj["cal_pink_x0"] = cal_pink_x0; - obj["cal_pink_x1"] = cal_pink_x1; - obj["cal_pink_x2"] = cal_pink_x2; - obj["cal_pink_x3"] = cal_pink_x3; - - obj["sheetName_red"] = sheetName_red; - obj["sheetName_green"] = sheetName_green; - obj["sheetName_black"] = sheetName_black; - obj["sheetName_purple"] = sheetName_purple; - obj["sheetName_orange"] = sheetName_orange; - obj["sheetName_blue"] = sheetName_blue; - obj["sheetName_yellow"] = sheetName_yellow; - obj["sheetName_pink"] = sheetName_pink; - - obj["link_red"] = link_red; - obj["link_green"] = link_green; - obj["link_black"] = link_black; - obj["link_purple"] = link_purple; - obj["link_orange"] = link_orange; - obj["link_blue"] = link_blue; - obj["link_yellow"] = link_yellow; - obj["link_pink"] = link_pink; + + for(int x=0;x #if FILESYSTEM == SPIFFS @@ -11,88 +12,46 @@ #define JSON_CONFIG_FILE "/tiltbridgeConfig.json" -struct Config { - char *mdnsID = (char *)malloc(sizeof(char) * 32); - bool invertTFT; - bool update_spiffs; - int8_t TZoffset; - char *tempUnit = (char *)malloc(sizeof(char) * 2); - uint8_t smoothFactor; - bool applyCalibration; - bool tempCorrect; - uint8_t cal_red_degree; - double cal_red_x0; - double cal_red_x1; - double cal_red_x2; - double cal_red_x3; - uint8_t cal_green_degree; - double cal_green_x0; - double cal_green_x1; - double cal_green_x2; - double cal_green_x3; - uint8_t cal_black_degree; - double cal_black_x0; - double cal_black_x1; - double cal_black_x2; - double cal_black_x3; - uint8_t cal_purple_degree; - double cal_purple_x0; - double cal_purple_x1; - double cal_purple_x2; - double cal_purple_x3; - uint8_t cal_orange_degree; - double cal_orange_x0; - double cal_orange_x1; - double cal_orange_x2; - double cal_orange_x3; - uint8_t cal_blue_degree; - double cal_blue_x0; - double cal_blue_x1; - double cal_blue_x2; - double cal_blue_x3; - uint8_t cal_yellow_degree; - double cal_yellow_x0; - double cal_yellow_x1; - double cal_yellow_x2; - double cal_yellow_x3; - uint8_t cal_pink_degree; - double cal_pink_x0; - double cal_pink_x1; - double cal_pink_x2; - double cal_pink_x3; +struct TiltCalData { + uint8_t degree = 1; + double x0 = 0.0; + double x1 = 1.0; + double x2 = 0.0; + double x3 = 0.0; +}; - char *sheetName_red = (char *)malloc(sizeof(char) * 25); - char *sheetName_green = (char *)malloc(sizeof(char) * 25); - char *sheetName_black = (char *)malloc(sizeof(char) * 25); - char *sheetName_purple = (char *)malloc(sizeof(char) * 25); - char *sheetName_orange = (char *)malloc(sizeof(char) * 25); - char *sheetName_blue = (char *)malloc(sizeof(char) * 25); - char *sheetName_yellow = (char *)malloc(sizeof(char) * 25); - char *sheetName_pink = (char *)malloc(sizeof(char) * 25); +struct GsheetsConfig { + char name[26] = ""; + char link[256] = ""; +}; + +struct Config { + char mdnsID[32] = "tiltbridge"; + bool invertTFT = false; + bool update_spiffs = false; + int8_t TZoffset = -5; + char tempUnit[2] = "F"; + uint8_t smoothFactor = 60; + bool applyCalibration = false; + bool tempCorrect = false; - char *link_red = (char *)malloc(sizeof(char) * 255); - char *link_green = (char *)malloc(sizeof(char) * 255); - char *link_black = (char *)malloc(sizeof(char) * 255); - char *link_purple = (char *)malloc(sizeof(char) * 255); - char *link_orange = (char *)malloc(sizeof(char) * 255); - char *link_blue = (char *)malloc(sizeof(char) * 255); - char *link_yellow = (char *)malloc(sizeof(char) * 255); - char *link_pink = (char *)malloc(sizeof(char) * 255); + TiltCalData tilt_calibration[TILT_COLORS]; + GsheetsConfig gsheets_config[TILT_COLORS]; - char *localTargetURL = (char *)malloc(sizeof(char) * 256); - uint16_t localTargetPushEvery; - char *brewstatusURL = (char *)malloc(sizeof(char) * 256); - uint16_t brewstatusPushEvery; - char *scriptsURL = (char *)malloc(sizeof(char) * 256); - char *scriptsEmail = (char *)malloc(sizeof(char) * 256); - char *brewersFriendKey = (char *)malloc(sizeof(char) * 65); - char *brewfatherKey = (char *)malloc(sizeof(char) * 65); - char *mqttBrokerHost = (char *)malloc(sizeof(char) * 256); - uint16_t mqttBrokerPort; - char *mqttUsername = (char *)malloc(sizeof(char) * 51); - char *mqttPassword = (char *)malloc(sizeof(char) * 65); - char *mqttTopic = (char *)malloc(sizeof(char) * 31); - uint16_t mqttPushEvery; + char localTargetURL[256] = ""; + uint16_t localTargetPushEvery = 30; + char brewstatusURL[256] = ""; + uint16_t brewstatusPushEvery = 30; + char scriptsURL[256] = ""; + char scriptsEmail[256] = ""; + char brewersFriendKey[65] = ""; + char brewfatherKey[65] = ""; + char mqttBrokerHost[256] = ""; + uint16_t mqttBrokerPort = 1883; + char mqttUsername[51] = ""; + char mqttPassword[65] = ""; + char mqttTopic[31] = ""; + uint16_t mqttPushEvery = 30; void load(JsonObjectConst); void save(JsonObject) const; diff --git a/src/main.cpp b/src/main.cpp index cf06102..df35304 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,22 +13,22 @@ void printMem() { const uint32_t free = ESP.getFreeHeap(); const uint32_t max = ESP.getMaxAllocHeap(); const uint8_t frag = 100 - (max * 100) / free; - Log.verbose(F("Free Heap: %d, Max Allocated: %d, Frag: %d" CR), free, max, frag); + Log.verbose(F("Free Heap: %d, Largest contiguous block: %d, Frag: %d%%\r\n"), free, max, frag); } void setup() { serial(); - Log.verbose(F("Loading config." CR)); + Log.verbose(F("Loading config.\r\n")); loadConfig(); - Log.verbose(F("Initializing LCD." CR)); + Log.verbose(F("Initializing LCD.\r\n")); lcd.init(); - Log.verbose(F("Initializing WiFi." CR)); + Log.verbose(F("Initializing WiFi.\r\n")); initWiFi(); -#ifdef LOG_LOCAL_LEVEL +#if defined(LOG_LOCAL_LEVEL) && !defined(DISABLE_LOGGING) esp_log_level_set("*", ESP_LOG_WARN); esp_log_level_set("FreeRTOS", ESP_LOG_WARN); @@ -58,7 +58,7 @@ void setup() { esp_log_level_set("dhcpc", ESP_LOG_WARN); #endif - Log.verbose(F("Initializing scanner." CR)); + Log.verbose(F("Initializing scanner.\r\n")); tilt_scanner.init(); // Initialize the BLE scanner tilt_scanner.wait_until_scan_complete(); // Wait until the initial scan completes @@ -67,7 +67,7 @@ void setup() { initButtons(); // Initialize buttons // Start independent timers -#if (ARDUINO_LOG_LEVEL >= 5) +#if (ARDUINO_LOG_LEVEL >= 5) && !defined(DISABLE_LOGGING) memCheck.attach(30, printMem); // Memory debug print on timer #endif } @@ -93,7 +93,7 @@ void loop() { // Check semaphores if (doBoardReset || http_server.restart_requested) { - Log.verbose(F("Resetting controller." CR)); + Log.verbose(F("Resetting controller.\r\n")); http_server.restart_requested = false; tilt_scanner.wait_until_scan_complete(); // Wait for scans to complete delay(1000); @@ -101,7 +101,7 @@ void loop() { } if (doWiFiReset || http_server.wifi_reset_requested) { - Log.verbose(F("Resetting WiFi configuration." CR)); + Log.verbose(F("Resetting WiFi configuration.\r\n")); http_server.wifi_reset_requested = false; tilt_scanner.wait_until_scan_complete(); // Wait for scans to complete delay(1000); @@ -110,13 +110,13 @@ void loop() { } if (http_server.name_reset_requested) { - Log.verbose(F("Resetting host name." CR)); + Log.verbose(F("Resetting host name.\r\n")); http_server.name_reset_requested = false; mdnsReset(); } if (http_server.factoryreset_requested) { - Log.verbose(F("Resetting to original settings." CR)); + Log.verbose(F("Resetting to original settings.\r\n")); http_server.factoryreset_requested = false; tilt_scanner.wait_until_scan_complete(); // Wait for scans to complete deleteConfigFile(); // Delete the config file in SPIFFS @@ -124,13 +124,13 @@ void loop() { } if (http_server.mqtt_init_rqd) { - Log.verbose(F("Re-initializing MQTT." CR)); + Log.verbose(F("Re-initializing MQTT.\r\n")); http_server.mqtt_init_rqd = false; data_sender.init_mqtt(); } if (http_server.lcd_reinit_rqd) { - Log.verbose(F("Re-initializing LCD." CR)); + Log.verbose(F("Re-initializing LCD.\r\n")); http_server.lcd_reinit_rqd = false; lcd.reinit(); } diff --git a/src/sendData.cpp b/src/sendData.cpp index d4ed721..eb51a07 100644 --- a/src/sendData.cpp +++ b/src/sendData.cpp @@ -52,11 +52,11 @@ bool dataSendHandler::send_to_localTarget() // Local Target send_localTarget = false; send_lock = true; - tilt_scanner.deinit(); +// tilt_scanner.deinit(); if (WiFiClass::status() == WL_CONNECTED && strlen(config.localTargetURL) >= LOCALTARGET_MIN_URL_LENGTH) { - Log.verbose(F("Calling send to Local Target." CR)); + Log.verbose(F("Calling send to Local Target.\r\n")); DynamicJsonDocument doc(TILT_ALL_DATA_SIZE + 128); char tilt_data[TILT_ALL_DATA_SIZE + 128]; @@ -69,16 +69,16 @@ bool dataSendHandler::send_to_localTarget() if (send_to_url(config.localTargetURL, "", tilt_data, "application/json")) { - Log.notice(F("Completed send to Local Target." CR)); + Log.notice(F("Completed send to Local Target.\r\n")); } else { result = false; // There was an error with the previous send - Log.verbose(F("Error sending to Local Target." CR)); + Log.verbose(F("Error sending to Local Target.\r\n")); } } localTargetTicker.once(config.localTargetPushEvery, [](){send_localTarget = true;}); // Set up subsequent send to localTarget - tilt_scanner.init(); +// tilt_scanner.init(); } send_lock = false; return result; @@ -94,15 +94,15 @@ bool send_to_bf_and_bf() send_brewersFriend = false; if (WiFiClass::status() == WL_CONNECTED && strlen(config.brewersFriendKey) > BREWERS_FRIEND_MIN_KEY_LENGTH) { - Log.verbose(F("Calling send to Brewer's Friend." CR)); + Log.verbose(F("Calling send to Brewer's Friend.\r\n")); retval = data_sender.send_to_bf_and_bf(BF_MEANS_BREWERS_FRIEND); if (retval) { - Log.notice(F("Completed send to Brewer's Friend." CR)); + Log.notice(F("Completed send to Brewer's Friend.\r\n")); } else { - Log.verbose(F("Error sending to Brewer's Friend." CR)); + Log.verbose(F("Error sending to Brewer's Friend.\r\n")); } } brewersFriendTicker.once(BREWERS_FRIEND_DELAY, [](){send_brewersFriend = true;}); // Set up subsequent send to Brewer's Friend @@ -116,15 +116,15 @@ bool send_to_bf_and_bf() send_brewfather = false; if (WiFiClass::status() == WL_CONNECTED && strlen(config.brewfatherKey) > BREWFATHER_MIN_KEY_LENGTH) { - Log.verbose(F("Calling send to Brewfather." CR)); + Log.verbose(F("Calling send to Brewfather.\r\n")); retval = data_sender.send_to_bf_and_bf(BF_MEANS_BREWFATHER); if (retval) { - Log.notice(F("Completed send to Brewer's Friend." CR)); + Log.notice(F("Completed send to Brewer's Friend.\r\n")); } else { - Log.verbose(F("Error sending to Brewer's Friend." CR)); + Log.verbose(F("Error sending to Brewer's Friend.\r\n")); } } brewfatherTicker.once(BREWFATHER_DELAY, [](){send_brewfather = true;}); // Set up subsequent send to Brewfather @@ -149,7 +149,7 @@ bool dataSendHandler::send_to_bf_and_bf(const uint8_t which_bf) { if (strlen(config.brewfatherKey) <= BREWFATHER_MIN_KEY_LENGTH) { - Log.verbose(F("Brewfather key not populated. Returning." CR)); + Log.verbose(F("Brewfather key not populated. Returning.\r\n")); return false; } strcpy(url, "http://log.brewfather.net/stream?id="); @@ -159,7 +159,7 @@ bool dataSendHandler::send_to_bf_and_bf(const uint8_t which_bf) { if (strlen(config.brewersFriendKey) <= BREWERS_FRIEND_MIN_KEY_LENGTH) { - Log.verbose(F("Brewer's Friend key not populated. Returning." CR)); + Log.verbose(F("Brewer's Friend key not populated. Returning.\r\n")); return false; } strcpy(url, "http://log.brewersfriend.com/stream/"); @@ -167,7 +167,7 @@ bool dataSendHandler::send_to_bf_and_bf(const uint8_t which_bf) } else { - Log.error(F("Invalid value of which_bf passed to send_to_bf_and_bf." CR)); + Log.error(F("Invalid value of which_bf passed to send_to_bf_and_bf.\r\n")); return false; } @@ -177,8 +177,8 @@ bool dataSendHandler::send_to_bf_and_bf(const uint8_t which_bf) { if (tilt_scanner.tilt(i)->is_loaded()) { - Log.verbose(F("Tilt loaded with color name: %s" CR), tilt_scanner.tilt(i)->color_name().c_str()); - j["name"] = tilt_scanner.tilt(i)->color_name(); + Log.verbose(F("Tilt loaded with color name: %s\r\n"), tilt_color_names[i]); + j["name"] = tilt_color_names[i]; j["temp"] = tilt_scanner.tilt(i)->converted_temp(true); // Always in Fahrenheit j["temp_unit"] = "F"; j["gravity"] = tilt_scanner.tilt(i)->converted_gravity(false); @@ -208,7 +208,7 @@ bool dataSendHandler::send_to_brewstatus() send_lock = true; if (WiFiClass::status() == WL_CONNECTED && strlen(config.brewstatusURL) > BREWSTATUS_MIN_URL_LENGTH) { - Log.verbose(F("Calling send to Brew Status." CR)); + Log.verbose(F("Calling send to Brew Status.\r\n")); // The payload should look like this when sent to Brewstatus: // ('Request payload:', 'SG=1.019&Temp=71.0&Color=ORANGE&Timepoint=43984.33630927084&Beer=Beer&Comment=Comment') @@ -227,16 +227,16 @@ bool dataSendHandler::send_to_brewstatus() snprintf(payload, payload_size, "SG=%s&Temp=%s&Color=%s&Timepoint=%.11f&Beer=Undefined&Comment=", tilt_scanner.tilt(i)->converted_gravity(false).c_str(), tilt_scanner.tilt(i)->converted_temp(true).c_str(), // Only sending Fahrenheit numbers since we don't send units - tilt_scanner.tilt(i)->color_name().c_str(), + tilt_color_names[i], ((double)std::time(0) + (config.TZoffset * 3600.0)) / 86400.0 + 25569.0); if (send_to_url(config.brewstatusURL, "", payload, "application/x-www-form-urlencoded")) { - Log.notice(F("Completed send to Brew Status." CR)); + Log.notice(F("Completed send to Brew Status.\r\n")); } else { result = false; - Log.verbose(F("Error sending to Brew Status." CR)); + Log.verbose(F("Error sending to Brew Status.\r\n")); } } } @@ -251,131 +251,85 @@ bool dataSendHandler::send_to_google() { bool result = true; - if (send_gSheets && ! send_lock) - { + if (send_gSheets && !send_lock) { // Google Sheets send_gSheets = false; send_lock = true; - tilt_scanner.deinit(); - + //tilt_scanner.deinit(); + StaticJsonDocument payload; + char payload_string[GSHEETS_JSON]; + StaticJsonDocument retval; int httpResponseCode; int numSent = 0; +#if (ARDUINO_LOG_LEVEL == 6) + char buff[1024] = ""; +#endif - if (strlen(config.scriptsURL) >= GSCRIPTS_MIN_URL_LENGTH && strlen(config.scriptsEmail) >= GSCRIPTS_MIN_EMAIL_LENGTH) - { - Log.verbose(F("Checking for any pending Google Sheets pushes." CR)); - - for (uint8_t i = 0; i < TILT_COLORS; i++) - { - // Loop through each of the tilt colors cached by tilt_scanner - if (tilt_scanner.tilt(i)->is_loaded()) - { - // If there is a color present - if (tilt_scanner.tilt(i)->gsheets_beer_name().length() > 0) - { + // The google sheets handler only fires if we have both a Google Scripts URL to post to, and an email address. + if (strlen(config.scriptsURL) >= GSCRIPTS_MIN_URL_LENGTH && strlen(config.scriptsEmail) >= GSCRIPTS_MIN_EMAIL_LENGTH) { + Log.verbose(F("Checking for any pending Google Sheets pushes.\r\n")); +// Log.verbose(F("Executing on core %i.\r\n"), xPortGetCoreID()); + printMem(); + + for (uint8_t i = 0; i < TILT_COLORS; i++) { + // Loop through each of the tilt colors and check if it is both available and has active data + if (tilt_scanner.tilt(i)->is_loaded()) { + // Check if there is a google sheet name associated with the specific Tilt + if (strlen(config.gsheets_config[i].name) > 0) { + // If there's a sheet name saved, then we should send the data if (numSent == 0) - Log.notice(F("Beginning GSheets check-in." CR)); - // If there's a sheet name saved - StaticJsonDocument payload; - payload["Beer"] = tilt_scanner.tilt(i)->gsheets_beer_name(); - payload["Temp"] = tilt_scanner.tilt(i)->converted_temp(true); // Always in Fahrenheit + Log.notice(F("Beginning GSheets check-in.\r\n")); + payload["Beer"] = config.gsheets_config[i].name; + payload["Temp"] = tilt_scanner.tilt(i)->converted_temp(true); // Always send in Fahrenheit payload["SG"] = tilt_scanner.tilt(i)->converted_gravity(false); - payload["Color"] = tilt_scanner.tilt(i)->color_name(); + payload["Color"] = tilt_color_names[i]; payload["Comment"] = ""; payload["Email"] = config.scriptsEmail; // The gmail email address associated with the script on google payload["tzOffset"] = config.TZoffset; - char payload_string[GSHEETS_JSON]; serializeJson(payload, payload_string); payload.clear(); - http.useHTTP10(true); // Turn off chunked transfer encoding to parse the stream http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); // Follow the 301 - http.setConnectTimeout(3000); // Set 3 second timeout + http.setConnectTimeout(6000); // Set 6 second timeout + http.setReuse(false); secureClient.setInsecure(); // Ignore SHA fingerprint - if (! http.begin(secureClient, config.scriptsURL)) // Connect secure - { - Log.error(F("Unable to create secure connection to %s." CR), config.scriptsURL); + if (!http.begin(secureClient, config.scriptsURL)) { // Connect secure + Log.error(F("Unable to create secure connection to %s.\r\n"), config.scriptsURL); result = false; - } // Failed to open a connection - else - { - Log.verbose(F("Created secure connection to %s." CR), config.scriptsURL); - Log.verbose(F("Sending the following payload to Google Sheets (%s):\n\t\t%s" CR), tilt_scanner.tilt(i)->color_name().c_str(), payload_string); + } else { + // Failed to open a connection + Log.verbose(F("Created secure connection to %s.\r\n"), config.scriptsURL); + Log.verbose(F("Sending the following payload to Google Sheets (%s):\r\n\t\t%s\r\n"), tilt_color_names[i], payload_string); http.addHeader(F("Content-Type"), F("application/json")); // Specify content-type header httpResponseCode = http.POST(payload_string); // Send the payload - if (httpResponseCode == 200) - { + if (httpResponseCode == HTTP_CODE_OK) { // HTTP_CODE_OK = 200 // POST success - StaticJsonDocument retval; #if (ARDUINO_LOG_LEVEL == 6) - Log.verbose(F("JSON Response:" CR)); - ReadLoggingStream loggingStream(http.getStream(), Serial); - deserializeJson(retval, loggingStream); - Serial.println(); + // We need to use a buffer in order to be able to use the response twice + strlcpy(buff, http.getString().c_str(), 1024); + Log.verbose(F("HTTP Response: 200\r\nFull Response:\r\n\t%s\r\n"), buff); + deserializeJson(retval, buff); +// deserializeJson(retval, http.getString().c_str()); #else - deserializeJson(retval, http.getStream()); + deserializeJson(retval, http.getString().c_str()); #endif - switch(i) - { - case(0): - { - strlcpy(config.link_red, retval["doclongurl"].as().c_str(), 255); - break; - } - case(1): - { - strlcpy(config.link_green, retval["doclongurl"].as().c_str(), 255); - break; - } - case(2): - { - strlcpy(config.link_black, retval["doclongurl"].as().c_str(), 255); - break; - } - case(3): - { - strlcpy(config.link_purple, retval["doclongurl"].as().c_str(), 255); - break; - } - case(4): - { - strlcpy(config.link_orange, retval["doclongurl"].as().c_str(), 255); - break; - } - case(5): - { - strlcpy(config.link_blue, retval["doclongurl"].as().c_str(), 255); - break; - } - case(6): - { - strlcpy(config.link_yellow, retval["doclongurl"].as().c_str(), 255); - break; - } - case(7): - { - strlcpy(config.link_pink, retval["doclongurl"].as().c_str(), 255); - break; - } - default: - { - break; - } + + if(strcmp(config.gsheets_config[i].link, retval["doclongurl"].as().c_str()) != 0) { + Log.verbose(F("Storing new doclongurl: %s.\r\n"), retval["doclongurl"].as().c_str()); + strlcpy(config.gsheets_config[i].link, retval["doclongurl"].as().c_str(), 255); + saveConfig(); } - saveConfig(); retval.clear(); numSent++; - } // Response code = 200 - else - { - // Post generated an error - Log.error(F("Google send to %s Tilt failed (%d): %s. Response:\n%s" CR), - tilt_scanner.tilt(i)->color_name().c_str(), + } else { + // Post generated an error (response code != 200) + Log.error(F("Google send to %s Tilt failed (%d): %s. Response:\r\n%s\r\n"), + tilt_color_names[i], httpResponseCode, http.errorToString(httpResponseCode).c_str(), http.getString().c_str()); @@ -383,16 +337,16 @@ bool dataSendHandler::send_to_google() } // Response code != 200 } // Good connection http.end(); - yield(); + delay(100); // Give garbage collection time to run } // Check we have a sheet name for the color } // Check scanner is loaded for color } // Loop through colors - Log.notice(F("Submitted %l sheet%s to Google." CR), numSent, (numSent== 1) ? "" : "s"); + Log.notice(F("Submitted %l sheet%s to Google.\r\n"), numSent, (numSent== 1) ? "" : "s"); } gSheetsTicker.once(GSCRIPTS_DELAY, [](){send_gSheets = true;}); // Set up subsequent send to Google Sheets - tilt_scanner.init(); + //tilt_scanner.init(); } send_lock = false; return result; @@ -404,41 +358,29 @@ void dataSendHandler::init_mqtt() if (strcmp(config.mqttBrokerHost, "") != 0 || strlen(config.mqttBrokerHost) != 0) { - if (url.isMDNS(config.mqttBrokerHost)) - { - Log.verbose(F("Initializing connection to MQTTBroker: %s (%s) on port: %d" CR), + if (url.isMDNS(config.mqttBrokerHost)) { + Log.verbose(F("Initializing connection to MQTTBroker: %s (%s) on port: %d\r\n"), config.mqttBrokerHost, url.getIP(config.mqttBrokerHost).toString().c_str(), config.mqttBrokerPort); - } - else - { - Log.verbose(F("Initializing connection to MQTTBroker: %s on port: %d" CR), + } else { + Log.verbose(F("Initializing connection to MQTTBroker: %s on port: %d\r\n"), config.mqttBrokerHost, config.mqttBrokerPort); } - if (mqtt_alreadyinit) - { + if (mqtt_alreadyinit) { mqttClient.disconnect(); delay(250); - if (url.isMDNS(config.mqttBrokerHost)) - { + if (url.isMDNS(config.mqttBrokerHost)) { mqttClient.setHost(url.getIP(config.mqttBrokerHost), config.mqttBrokerPort); - } - else - { + } else { mqttClient.setHost(config.mqttBrokerHost, config.mqttBrokerPort); } - } - else - { - if (url.isMDNS(config.mqttBrokerHost)) - { + } else { + if (url.isMDNS(config.mqttBrokerHost)) { mqttClient.begin(url.getIP(config.mqttBrokerHost), config.mqttBrokerPort, mqClient); - } - else - { + } else { mqttClient.begin(config.mqttBrokerHost, config.mqttBrokerPort, mqClient); } } @@ -490,29 +432,29 @@ bool dataSendHandler::send_to_url(const char *url, const char *apiKey, const cha { if (lcburl.isMDNS(lcburl.getHost().c_str())) // Use the IP address we resolved (necessary for mDNS) - Log.verbose(F("Connecting to: %s at %s on port %l" CR), + Log.verbose(F("Connecting to: %s at %s on port %l\r\n"), lcburl.getHost().c_str(), lcburl.getIP(lcburl.getHost().c_str() ).toString().c_str(), lcburl.getPort()); else - Log.verbose(F("Connecting to: %s on port %l" CR), + Log.verbose(F("Connecting to: %s on port %l\r\n"), lcburl.getHost().c_str(), lcburl.getPort()); if (client.connect(lcburl.getIP(lcburl.getHost().c_str()), 80)) { - Log.verbose(F("Connected to: %s." CR), lcburl.getHost().c_str()); + Log.verbose(F("Connected to: %s.\r\n"), lcburl.getHost().c_str()); // Open POST connection if (lcburl.getAfterPath().length() > 0) { - Log.verbose(F("POST /%s%s HTTP/1.1" CR), + Log.verbose(F("POST /%s%s HTTP/1.1\r\n"), lcburl.getPath().c_str(), lcburl.getAfterPath().c_str()); } else { - Log.verbose(F("POST /%s HTTP/1.1" CR), lcburl.getPath().c_str()); + Log.verbose(F("POST /%s HTTP/1.1\r\n"), lcburl.getPath().c_str()); } client.print(F("POST /")); client.print(lcburl.getPath().c_str()); @@ -525,31 +467,31 @@ bool dataSendHandler::send_to_url(const char *url, const char *apiKey, const cha // Begin headers // // Host - Log.verbose(F("Host: %s:%l" CR), lcburl.getHost().c_str(), lcburl.getPort()); + Log.verbose(F("Host: %s:%l\r\n"), lcburl.getHost().c_str(), lcburl.getPort()); client.print(F("Host: ")); client.print(lcburl.getHost().c_str()); client.print(F(":")); client.println(lcburl.getPort()); // - Log.verbose(F("Connection: close" CR)); + Log.verbose(F("Connection: close\r\n")); client.println(F("Connection: close")); // Content - Log.verbose(F("Content-Length: %l" CR), strlen(dataToSend)); + Log.verbose(F("Content-Length: %l\r\n"), strlen(dataToSend)); client.print(F("Content-Length: ")); client.println(strlen(dataToSend)); // Content Type - Log.verbose(F("Content-Type: %s" CR), contentType); + Log.verbose(F("Content-Type: %s\r\n"), contentType); client.print(F("Content-Type: ")); client.println(contentType); // API Key if (strlen(apiKey) > 2) { - Log.verbose(F("X-API-KEY: %s" CR), apiKey); + Log.verbose(F("X-API-KEY: %s\r\n"), apiKey); client.print(F("X-API-KEY: ")); client.println(apiKey); } // Terminate headers with a blank line - Log.verbose(F("End headers." CR)); + Log.verbose(F("End headers.\r\n")); client.println(); // // End Headers @@ -560,7 +502,7 @@ bool dataSendHandler::send_to_url(const char *url, const char *apiKey, const cha char status[32] = {0}; client.readBytesUntil('\r', status, sizeof(status)); client.stop(); - Log.verbose(F("Status: %s" CR), status); + Log.verbose(F("Status: %s\r\n"), status); if (strcmp(status + 9, "200 OK") == 0) { if (checkBody == true) // We can do additional checks here @@ -569,42 +511,42 @@ bool dataSendHandler::send_to_url(const char *url, const char *apiKey, const cha String response = String(status); if (response.indexOf(bodyCheck) >= 0) { - Log.verbose(F("Response body ok." CR)); + Log.verbose(F("Response body ok.\r\n")); retVal = true; } else { - Log.error(F("Unexpected body content: %s" CR), response.c_str()); + Log.error(F("Unexpected body content: %s\r\n"), response.c_str()); retVal = false; } } else { - Log.verbose(F("Post to %s was successful." CR), lcburl.getHost().c_str()); + Log.verbose(F("Post to %s was successful.\r\n"), lcburl.getHost().c_str()); retVal = true; } } else { - Log.error(F("Unexpected status: %s" CR), status); + Log.error(F("Unexpected status: %s\r\n"), status); retVal = false; } } else { - Log.warning(F("Connection failed, Host: %s, Port: %l (Err: %d)" CR), + Log.warning(F("Connection failed, Host: %s, Port: %l (Err: %d)\r\n"), lcburl.getHost().c_str(), lcburl.getPort(), client.connected()); retVal = false; } } else { - Log.error(F("Invalid target: %s." CR), url); + Log.error(F("Invalid target: %s.\r\n"), url); } } else { - Log.notice(F("No URL provided, or no data to send." CR)); + Log.notice(F("No URL provided, or no data to send.\r\n")); retVal = false; } return retVal; @@ -624,7 +566,7 @@ bool dataSendHandler::send_to_mqtt() send_lock = true; if (strcmp(config.mqttBrokerHost, "") != 0 || strlen(config.mqttBrokerHost) != 0) { - Log.verbose(F("Publishing available results to MQTT Broker." CR)); + Log.verbose(F("Publishing available results to MQTT Broker.\r\n")); // Function sends three payloads with the first two designed to // support autodiscovery and configuration on Home Assistant. // General payload formatted as json when sent to mqTT: @@ -639,7 +581,7 @@ bool dataSendHandler::send_to_mqtt() char tilt_topic[50] = {'\0'}; snprintf(tilt_topic, 50, "%s/tilt_%s", config.mqttTopic, - tilt_scanner.tilt(i)->color_name().c_str()); + tilt_color_names[i]); for (uint8_t j = 0; j < 3; j++) { @@ -652,7 +594,7 @@ bool dataSendHandler::send_to_mqtt() case 0: //Home Assistant Config Topic for Temperature sprintf(m_topic, "homeassistant/sensor/%s_tilt_%sT/config", config.mqttTopic, - tilt_scanner.tilt(i)->color_name().c_str()); + tilt_color_names[i]); payload["dev_cla"] = "temperature"; strcat(unit, "\u00b0"); strcat(unit, config.tempUnit); @@ -660,7 +602,7 @@ bool dataSendHandler::send_to_mqtt() payload["ic"] = "mdi:thermometer"; payload["stat_t"] = tilt_topic; strcat(tilt_name, "Tilt Temperature - "); - strcat(tilt_name, tilt_scanner.tilt(i)->color_name().c_str()); + strcat(tilt_name, tilt_color_names[i]); payload["name"] = tilt_name; payload["val_tpl"] = "{{value_json.Temp}}"; retain = true; @@ -668,13 +610,13 @@ bool dataSendHandler::send_to_mqtt() case 1: //Home Assistant Config Topic for Sp Gravity sprintf(m_topic, "homeassistant/sensor/%s_tilt_%sG/config", config.mqttTopic, - tilt_scanner.tilt(i)->color_name().c_str()); + tilt_color_names[i]); //payload["dev_cla"] = "None"; payload["unit_of_meas"] = "SG"; //payload["ic"] = ""; payload["stat_t"] = tilt_topic; strcat(tilt_name, "Tilt Specific Gravity - "); - strcat(tilt_name, tilt_scanner.tilt(i)->color_name().c_str()); + strcat(tilt_name, tilt_color_names[i]); payload["name"] = tilt_name; payload["val_tpl"] = "{{value_json.SG}}"; retain = true; @@ -685,7 +627,7 @@ bool dataSendHandler::send_to_mqtt() char current_temp[5] = {'\0'}; strcpy(current_grav, tilt_scanner.tilt(i)->converted_gravity(false).c_str()); strcpy(current_temp, tilt_scanner.tilt(i)->converted_temp(false).c_str()); - payload["Color"] = tilt_scanner.tilt(i)->color_name(); + payload["Color"] = tilt_color_names[i]; payload["timeStamp"] = (int)std::time(0); payload["fermunits"] = "SG"; payload["SG"] = current_grav; @@ -697,12 +639,12 @@ bool dataSendHandler::send_to_mqtt() char payload_string[300] = {'\0'}; serializeJson(payload, payload_string); - Log.verbose(F("Topic: %s" CR), m_topic); - Log.verbose(F("Message: %s" CR), payload_string); + Log.verbose(F("Topic: %s\r\n"), m_topic); + Log.verbose(F("Message: %s\r\n"), payload_string); if (!mqttClient.connected() && j == 0) { - Log.warning(F("MQTT disconnected. Attempting to reconnect to MQTT Broker" CR)); + Log.warning(F("MQTT disconnected. Attempting to reconnect to MQTT Broker\r\n")); connect_mqtt(); } @@ -713,17 +655,14 @@ bool dataSendHandler::send_to_mqtt() } } } + if (result) { + Log.notice(F("Completed publish to MQTT Broker.\r\n")); + } else { + result = false; // There was an error with the previous send + Log.verbose(F("Error publishing to MQTT Broker.\r\n")); + } } mqttTicker.once(config.mqttPushEvery, [](){send_mqtt = true;}); // Set up subsequent send to MQTT - if (result) - { - Log.notice(F("Completed publish to MQTT Broker." CR)); - } - else - { - result = false; // There was an error with the previous send - Log.verbose(F("Error publishing to MQTT Broker." CR)); - } } send_lock = false; return result; diff --git a/src/sendData.h b/src/sendData.h index 62fb6c9..5abb6cb 100644 --- a/src/sendData.h +++ b/src/sendData.h @@ -1,7 +1,3 @@ -// -// Created by John Beeler on 2/18/19. -// - #ifndef TILTBRIDGE_SENDDATA_H #define TILTBRIDGE_SENDDATA_H @@ -15,10 +11,6 @@ #include #include -#if (ARDUINO_LOG_LEVEL == 6) -#include -#endif - #include #include #include @@ -29,9 +21,9 @@ #include #include -#define GSCRIPTS_DELAY (10 * 60 * 1000) // 10 minute delay between pushes to Google Sheets directly -#define BREWERS_FRIEND_DELAY (15 * 60 * 1000) // 15 minute delay between pushes to Brewer's Friend -#define BREWFATHER_DELAY (15 * 60 * 1000) // 15 minute delay between pushes to Brewfather +#define GSCRIPTS_DELAY (10 * 60) // 10 minute delay between pushes to Google Sheets directly +#define BREWERS_FRIEND_DELAY (15 * 60) // 15 minute delay between pushes to Brewer's Friend +#define BREWFATHER_DELAY (15 * 60) // 15 minute delay between pushes to Brewfather #define BREWFATHER_MIN_KEY_LENGTH 5 #define BREWERS_FRIEND_MIN_KEY_LENGTH 12 @@ -42,7 +34,7 @@ #define GSCRIPTS_MIN_EMAIL_LENGTH 7 #define GSHEETS_JSON 512 -// This is me being simplifying the reuse of code. The formats for Brewer's +// This is me being lazy and simplifying the reuse of code. The formats for Brewer's // Friend and Brewfather are basically the same so I'm combining them together // in one function #define BF_MEANS_BREWFATHER 1 diff --git a/src/serialhandler.cpp b/src/serialhandler.cpp index 55052fe..ad87ee4 100644 --- a/src/serialhandler.cpp +++ b/src/serialhandler.cpp @@ -25,7 +25,7 @@ void serial() SERIAL.flush(); Log.begin(ARDUINO_LOG_LEVEL, &SERIAL, true); Log.setPrefix(printTimestamp); - Log.notice(F("Serial logging started at %l." CR), BAUD); + Log.notice(F("Serial logging started at %l.\r\n"), BAUD); } void printTimestamp(Print *_logOutput) diff --git a/src/tilt/tiltHydrometer.cpp b/src/tilt/tiltHydrometer.cpp index 31247f6..15b771f 100644 --- a/src/tilt/tiltHydrometer.cpp +++ b/src/tilt/tiltHydrometer.cpp @@ -5,6 +5,29 @@ #include "tiltHydrometer.h" #include "jsonconfig.h" +const char* tilt_color_names[] = { + "Red", + "Green", + "Black", + "Purple", + "Orange", + "Blue", + "Yellow", + "Pink" +}; + + +const uint32_t tilt_text_colors[] = { + 0xF800, // Red + 0x07E0, // Green + 0xFFFF, // Black (white) + 0x780F, // Purple + 0xBAA0, // Orange (hook 'em) + 0x001F, // Blue + 0xFFE0, // Yellow + 0xFE19 // Pink +}; + tiltHydrometer::tiltHydrometer(uint8_t color) { m_loaded = false; @@ -62,107 +85,6 @@ uint8_t tiltHydrometer::uuid_to_color_no(std::string uuid) } } -std::string tiltHydrometer::color_name() -{ - // If these change, modify TILT_COLOR_SIZE (currrently 7 for "Yellow" + 1) - switch (m_color) - { - case TILT_COLOR_RED: - return "Red"; - case TILT_COLOR_GREEN: - return "Green"; - case TILT_COLOR_BLACK: - return "Black"; - case TILT_COLOR_PURPLE: - return "Purple"; - case TILT_COLOR_ORANGE: - return "Orange"; - case TILT_COLOR_BLUE: - return "Blue"; - case TILT_COLOR_YELLOW: - return "Yellow"; - case TILT_COLOR_PINK: - return "Pink"; - default: - return "None"; - } -} - -uint32_t tiltHydrometer::text_color() -{ - - switch (m_color) - { - case TILT_COLOR_RED: - return 0xF800; - case TILT_COLOR_GREEN: - return 0x07E0; - case TILT_COLOR_BLACK: - return 0xFFFF; - case TILT_COLOR_PURPLE: - return 0x780F; - case TILT_COLOR_ORANGE: - return 0xFDA0; - case TILT_COLOR_BLUE: - return 0x001F; - case TILT_COLOR_YELLOW: - return 0xFFE0; - case TILT_COLOR_PINK: - return 0xFE19; - default: - return 0xFFFF; - } -} - -std::string tiltHydrometer::gsheets_beer_name() -{ - switch (m_color) - { - case TILT_COLOR_RED: - return config.sheetName_red; - case TILT_COLOR_GREEN: - return config.sheetName_green; - case TILT_COLOR_BLACK: - return config.sheetName_black; - case TILT_COLOR_PURPLE: - return config.sheetName_purple; - case TILT_COLOR_ORANGE: - return config.sheetName_orange; - case TILT_COLOR_BLUE: - return config.sheetName_blue; - case TILT_COLOR_YELLOW: - return config.sheetName_yellow; - case TILT_COLOR_PINK: - return config.sheetName_pink; - default: - return ""; - } -} - -std::string tiltHydrometer::gsheets_link_name() -{ - switch (m_color) - { - case TILT_COLOR_RED: - return config.link_red; - case TILT_COLOR_GREEN: - return config.link_green; - case TILT_COLOR_BLACK: - return config.link_black; - case TILT_COLOR_PURPLE: - return config.link_purple; - case TILT_COLOR_ORANGE: - return config.link_orange; - case TILT_COLOR_BLUE: - return config.link_blue; - case TILT_COLOR_YELLOW: - return config.link_yellow; - case TILT_COLOR_PINK: - return config.link_pink; - default: - return ""; - } -} bool tiltHydrometer::set_values(uint16_t i_temp, uint16_t i_grav, uint8_t i_tx_pwr, int8_t current_rssi) { @@ -229,72 +151,20 @@ bool tiltHydrometer::set_values(uint16_t i_temp, uint16_t i_grav, uint8_t i_tx_p #if PRINT_GRAV_UPDATES == 1 char value[7]; sprintf(value, "%.4f", d_grav); - Log.verbose(F("%s Tilt gravity = %s" CR), color_name().c_str(), value); + Log.verbose(F("%s Tilt gravity = %s\r\n"), tilt_color_names[m_color], value); #endif if (config.applyCalibration) { - double x0 = 0.0; - double x1 = 1.0; - double x2 = 0.0; - double x3 = 0.0; - - switch (m_color) - { - case TILT_COLOR_RED: - x0 = config.cal_red_x0; - x1 = config.cal_red_x1; - x2 = config.cal_red_x2; - x3 = config.cal_red_x3; - break; - case TILT_COLOR_GREEN: - x0 = config.cal_green_x0; - x1 = config.cal_green_x1; - x2 = config.cal_green_x2; - x3 = config.cal_green_x3; - break; - case TILT_COLOR_BLACK: - x0 = config.cal_black_x0; - x1 = config.cal_black_x1; - x2 = config.cal_black_x2; - x3 = config.cal_black_x3; - break; - case TILT_COLOR_PURPLE: - x0 = config.cal_purple_x0; - x1 = config.cal_purple_x1; - x2 = config.cal_purple_x2; - x3 = config.cal_purple_x3; - break; - case TILT_COLOR_ORANGE: - x0 = config.cal_orange_x0; - x1 = config.cal_orange_x1; - x2 = config.cal_orange_x2; - x3 = config.cal_orange_x3; - break; - case TILT_COLOR_BLUE: - x0 = config.cal_blue_x0; - x1 = config.cal_blue_x1; - x2 = config.cal_blue_x2; - x3 = config.cal_blue_x3; - break; - case TILT_COLOR_YELLOW: - x0 = config.cal_yellow_x0; - x1 = config.cal_yellow_x1; - x2 = config.cal_yellow_x2; - x3 = config.cal_yellow_x3; - break; - case TILT_COLOR_PINK: - x0 = config.cal_pink_x0; - x1 = config.cal_pink_x1; - x2 = config.cal_pink_x2; - x3 = config.cal_pink_x3; - break; - } + double x0 = config.tilt_calibration[m_color].x0; + double x1 = config.tilt_calibration[m_color].x1; + double x2 = config.tilt_calibration[m_color].x2; + double x3 = config.tilt_calibration[m_color].x3; /* for (auto& el : cal_params.items()) { std::string coeff = el.key(); double val = el.value().get(); - Log.verbose(F("Calibration coefficient %s = %D" CR), coeff.c_str(), val); + Log.verbose(F("Calibration coefficient %s = %D\r\n"), coeff.c_str(), val); if (!coeff.compare("x0")) x0 = val; if (!coeff.compare("x1")) x1 = val; @@ -307,7 +177,7 @@ bool tiltHydrometer::set_values(uint16_t i_temp, uint16_t i_grav, uint8_t i_tx_p char calvalue[7]; sprintf(calvalue, "%.4f", d_grav); - Log.verbose(F("%s Tilt calibration corrected gravity = %s" CR), color_name().c_str(), calvalue); + Log.verbose(F("%s Tilt calibration corrected gravity = %s\r\n"), tilt_color_names[m_color], calvalue); } if (config.tempCorrect) @@ -318,7 +188,7 @@ bool tiltHydrometer::set_values(uint16_t i_temp, uint16_t i_grav, uint8_t i_tx_p char calvalue[6]; sprintf(calvalue, "%.4f", d_grav); - Log.verbose(F("%s Tilt temperature corrected gravity = %s" CR), color_name().c_str(), calvalue); + Log.verbose(F("%s Tilt temperature corrected gravity = %s\r\n"), tilt_color_names[m_color], calvalue); } gravity = (int)round(d_grav * grav_scalar); @@ -349,18 +219,22 @@ void tiltHydrometer::to_json_string(char *json_string, bool use_raw_gravity) { StaticJsonDocument j; - j["color"] = color_name(); + j["color"] = tilt_color_names[m_color]; j["temp"] = converted_temp(false); j["tempUnit"] = is_celsius() ? "C" : "F"; j["gravity"] = converted_gravity(use_raw_gravity); - j["gsheets_name"] = gsheets_beer_name(); - j["gsheets_link"] = gsheets_link_name(); j["weeks_on_battery"] = weeks_since_last_battery_change; j["sends_battery"] = receives_battery; j["high_resolution"] = tilt_pro; j["fwVersion"] = version_code; j["rssi"] = rssi; + // These are loaded from config, but are included in the JSON for simplicity in generating the dashboard without + // an additional API call + j["gsheets_name"] = config.gsheets_config[m_color].name; + j["gsheets_link"] = config.gsheets_config[m_color].link; + + serializeJson(j, json_string, TILT_DATA_SIZE); } diff --git a/src/tilt/tiltHydrometer.h b/src/tilt/tiltHydrometer.h index 68ed634..ee60a23 100644 --- a/src/tilt/tiltHydrometer.h +++ b/src/tilt/tiltHydrometer.h @@ -1,40 +1,36 @@ -// -// Created by John Beeler on 4/28/18. -// - #ifndef TILTBRIDGE_TILTHYDROMETER_H #define TILTBRIDGE_TILTHYDROMETER_H -#include "jsonconfig.h" +//#include "jsonconfig.h" #include #include #define TILT_DATA_SIZE 477 // JSON size of a Tilt #define TILT_ALL_DATA_SIZE (TILT_DATA_SIZE * TILT_COLORS + 71) // JSON size of 8 Tilts -// There's definitely a better way of doing this -#define TILT_COLOR_RED 0 -#define TILT_COLOR_GREEN 1 -#define TILT_COLOR_BLACK 2 + +// Internally, we keep track of the Tilt colors by index +#define TILT_COLOR_RED 0 +#define TILT_COLOR_GREEN 1 +#define TILT_COLOR_BLACK 2 #define TILT_COLOR_PURPLE 3 #define TILT_COLOR_ORANGE 4 -#define TILT_COLOR_BLUE 5 +#define TILT_COLOR_BLUE 5 #define TILT_COLOR_YELLOW 6 -#define TILT_COLOR_PINK 7 - -#define TILT_COLOR_SIZE 7 // Let's keep track of the longest this string may be (Yellow) +1 +#define TILT_COLOR_PINK 7 #define TILT_COLORS 8 #define TILT_NONE 255 // Alternative to a tilt color -#define TILT_COLOR_RED_UUID "a495bb10c5b14b44b5121370f02d74de" -#define TILT_COLOR_GREEN_UUID "a495bb20c5b14b44b5121370f02d74de" -#define TILT_COLOR_BLACK_UUID "a495bb30c5b14b44b5121370f02d74de" + +#define TILT_COLOR_RED_UUID "a495bb10c5b14b44b5121370f02d74de" +#define TILT_COLOR_GREEN_UUID "a495bb20c5b14b44b5121370f02d74de" +#define TILT_COLOR_BLACK_UUID "a495bb30c5b14b44b5121370f02d74de" #define TILT_COLOR_PURPLE_UUID "a495bb40c5b14b44b5121370f02d74de" #define TILT_COLOR_ORANGE_UUID "a495bb50c5b14b44b5121370f02d74de" -#define TILT_COLOR_BLUE_UUID "a495bb60c5b14b44b5121370f02d74de" +#define TILT_COLOR_BLUE_UUID "a495bb60c5b14b44b5121370f02d74de" #define TILT_COLOR_YELLOW_UUID "a495bb70c5b14b44b5121370f02d74de" -#define TILT_COLOR_PINK_UUID "a495bb80c5b14b44b5121370f02d74de" +#define TILT_COLOR_PINK_UUID "a495bb80c5b14b44b5121370f02d74de" #define TILT_NO_DATA_RECEIVED_EXPIRATION (5 * 60 * 1000) // expire in 5 minutes if we didn't read any values in that time. in ms @@ -46,11 +42,7 @@ class tiltHydrometer explicit tiltHydrometer(uint8_t color); bool set_values(uint16_t i_temp, uint16_t i_grav, uint8_t i_tx_pwr, int8_t current_rssi); - std::string color_name(); - uint32_t text_color(); std::string converted_gravity(bool use_raw_gravity); - std::string gsheets_beer_name(); - std::string gsheets_link_name(); void to_json_string(char *json_string, bool use_raw_gravity); std::string converted_temp(bool fahrenheit_only); bool is_celsius() const; @@ -58,7 +50,6 @@ class tiltHydrometer static uint8_t uuid_to_color_no(std::string data); - // There is no real reason these need to be uint32, given that we are receiving 2 bytes each (uint16) uint16_t temp; uint16_t gravity; uint16_t gravity_smoothed; @@ -70,12 +61,15 @@ class tiltHydrometer bool receives_battery; // Tracks if this tilt sends battery life bool tilt_pro; // Tracks if this tilt is "high resolution" or not (ie. is a Tilt Pro) + uint8_t m_color; // Color number (0-7) for lookups private: - uint8_t m_color; bool m_loaded; // Has data been loaded from an ad string unsigned long m_lastUpdate; // Keep track of when we last updated and stop propagating out stale information bool m_has_sent_197; // Used to determine if the tilt sends battery life (a 197 tx_pwr followed by a non-197 tx_pwr) }; +extern const char* tilt_color_names[]; +extern const uint32_t tilt_text_colors[]; + #endif //TILTBRIDGE_TILTHYDROMETER_H diff --git a/src/tilt/tiltScanner.cpp b/src/tilt/tiltScanner.cpp index ca05810..7d62205 100644 --- a/src/tilt/tiltScanner.cpp +++ b/src/tilt/tiltScanner.cpp @@ -22,7 +22,7 @@ void MyAdvertisedDeviceCallbacks::onResult(NimBLEAdvertisedDevice *advertisedDev advertisedDevice->getManufacturerData()[2] == 0x02 && advertisedDevice->getManufacturerData()[3] == 0x15) { #ifdef BLE_PRINT_ALL_DEVICES - Log.verbose(F("Advertised iBeacon Device: %s " CR), advertisedDevice->toString().c_str()); + Log.verbose(F("Advertised iBeacon Device: %s \r\n"), advertisedDevice->toString().c_str()); #endif tilt_scanner.load_tilt_from_advert_hex(advertisedDevice->getManufacturerData(), advertisedDevice->getRSSI()); } @@ -67,19 +67,14 @@ void tiltScanner::deinit() bool tiltScanner::scan() { bool retval = false; - if (shouldRun) - { - if (!pBLEScan->isScanning()) // Check if scan already in progress - //Try to start a new scan - { + if (shouldRun) { + if (!pBLEScan->isScanning()) { // Check if scan already in progress + //Try to start a new scan pBLEScan->clearResults(); - if (pBLEScan->start(BLE_SCAN_TIME, nullptr, true)) //This no longer ever returns true...possibly a bug?? - { + if (pBLEScan->start(BLE_SCAN_TIME, nullptr, true)) { retval = true; //Scan successfully started. - } - else - { - Log.verbose(F("Scan failed to start." CR)); + } else { + Log.verbose(F("Scan failed to start.\r\n")); } } } @@ -147,9 +142,9 @@ uint8_t tiltScanner::load_tilt_from_advert_hex(const std::string &advert_string_ return TILT_NONE; } - uint16_t temp = std::stoul(temp_arr, nullptr, 16); - uint16_t gravity = std::stoul(grav_arr, nullptr, 16); - uint8_t tx_pwr = std::stoul(tx_pwr_arr, nullptr, 16); + uint16_t temp = std::strtoul(temp_arr, nullptr, 16); + uint16_t gravity = std::strtoul(grav_arr, nullptr, 16); + uint8_t tx_pwr = std::strtoul(tx_pwr_arr, nullptr, 16); m_tilt_devices[m_color]->set_values(temp, gravity, tx_pwr, current_rssi); @@ -164,16 +159,14 @@ tiltHydrometer *tiltScanner::tilt(uint8_t color) void tiltScanner::tilt_to_json_string(char *all_tilt_json, bool use_raw_gravity) { DynamicJsonDocument doc(TILT_ALL_DATA_SIZE); - for (uint8_t i = 0; i < TILT_COLORS; i++) + char tilt_data[TILT_DATA_SIZE]; + for(uint8_t i = 0; i < TILT_COLORS; i++) { if (m_tilt_devices[i]->is_loaded()) { - char color[TILT_COLOR_SIZE]; - strlcpy(color, m_tilt_devices[i]->color_name().c_str(), TILT_COLOR_SIZE); - char tilt_data[TILT_DATA_SIZE]; tilt_data[0] = {'\0'}; m_tilt_devices[i]->to_json_string(tilt_data, use_raw_gravity); - doc[color] = serialized(tilt_data); + doc[tilt_color_names[i]] = serialized(tilt_data); } } serializeJson(doc, all_tilt_json, TILT_ALL_DATA_SIZE); diff --git a/src/wifi_setup.cpp b/src/wifi_setup.cpp index bcf07d6..bd38e5d 100644 --- a/src/wifi_setup.cpp +++ b/src/wifi_setup.cpp @@ -11,7 +11,7 @@ void saveParamsCallback() { void apCallback(WiFiManager *myWiFiManager) { // Callback to display the WiFi LCD notification and set bandwidth - Log.verbose(F("Entered config mode: SSID: %s, IP: %s" CR), myWiFiManager->getConfigPortalSSID().c_str(), WiFi.softAPIP().toString().c_str()); + Log.verbose(F("Entered config mode: SSID: %s, IP: %s\r\n"), myWiFiManager->getConfigPortalSSID().c_str(), WiFi.softAPIP().toString().c_str()); lcd.display_wifi_connect_screen(myWiFiManager->getConfigPortalSSID().c_str(), WIFI_SETUP_AP_PASS); esp_wifi_set_bandwidth(WIFI_IF_AP, WIFI_BW_HT20); // Set the bandwidth of ESP32 interface } @@ -33,7 +33,7 @@ void mdnsReset() { Log.error(F("Error resetting MDNS responder.")); ESP.restart(); } else { - Log.notice(F("mDNS responder restarted, hostname: %s.local." CR), WiFi.getHostname()); + Log.notice(F("mDNS responder restarted, hostname: %s.local.\r\n"), WiFi.getHostname()); MDNS.addService("http", "tcp", WEBPORT); MDNS.addService("tiltbridge", "tcp", WEBPORT); #if DOTELNET == true @@ -67,7 +67,7 @@ void initWiFi() { wm.addParameter(&custom_mdns_name); if (!wm.autoConnect(WIFI_SETUP_AP_NAME, WIFI_SETUP_AP_PASS)) { - Log.warning(F("Failed to connect and/or hit timeout. Restarting." CR)); + Log.warning(F("Failed to connect and/or hit timeout. Restarting.\r\n")); ESP.restart(); } else { // We finished with portal (We were configured) @@ -95,7 +95,7 @@ void initWiFi() { } if (!MDNS.begin(config.mdnsID)) { - Log.error(F("Error setting up MDNS responder." CR)); + Log.error(F("Error setting up MDNS responder.\r\n")); } MDNS.addService("http", "tcp", WEBPORT); // technically we should wait on this, but I'm impatient.