diff --git a/data/js/app.js b/data/js/app.js index 623c6aa4..6fc7e456 100644 --- a/data/js/app.js +++ b/data/js/app.js @@ -78,7 +78,8 @@ const vueApp = Vue.createApp({ 2: 'Brew PID Parameters', 3: 'Brew Control', 4: 'Scale Parameters', - 5: 'Power Settings' + 5: 'Display Settings', + 6: 'Power Settings' } return sectionNames[sectionId] diff --git a/platformio.ini b/platformio.ini index 393bea29..3f35ab20 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = knolleary/PubSubClient @ 2.8.0 bblanchon/ArduinoJson @ 6.21.4 git+https://github.com/esphome/AsyncTCP @ 2.1.4 - git+https://github.com/esphome/ESPAsyncWebServer @ 3.2.2 + git+https://github.com/esphome/ESPAsyncWebServer @ 3.3.0 git+https://github.com/tzapu/WiFiManager @ 2.0.17 extra_scripts = pre:auto_firmware_version.py diff --git a/src/defaults.h b/src/defaults.h index 7de3ef82..a097a10c 100644 --- a/src/defaults.h +++ b/src/defaults.h @@ -48,48 +48,54 @@ int writeSysParamsToStorage(void); #define BACKFLUSH_FILL_TIME 5 // time in seconds the pump is running during backflush #define BACKFLUSH_FLUSH_TIME 10 // time in seconds the 3-way valve is open during backflush #define FEATURE_BREW_CONTROL 0 // enables function to control pump and solenoid valve +#define FEATURE_SHOT_TIMER 0 // enables full screen shot timer +#define SHOT_TIMER_DISPLAY_DELAY 3 // time in seconds that shot timer will be shown after brew finished +#define FEATURE_HEATING_LOGO 1 // enables full screen logo if mashine is heating +#define FEATURE_PID_OFF_LOGO 1 // enables full screen logo if pid is switched off -#define PID_KP_START_MIN 0 -#define PID_KP_START_MAX 999 -#define PID_TN_START_MIN 0 -#define PID_TN_START_MAX 999 -#define PID_KP_REGULAR_MIN 0 -#define PID_KP_REGULAR_MAX 999 -#define PID_TN_REGULAR_MIN 0 -#define PID_TN_REGULAR_MAX 999 -#define PID_TV_REGULAR_MIN 0 -#define PID_TV_REGULAR_MAX 999 -#define PID_I_MAX_REGULAR_MIN 0 -#define PID_I_MAX_REGULAR_MAX 999 -#define PID_KP_BD_MIN 0 -#define PID_KP_BD_MAX 999 -#define PID_TN_BD_MIN 0 -#define PID_TN_BD_MAX 999 -#define PID_TV_BD_MIN 0 -#define PID_TV_BD_MAX 999 -#define BREW_SETPOINT_MIN 20 -#define BREW_SETPOINT_MAX 110 -#define STEAM_SETPOINT_MIN 100 -#define STEAM_SETPOINT_MAX 140 -#define BREW_TEMP_OFFSET_MIN 0 -#define BREW_TEMP_OFFSET_MAX 20 -#define BREW_TIME_MIN 0 -#define BREW_TIME_MAX 180 -#define BREW_PID_DELAY_MIN 0 -#define BREW_PID_DELAY_MAX 60 -#define PRE_INFUSION_TIME_MIN 0 -#define PRE_INFUSION_TIME_MAX 60 -#define PRE_INFUSION_PAUSE_MIN 0 -#define PRE_INFUSION_PAUSE_MAX 60 -#define WEIGHTSETPOINT_MIN 0 -#define WEIGHTSETPOINT_MAX 500 -#define PID_KP_STEAM_MIN 0 -#define PID_KP_STEAM_MAX 500 -#define STANDBY_MODE_TIME_MIN 30 -#define STANDBY_MODE_TIME_MAX 120 -#define BACKFLUSH_CYCLES_MIN 2 -#define BACKFLUSH_CYCLES_MAX 20 -#define BACKFLUSH_FILL_TIME_MIN 5 -#define BACKFLUSH_FILL_TIME_MAX 20 -#define BACKFLUSH_FLUSH_TIME_MIN 5 -#define BACKFLUSH_FLUSH_TIME_MAX 20 +#define PID_KP_START_MIN 0 +#define PID_KP_START_MAX 999 +#define PID_TN_START_MIN 0 +#define PID_TN_START_MAX 999 +#define PID_KP_REGULAR_MIN 0 +#define PID_KP_REGULAR_MAX 999 +#define PID_TN_REGULAR_MIN 0 +#define PID_TN_REGULAR_MAX 999 +#define PID_TV_REGULAR_MIN 0 +#define PID_TV_REGULAR_MAX 999 +#define PID_I_MAX_REGULAR_MIN 0 +#define PID_I_MAX_REGULAR_MAX 999 +#define PID_KP_BD_MIN 0 +#define PID_KP_BD_MAX 999 +#define PID_TN_BD_MIN 0 +#define PID_TN_BD_MAX 999 +#define PID_TV_BD_MIN 0 +#define PID_TV_BD_MAX 999 +#define BREW_SETPOINT_MIN 20 +#define BREW_SETPOINT_MAX 110 +#define STEAM_SETPOINT_MIN 100 +#define STEAM_SETPOINT_MAX 140 +#define BREW_TEMP_OFFSET_MIN 0 +#define BREW_TEMP_OFFSET_MAX 20 +#define BREW_TIME_MIN 0 +#define BREW_TIME_MAX 180 +#define BREW_PID_DELAY_MIN 0 +#define BREW_PID_DELAY_MAX 60 +#define PRE_INFUSION_TIME_MIN 0 +#define PRE_INFUSION_TIME_MAX 60 +#define PRE_INFUSION_PAUSE_MIN 0 +#define PRE_INFUSION_PAUSE_MAX 60 +#define WEIGHTSETPOINT_MIN 0 +#define WEIGHTSETPOINT_MAX 500 +#define PID_KP_STEAM_MIN 0 +#define PID_KP_STEAM_MAX 500 +#define STANDBY_MODE_TIME_MIN 30 +#define STANDBY_MODE_TIME_MAX 120 +#define BACKFLUSH_CYCLES_MIN 2 +#define BACKFLUSH_CYCLES_MAX 20 +#define BACKFLUSH_FILL_TIME_MIN 5 +#define BACKFLUSH_FILL_TIME_MAX 20 +#define BACKFLUSH_FLUSH_TIME_MIN 5 +#define BACKFLUSH_FLUSH_TIME_MAX 20 +#define SHOT_TIMER_DISPLAY_DELAY_MIN 0 +#define SHOT_TIMER_DISPLAY_DELAY_MAX 60 diff --git a/src/display/displayCommon.h b/src/display/displayCommon.h index fe1f0c8a..464111c7 100644 --- a/src/display/displayCommon.h +++ b/src/display/displayCommon.h @@ -237,11 +237,11 @@ void displayLogo(String displaymessagetext, String displaymessagetext2) { * @brief display shot and flush timer */ bool displayShottimer() { - if (FEATURE_SHOTTIMER == 0) { + if (featureShotTimer == 0) { return false; } - if (machineState == kBrew || (millis() - lastBrewTimeMillis) < SHOTTIMERDISPLAYDELAY || machineState == kManualFlush) { + if (machineState == kBrew || (millis() - lastBrewTimeMillis) < (shotTimerDisplayDelay * 1000) || machineState == kManualFlush) { u8g2.clearBuffer(); if (machineState != kManualFlush) { @@ -277,7 +277,7 @@ bool displayShottimer() { */ bool displayMachineState() { // Show the heating logo when we are in regular PID mode and more than 5degC below the set point - if (FEATURE_HEATINGLOGO > 0 && machineState == kPidNormal && (setpoint - temperature) > 5.) { + if (featureHeatingLogo > 0 && machineState == kPidNormal && (setpoint - temperature) > 5.) { // For status info u8g2.clearBuffer(); @@ -293,7 +293,7 @@ bool displayMachineState() { return true; } // Offline logo - else if (FEATURE_PIDOFF_LOGO == 1 && machineState == kPidDisabled) { + else if (featurePidOffLogo == 1 && machineState == kPidDisabled) { u8g2.clearBuffer(); u8g2.drawXBMP(38, 0, Off_Logo_width, Off_Logo_height, Off_Logo); u8g2.setCursor(0, 55); @@ -303,7 +303,7 @@ bool displayMachineState() { u8g2.sendBuffer(); return true; } - else if (FEATURE_PIDOFF_LOGO == 1 && machineState == kStandby) { + else if (featurePidOffLogo == 1 && machineState == kStandby) { u8g2.clearBuffer(); u8g2.drawXBMP(38, 0, Off_Logo_width, Off_Logo_height, Off_Logo); u8g2.setCursor(36, 55); diff --git a/src/display/displayRotateUpright.h b/src/display/displayRotateUpright.h index 7caa85c7..1f2e6e2f 100644 --- a/src/display/displayRotateUpright.h +++ b/src/display/displayRotateUpright.h @@ -88,7 +88,7 @@ void displayEmergencyStop(void) { * @brief display shot timer */ bool displayShottimer() { - if (((timeBrewed > 0 && featureBrewControl == 0) || (featureBrewControl > 0 && currBrewState > kBrewIdle && currBrewState <= kBrewFinished)) && FEATURE_SHOTTIMER == 1) { + if (((timeBrewed > 0 && featureBrewControl == 0) || (featureBrewControl > 0 && currBrewState > kBrewIdle && currBrewState <= kBrewFinished)) && featureShotTimer == 1) { u8g2.clearBuffer(); // draw temp icon @@ -100,8 +100,8 @@ bool displayShottimer() { u8g2.sendBuffer(); return true; } - else if (FEATURE_SHOTTIMER == 1 && millis() >= lastBrewTimeMillis && // directly after creating lastbrewTimeMillis (happens when turning off the brew switch, case 43 in the code) should be started - lastBrewTimeMillis + SHOTTIMERDISPLAYDELAY >= millis() && // should run until millis() has caught up with SHOTTIMERDISPLAYDELAY, this can be used to control the display duration + else if (featureShotTimer == 1 && millis() >= lastBrewTimeMillis && // directly after creating lastbrewTimeMillis (happens when turning off the brew switch, case 43 in the code) should be started + lastBrewTimeMillis + (shotTimerDisplayDelay * 1000) >= millis() && // should run until millis() has caught up with shotTimerDisplayDelay, this can be used to control the display duration lastBrewTimeMillis < totalBrewTime) // if the totalBrewTime is reached automatically, nothing should be done, otherwise wrong time will be displayed because switch is pressed later than totalBrewTime { u8g2.clearBuffer(); diff --git a/src/display/displayTemplateMinimal.h b/src/display/displayTemplateMinimal.h index de8063b0..3deb69de 100644 --- a/src/display/displayTemplateMinimal.h +++ b/src/display/displayTemplateMinimal.h @@ -81,8 +81,8 @@ void printScreen() { // Brew time #if (FEATURE_BREWSWITCH == 1) if (featureBrewControl) { - // Shown brew time while machine is brewing and after the brewing during SHOTTIMERDISPLAYDELAY - if (machineState == kBrew || (millis() - lastBrewTimeMillis) < SHOTTIMERDISPLAYDELAY) { + // Shown brew time while machine is brewing and after the brewing during shotTimerDisplayDelay + if (machineState == kBrew || (millis() - lastBrewTimeMillis) < (shotTimerDisplayDelay * 1000)) { u8g2.setCursor(34, 44); u8g2.print(langstring_brew); u8g2.print(timeBrewed / 1000, 0); @@ -105,8 +105,8 @@ void printScreen() { // Brew Timer with optocoupler else { - // Shown brew time while machine is brewing and after the brewing during SHOTTIMERDISPLAYDELAY - if (machineState == kBrew || (millis() - lastBrewTimeMillis) < SHOTTIMERDISPLAYDELAY) { + // Shown brew time while machine is brewing and after the brewing during shotTimerDisplayDelay + if (machineState == kBrew || (millis() - lastBrewTimeMillis) < (shotTimerDisplayDelay * 1000)) { u8g2.setCursor(34, 44); u8g2.print(langstring_brew); u8g2.print(timeBrewed / 1000, 0); diff --git a/src/display/displayTemplateStandard.h b/src/display/displayTemplateStandard.h index bf837555..1de76622 100644 --- a/src/display/displayTemplateStandard.h +++ b/src/display/displayTemplateStandard.h @@ -63,8 +63,8 @@ void printScreen() { #if (FEATURE_BREWSWITCH == 1) if (featureBrewControl) { - // Shown brew time while machine is brewing and after the brewing during SHOTTIMERDISPLAYDELAY - if (machineState == kBrew || (millis() - lastBrewTimeMillis) < SHOTTIMERDISPLAYDELAY) { + // Shown brew time while machine is brewing and after the brewing during shotTimerDisplayDelay + if (machineState == kBrew || (millis() - lastBrewTimeMillis) < (shotTimerDisplayDelay * 1000)) { u8g2.setFontMode(1); u8g2.setCursor(34, 36); u8g2.print(langstring_brew); @@ -92,8 +92,8 @@ void printScreen() { else { // Brew Timer with optocoupler - // Shown brew time while machine is brewing and after the brewing during SHOTTIMERDISPLAYDELAY - if (machineState == kBrew || (millis() - lastBrewTimeMillis) < SHOTTIMERDISPLAYDELAY) { + // Shown brew time while machine is brewing and after the brewing during shotTimerDisplayDelay + if (machineState == kBrew || (millis() - lastBrewTimeMillis) < (shotTimerDisplayDelay * 1000)) { u8g2.setCursor(34, 36); u8g2.print(langstring_brew); u8g2.setCursor(84, 36); diff --git a/src/embeddedWebserver.h b/src/embeddedWebserver.h index 3690977b..e9f87ff0 100644 --- a/src/embeddedWebserver.h +++ b/src/embeddedWebserver.h @@ -58,7 +58,7 @@ void serverSetup(); void setEepromWriteFcn(int (*fcnPtr)(void)); // editable vars are specified in main.cpp -#define EDITABLE_VARS_LEN 37 +#define EDITABLE_VARS_LEN 41 extern std::map editableVars; // EEPROM diff --git a/src/main.cpp b/src/main.cpp index c8df9cd6..d06d0d68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,6 +104,10 @@ const boolean ota = OTA; // Display uint8_t oled_i2c = OLED_I2C; +uint8_t featureShotTimer = FEATURE_SHOT_TIMER; +double shotTimerDisplayDelay = SHOT_TIMER_DISPLAY_DELAY; +uint8_t featureHeatingLogo = FEATURE_HEATING_LOGO; +uint8_t featurePidOffLogo = FEATURE_PID_OFF_LOGO; // WiFi uint8_t wifiCredentialsSaved = 0; @@ -269,6 +273,10 @@ SysPara sysParaBackflushCycles(&backflushCycles, BACKFLUSH_CYCLES_MIN, BACK SysPara sysParaBackflushFillTime(&backflushFillTime, BACKFLUSH_FILL_TIME_MIN, BACKFLUSH_FILL_TIME_MAX, STO_ITEM_BACKFLUSH_FILL_TIME); SysPara sysParaBackflushFlushTime(&backflushFlushTime, BACKFLUSH_FLUSH_TIME_MIN, BACKFLUSH_FLUSH_TIME_MAX, STO_ITEM_BACKFLUSH_FLUSH_TIME); SysPara sysParaFeatureBrewControl(&featureBrewControl, 0, 1, STO_ITEM_FEATURE_BREW_CONTROL); +SysPara sysParaFeatureShotTimer(&featureShotTimer, 0, 1, STO_ITEM_FEATURE_SHOT_TIMER); +SysPara sysParaShotTimerDisplayDelay(&shotTimerDisplayDelay, SHOT_TIMER_DISPLAY_DELAY_MIN, SHOT_TIMER_DISPLAY_DELAY_MAX, STO_ITEM_SHOT_TIMER_DISPLAY_DELAY); +SysPara sysParaFeatureHeatingLogo(&featureHeatingLogo, 0, 1, STO_ITEM_FEATURE_HEATING_LOGO); +SysPara sysParaFeaturePidOffLogo(&featurePidOffLogo, 0, 1, STO_ITEM_FEATURE_PID_OFF_LOGO); // Other variables boolean emergencyStop = false; // Emergency stop if temperature is too high @@ -297,6 +305,7 @@ enum SectionNames { sBDSection, sBrewSection, sScaleSection, + sDisplaySection, sPowerSection, sOtherSection }; @@ -1245,7 +1254,7 @@ void setup() { editableVars["STANDBY_MODE_TIMER"] = {.displayName = F("Standby Time"), .hasHelpText = true, - .helpText = F("Time in minutes until the heater is turned off. Timer is reset by brew detection."), + .helpText = F("Time in minutes until the heater is turned off. Timer is reset by brew, manual flush, backflush and steam."), .type = kDouble, .section = sPowerSection, .position = 30, @@ -1254,7 +1263,7 @@ void setup() { .maxValue = STANDBY_MODE_TIME_MAX, .ptr = (void*)&standbyModeTime}; - editableVars["BREWCONTROL"] = {.displayName = F("Brew Control"), + editableVars["BREWCONTROL"] = {.displayName = F("Enable Brew Control"), .hasHelpText = true, .helpText = F("Enables brew-by-time or brew-by-weight"), .type = kUInt8, @@ -1314,8 +1323,51 @@ void setup() { .ptr = (void*)&scale2Calibration}; #endif + editableVars["SHOT_TIMER"] = {.displayName = F("Enable Shot Timer"), + .hasHelpText = true, + .helpText = "Enables a full screen shot and flush timer", + .type = kUInt8, + .section = sDisplaySection, + .position = 37, + .show = [] { return true; }, + .minValue = 0, + .maxValue = 1, + .ptr = (void*)&featureShotTimer}; + + editableVars["SHOT_TIMER_DISPLAY_DELAY"] = {.displayName = F("Shot Timer Display Delay (s)"), + .hasHelpText = true, + .helpText = "time in ms that shot timer will be shown after brew finished", + .type = kDouble, + .section = sDisplaySection, + .position = 38, + .show = [] { return true; }, + .minValue = SHOT_TIMER_DISPLAY_DELAY_MIN, + .maxValue = SHOT_TIMER_DISPLAY_DELAY_MAX, + .ptr = (void*)&shotTimerDisplayDelay}; + + editableVars["HEATING_LOGO"] = {.displayName = F("Enable Heating Logo"), + .hasHelpText = true, + .helpText = "full screen logo will be shown if temperature is 5°C below setpoint", + .type = kUInt8, + .section = sDisplaySection, + .position = 39, + .show = [] { return true; }, + .minValue = 0, + .maxValue = 1, + .ptr = (void*)&featureHeatingLogo}; + + editableVars["PID_OFF_LOGO"] = {.displayName = F("Enable ´PID Disabled´ Logo"), + .hasHelpText = true, + .helpText = "full screen logo will be shown if pid is disabled", + .type = kUInt8, + .section = sDisplaySection, + .position = 40, + .show = [] { return true; }, + .minValue = 0, + .maxValue = 1, + .ptr = (void*)&featurePidOffLogo}; editableVars["VERSION"] = { - .displayName = F("Version"), .hasHelpText = false, .helpText = "", .type = kCString, .section = sOtherSection, .position = 37, .show = [] { return false; }, .minValue = 0, .maxValue = 1, .ptr = (void*)sysVersion}; + .displayName = F("Version"), .hasHelpText = false, .helpText = "", .type = kCString, .section = sOtherSection, .position = 41, .show = [] { return false; }, .minValue = 0, .maxValue = 1, .ptr = (void*)sysVersion}; // when adding parameters, set EDITABLE_VARS_LEN to max of .position #if (FEATURE_PRESSURESENSOR == 1) @@ -1857,6 +1909,10 @@ int readSysParamsFromStorage(void) { if (sysParaBackflushFillTime.getStorage() != 0) return -1; if (sysParaBackflushFlushTime.getStorage() != 0) return -1; if (sysParaFeatureBrewControl.getStorage() != 0) return -1; + if (sysParaFeatureShotTimer.getStorage() != 0) return -1; + if (sysParaShotTimerDisplayDelay.getStorage() != 0) return -1; + if (sysParaFeatureHeatingLogo.getStorage() != 0) return -1; + if (sysParaFeaturePidOffLogo.getStorage() != 0) return -1; return 0; } @@ -1898,6 +1954,10 @@ int writeSysParamsToStorage(void) { if (sysParaBackflushFillTime.setStorage() != 0) return -1; if (sysParaBackflushFlushTime.setStorage() != 0) return -1; if (sysParaFeatureBrewControl.setStorage() != 0) return -1; + if (sysParaFeatureShotTimer.setStorage() != 0) return -1; + if (sysParaShotTimerDisplayDelay.setStorage() != 0) return -1; + if (sysParaFeatureHeatingLogo.setStorage() != 0) return -1; + if (sysParaFeaturePidOffLogo.setStorage() != 0) return -1; return storageCommit(); } diff --git a/src/storage.h b/src/storage.h index 0f613deb..9bf4688e 100644 --- a/src/storage.h +++ b/src/storage.h @@ -45,6 +45,10 @@ typedef enum { STO_ITEM_BACKFLUSH_FILL_TIME, // time in ms the pump is running during backflush STO_ITEM_BACKFLUSH_FLUSH_TIME, // time in ms the 3-way valve is open during backflush STO_ITEM_FEATURE_BREW_CONTROL, // enables function to control pump and solenoid valve + STO_ITEM_FEATURE_SHOT_TIMER, // enables full screen shot timer + STO_ITEM_SHOT_TIMER_DISPLAY_DELAY, // time in ms that shot timer will be shown after brew finished + STO_ITEM_FEATURE_HEATING_LOGO, // enables full screen logo if mashine is heating + STO_ITEM_FEATURE_PID_OFF_LOGO, // enables full screen logo if pid is switched off /* WHEN ADDING NEW ITEMS, THE FOLLOWING HAS TO BE UPDATED: * - storage structure: sto_data_t @@ -116,6 +120,10 @@ typedef struct __attribute__((packed)) { double backflushFillTimeMs; double backflushFlushTimeMs; uint8_t featureBrewControl; + uint8_t featureShotTimer; + double shotTimerDisplayDelay; + uint8_t featureHeatingLogo; + uint8_t featurePidOffLogo; } sto_data_t; @@ -168,6 +176,10 @@ static const sto_data_t itemDefaults PROGMEM = { BACKFLUSH_FILL_TIME, // STO_ITEM_BACKFLUSH_FILLTIME BACKFLUSH_FLUSH_TIME, // STO_ITEM_BACKFLUSH_FLUSHTIME FEATURE_BREW_CONTROL, // STO_ITEM_FEATURE_BREW_CONTROL + FEATURE_SHOT_TIMER, // STO_ITEM_FEATURE_SHOT_TIMER + SHOT_TIMER_DISPLAY_DELAY, // STO_ITEM_SHOT_TIMER_DISPLAY_DELAY + FEATURE_HEATING_LOGO, // STO_ITEM_FEATURE_HEATING_LOGO + FEATURE_PID_OFF_LOGO, // STO_ITEM_FEATURE_PID_OFF_LOGO }; /** @@ -355,6 +367,26 @@ static inline int32_t getItemAddr(sto_item_id_t itemId, uint16_t* maxItemSize = size = STRUCT_MEMBER_SIZE(sto_data_t, featureBrewControl); break; + case STO_ITEM_FEATURE_SHOT_TIMER: + addr = offsetof(sto_data_t, featureShotTimer); + size = STRUCT_MEMBER_SIZE(sto_data_t, featureShotTimer); + break; + + case STO_ITEM_SHOT_TIMER_DISPLAY_DELAY: + addr = offsetof(sto_data_t, shotTimerDisplayDelay); + size = STRUCT_MEMBER_SIZE(sto_data_t, shotTimerDisplayDelay); + break; + + case STO_ITEM_FEATURE_HEATING_LOGO: + addr = offsetof(sto_data_t, featureHeatingLogo); + size = STRUCT_MEMBER_SIZE(sto_data_t, featureHeatingLogo); + break; + + case STO_ITEM_FEATURE_PID_OFF_LOGO: + addr = offsetof(sto_data_t, featurePidOffLogo); + size = STRUCT_MEMBER_SIZE(sto_data_t, featurePidOffLogo); + break; + default: LOGF(ERROR, "invalid item ID %i!", itemId); addr = -1; diff --git a/src/userConfig_sample.h b/src/userConfig_sample.h index 657e7c8e..07b800a9 100644 --- a/src/userConfig_sample.h +++ b/src/userConfig_sample.h @@ -29,18 +29,14 @@ enum MACHINE { #define MACHINEID RancilioSilvia // Machine type (see enum MACHINE) // Display -#define OLED_DISPLAY 2 // 0 = deactivated, 1 = SH1106 (e.g. 1.3 "128x64), 2 = SSD1306 (e.g. 0.96" 128x64), 3 = SH1106_126x64_SPI -#define OLED_I2C 0x3C // I2C address for OLED, 0x3C by default -#define DISPLAYTEMPLATE 3 // 1 = Standard display template, 2 = Minimal template, 3 = only temperature, 4 = scale template, 20 = vertical display (see git Handbook for further information) -#define DISPLAYROTATE U8G2_R0 // rotate display clockwise: U8G2_R0 = no rotation; U8G2_R1 = 90°; U8G2_R2 = 180°; U8G2_R3 = 270° -#define SCREEN_WIDTH 128 // OLED display width, in pixels -#define SCREEN_HEIGHT 64 // OLED display height, in pixels -#define FEATURE_SHOTTIMER 1 // 0 = deactivated, 1 = activated (with weight if FEATURE_SCALE activated) -#define FEATURE_HEATINGLOGO 1 // 0 = deactivated, 1 = activated -#define FEATURE_PIDOFF_LOGO 1 // 0 = deactivated, 1 = activated -#define SHOTTIMERDISPLAYDELAY 3000 // time in ms that shot timer will be shown after brew finished - -#define LANGUAGE 0 // LANGUAGE = 0 (DE), LANGUAGE = 1 (EN), LANGUAGE = 2 (ES) +#define OLED_DISPLAY 2 // 0 = deactivated, 1 = SH1106 (e.g. 1.3 "128x64), 2 = SSD1306 (e.g. 0.96" 128x64), 3 = SH1106_126x64_SPI +#define OLED_I2C 0x3C // I2C address for OLED, 0x3C by default +#define DISPLAYTEMPLATE 3 // 1 = Standard display template, 2 = Minimal template, 3 = only temperature, 4 = scale template, 20 = vertical display (see git Handbook for further information) +#define DISPLAYROTATE U8G2_R0 // rotate display clockwise: U8G2_R0 = no rotation; U8G2_R1 = 90°; U8G2_R2 = 180°; U8G2_R3 = 270° +#define SCREEN_WIDTH 128 // OLED display width, in pixels +#define SCREEN_HEIGHT 64 // OLED display height, in pixels + +#define LANGUAGE 0 // LANGUAGE = 0 (DE), LANGUAGE = 1 (EN), LANGUAGE = 2 (ES) // Connectivity #define CONNECTMODE 1 // 0 = offline 1 = WIFI-MODE