diff --git a/src/mode.cpp b/src/mode.cpp
index b82ea1e..0159156 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -11,6 +11,7 @@
#include "display.h"
#include "mode/Power/Power.h"
#include "mode/Energy/Energy.h"
+#include "mode/Timer/Timer.h"
ModeId currentModeId = NONE;
@@ -119,6 +120,9 @@ void loadNewMode() {
case ENERGY:
mode = new Energy(display);
break;
+ case TIMER:
+ mode = new Timer2(display);
+ break;
default:
Serial.print("No mode loaded.\n");
display.clear();
diff --git a/src/mode/Mode.h b/src/mode/Mode.h
index 9536657..8ae8ca3 100644
--- a/src/mode/Mode.h
+++ b/src/mode/Mode.h
@@ -26,12 +26,11 @@ enum ModeId {
MATRIX,
POWER,
ENERGY,
+ TIMER,
};
class Mode {
-private:
-
struct Timer {
microseconds_t interval;
microseconds_t rest;
diff --git a/src/mode/Timer/Timer.h b/src/mode/Timer/Timer.h
new file mode 100644
index 0000000..7af69a3
--- /dev/null
+++ b/src/mode/Timer/Timer.h
@@ -0,0 +1,115 @@
+#ifndef MODE_TIMER_H
+#define MODE_TIMER_H
+
+#include "mode/Mode.h"
+
+class Timer2 final : public Mode {
+
+ const unsigned long targetMillis = millis() + 6 * 60 * 1000;
+
+ uint16_t days = 0;
+
+ uint16_t hours = 0;
+
+ uint16_t minutes = 0;
+
+ uint16_t seconds = 0;
+
+ unsigned long diffSeconds = 0;
+
+public:
+
+ explicit Timer2(Display& display) : Mode(display) {
+ //
+ }
+
+ const char *getName() override {
+ return "Timer";
+ }
+
+protected:
+
+ void step(microseconds_t microseconds) override {
+ const auto now = millis();
+ diffSeconds = now >= targetMillis ? 0 : (targetMillis - now) / 1000;
+ days = diffSeconds / (24 * 60 * 60);
+ hours = diffSeconds / (60 * 60) % 24;
+ minutes = diffSeconds / 60 % 60;
+ seconds = diffSeconds % 60;
+ markDirty();
+ }
+
+ void draw(Display& display) override {
+ display.clear();
+
+ if (diffSeconds == 0) {
+ drawNoTime(display);
+ return;
+ }
+
+ uint8_t x = 0;
+ if (days > 0) {
+ drawDay(display, days, &x);
+ x += display.print(x, 1, 10, WHITE, true);
+ } else {
+ x += 2;
+ }
+ drawHour(display, days, hours, &x);
+ x += display.print(x, 1, 10, WHITE, true);
+ draw2Digit(display, minutes, &x);
+ if (days <= 0) {
+ x += display.print(x, 1, 10, WHITE, true);
+ draw2Digit(display, seconds, &x);
+ }
+ }
+
+private:
+
+ static void drawNoTime(Display& display) {
+ uint8_t x = 2;
+ x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
+ x++;
+ x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
+ x += display.print(x, 1, 10, WHITE, true);
+ x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
+ x++;
+ x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
+ x += display.print(x, 1, 10, WHITE, true);
+ x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
+ x++;
+ display.print(x, 1, SYMBOL_DASH, WHITE, true);
+ }
+
+ static void drawDay(Display& display, int days, uint8_t *x) {
+ if (days >= 100) {
+ *x += display.print(*x, 1, days / 100, WHITE, true) + 1;
+ } else {
+ *x += DISPLAY_CHAR_WIDTH + 1;
+ }
+
+ if (days >= 10) {
+ *x += display.print(*x, 1, days / 10 % 10, WHITE, true) + 1;
+ } else {
+ *x += DISPLAY_CHAR_WIDTH + 1;
+ }
+
+ *x += display.print(*x, 1, days % 10, WHITE, true);
+ }
+
+ static void drawHour(Display& display, int days, int hours, uint8_t *x) {
+ if (days > 0 || hours >= 10) {
+ *x += display.print(*x, 1, hours / 10, WHITE, true) + 1;
+ } else {
+ *x += DISPLAY_CHAR_WIDTH + 1;
+ }
+ *x += display.print(*x, 1, hours % 10, WHITE, true);
+ }
+
+ static void draw2Digit(Display& display, int value, uint8_t *x) {
+ *x += display.print(*x, 1, value / 10, WHITE, true) + 1;
+ *x += display.print(*x, 1, value % 10, WHITE, true);
+ }
+
+};
+
+#endif
diff --git a/src/server.cpp b/src/server.cpp
index 506a536..66548e0 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -114,6 +114,7 @@ void web_index() {
server.sendContent(R"(MATRIX
)");
server.sendContent(R"(POWER
)");
server.sendContent(R"(ENERGY
)");
+ server.sendContent(R"(TIMER
)");
server.sendContent(R"(
)");