diff --git a/platformio.ini b/platformio.ini
index 6f1a522e..8dc3cc4b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -2,17 +2,22 @@
lib_dir = lib
src_dir = src
extra_configs = platformio_extra.ini
+default_envs = esp32_usb
[env]
platform = espressif32 @^6.5.0
-board = az-delivery-devkit-v4
+#board = az-delivery-devkit-v4
+board = esp32dev
board_build.filesystem = littlefs
board_build.partitions = partitions_4M.csv
framework = arduino
monitor_speed = 115200
check_tool = clangtidy
check_skip_packages = yes
+build_flags =
+ ${env:TFT_eSPI.build_flags}
lib_deps =
+ ${env:TFT_eSPI.lib_deps}
lebuni/ZACwire for TSic @ 2.0.0
milesburton/DallasTemperature @ 3.11.0
paulstoffregen/OneWire @ 2.3.8
@@ -28,6 +33,32 @@ extra_scripts =
pre:auto_firmware_version.py
pre:run_clangformat.py
+[env:TFT_eSPI]
+build_flags =
+ -DUSER_SETUP_LOADED=1
+ -DST7789_DRIVER=1
+ -DTFT_WIDTH=240
+ -DTFT_HEIGHT=240
+ -DTFT_MOSI=23
+ -DTFT_SCLK=18
+ -DTFT_CS=-1
+ -DTFT_DC=27
+ -DTFT_RST=33
+ -DLOAD_GLCD=1
+ -DLOAD_FONT2=1
+ -DLOAD_FONT4=1
+ -DLOAD_FONT6=1
+ -DLOAD_FONT7=1
+ -DLOAD_FONT8=1
+ -DLOAD_GFXFF=1
+ -DSMOOTH_FONT=1
+ -DSPI_FREQUENCY=40000000
+ -DSPI_READ_FREQUENCY=20000000
+ -DSPI_TOUCH_FREQUENCY=2500000
+lib_deps =
+ bodmer/TFT_eSPI
+ bodmer/TFT_eWidget
+
[env:esp32_usb]
monitor_filters = esp32_exception_decoder
debug_tool = esp-prog
diff --git a/src/display/DisplayBase.cpp b/src/display/DisplayBase.cpp
new file mode 100644
index 00000000..9fd92718
--- /dev/null
+++ b/src/display/DisplayBase.cpp
@@ -0,0 +1,43 @@
+#include "DisplayBase.h"
+#include "float.h"
+
+Viewport DisplayBase::getView(Area area) {
+ return areaMap[area];
+}
+
+void DisplayBase::clearView(Area area) {
+ Viewport view = getView(area);
+ clearRect(view.getUpperLeft().X, view.getUpperLeft().Y, view.getWidth(), view.getHeight());
+}
+
+void DisplayBase::drawImageCentered(Area area, int width, int height, const uint8_t *bitmap) {
+ Viewport view = getView(area);
+ int xDelta = (view.getWidth() - width) / 2;
+ drawImage(view.getUpperLeft().X + xDelta, view.getUpperLeft().Y, width, height, bitmap);
+}
+
+void DisplayBase::drawImageCentered(Area area, int width, int height, const uint16_t *bitmap) {
+ Viewport view = getView(area);
+ int xDelta = (view.getWidth() - width) / 2;
+ drawImage(view.getUpperLeft().X + xDelta, view.getUpperLeft().Y, width, height, bitmap);
+}
+
+void DisplayBase::printCentered(Area area, const char* line1) {
+ Viewport view = getView(area);
+ printCentered(line1, view.getUpperLeft().Y);
+}
+
+void DisplayBase::printCentered(Area area, const char* line1, const char* line2) {
+ Viewport view = getView(area);
+ printCentered(line1, line2, view.getUpperLeft().Y);
+}
+
+int DisplayBase::getDataDigits(float data) {
+ int dataDigits = 0;
+ if (data - 100 > -FLT_EPSILON) {
+ dataDigits = 3;
+ } else {
+ dataDigits = 2;
+ }
+ return dataDigits;
+}
diff --git a/src/display/DisplayBase.h b/src/display/DisplayBase.h
new file mode 100644
index 00000000..619dacc2
--- /dev/null
+++ b/src/display/DisplayBase.h
@@ -0,0 +1,77 @@
+#ifndef DISPLAY_BASE_H
+#define DISPLAY_BASE_H
+
+#include "IDisplay.h" // Include your interface header
+
+class DisplayBase : public IDisplay {
+public:
+ // To be implemented by derived classes
+ virtual void init(Rotation rotation) = 0;
+ virtual void clearBuffer() = 0;
+ virtual void setPowerSave(uint32_t is_enabled) = 0;
+ virtual void drawImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t* bitmap) = 0;
+ virtual void drawImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t* bitmap) = 0;
+ virtual void drawImage(uint16_t x, uint16_t y, tImage bitmap) = 0;
+ virtual void setFont(FontType fontType) = 0;
+ virtual void setCursor(int16_t x, int16_t y) = 0;
+ virtual void print(float data, int digits) = 0;
+ virtual void print(char c) = 0;
+ virtual void print(const char* c) = 0;
+ virtual void println(const String &s) = 0;
+ virtual void drawGlyph(uint8_t x, uint8_t y, uint8_t encoding) = 0;
+ virtual void sendBuffer() = 0;
+ virtual int getWidth() = 0;
+ virtual int getHeight() = 0;
+ virtual void clearRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0;
+
+ virtual void drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) = 0;
+ virtual void drawVLine(uint16_t x, uint16_t y, uint16_t h) = 0;
+ virtual void drawHLine(uint16_t x, uint16_t y, uint16_t w) = 0;
+ virtual void drawCircle(uint16_t x, uint16_t y, uint16_t rad) = 0;
+ virtual void drawDisc(uint16_t x, uint16_t y, uint16_t rad) = 0;
+ virtual void drawPixel(uint16_t x, uint16_t y) = 0;
+ virtual void drawFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0;
+
+ virtual void printCentered(const char* c, uint16_t y) = 0;
+ virtual void printCentered(const char* line1, const char* line2, uint16_t y) = 0;
+
+ virtual void printRightAligned(const char* c, uint16_t y) = 0;
+ virtual void printRightAligned(const char* c, uint16_t y, FontType font) = 0;
+ virtual void printRightAligned(float data, unsigned int digits, uint16_t y) = 0;
+ virtual void printTemperatures(float t1, float t2, bool steaming) = 0;
+ virtual void printBrewingInfo(unsigned long totalBrewTime, unsigned long brewTimer, unsigned int activeBrewTimeEndDetection, bool scaleEnabled, int currentWeight, float activeScaleSensorWeightSetPoint) = 0;
+ virtual void printCountdown(unsigned int timer) = 0;
+
+ virtual void fillView(Area view, uint32_t color) = 0;
+ virtual void drawBorder(Area view) = 0;
+
+ // implemented by baseclass, probably we could move more methods there
+ virtual int getDataDigits(float data);
+ virtual Viewport getView(Area area);
+ virtual void clearView(Area area);
+ virtual void drawImageCentered(Area area, int width, int height, const uint8_t *bitmap);
+ virtual void drawImageCentered(Area area, int width, int height, const uint16_t *bitmap);
+ virtual void printCentered(Area area, const char* line1);
+ virtual void printCentered(Area area, const char* line1, const char* line2);
+
+protected:
+ virtual void initViews() = 0;
+
+ std::map areaMap;
+
+ // Viewport bootLogo;
+ // Viewport bootMessage;
+ // Viewport actionImage;
+ // Viewport statusIcons;
+ // Viewport profileIcon;
+ // Viewport temperature;
+ // Viewport statusMessage;
+ // Viewport softwareUpdate;
+
+ Viewport statusbar;
+ Viewport progressbar;
+ Viewport temperature;
+ Viewport brewTime;
+};
+
+#endif // DISPLAY_BASE_H
diff --git a/src/display/DisplayHelper.cpp b/src/display/DisplayHelper.cpp
new file mode 100644
index 00000000..8df6a924
--- /dev/null
+++ b/src/display/DisplayHelper.cpp
@@ -0,0 +1,51 @@
+#include "DisplayHelper.h"
+
+DisplayHelper::DisplayHelper() {
+ currentProfileIcon = ProfileIcon::None;
+ currentActionImage = std::make_pair(false, StatusImage::None);
+
+ currentIconMap = {
+ {0, StatusIcon::None},
+ {1, StatusIcon::None},
+ {2, StatusIcon::None}
+ };
+}
+
+StatusIcon DisplayHelper::getStatusIconAtIndex(uint8_t index) {
+ return currentIconMap[index];
+}
+
+void DisplayHelper::setStatusIconAtIndex(uint8_t index, StatusIcon icon) {
+ currentIconMap[index] = icon;
+}
+
+ProfileIcon DisplayHelper::getCurrentProfileIcon() {
+ return currentProfileIcon;
+}
+
+void DisplayHelper::setCurrentProfileIcon(ProfileIcon icon) {
+ currentProfileIcon = icon;
+}
+
+StatusImage DisplayHelper::getCurrentActionImage(bool rotated) {
+ if (currentActionImage.first == rotated) {
+ return currentActionImage.second;
+ }
+ return StatusImage::None;
+}
+
+void DisplayHelper::setCurrentActionImage(StatusImage image, bool rotated) {
+ currentActionImage.first = rotated;
+ currentActionImage.second = image;
+}
+
+String DisplayHelper::StatusIconToString(StatusIcon icon) {
+ switch (icon) {
+ case StatusIcon::None: return "None";
+ case StatusIcon::Wifi_Not_Ok: return "Wifi_Not_Ok";
+ case StatusIcon::Mqtt_Not_Ok: return "Mqtt_Not_Ok";
+ case StatusIcon::Wifi_Ok: return "Wifi_Ok";
+ case StatusIcon::Mqtt_Ok: return "Mqtt_Ok";
+ default: return "Invalid value";
+ }
+}
diff --git a/src/display/DisplayHelper.h b/src/display/DisplayHelper.h
new file mode 100644
index 00000000..692648b0
--- /dev/null
+++ b/src/display/DisplayHelper.h
@@ -0,0 +1,31 @@
+#ifndef DISPLAY_HELPER_H
+#define DISPLAY_HELPER_H
+
+#include "status_images.h"
+#include "ImageDictionary.h"
+#include