diff --git a/platformio.ini b/platformio.ini
index d0a3537..beee78b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -13,6 +13,7 @@ platform = espressif32
board = esp32dev
framework = arduino
lib_deps = https://github.com/adafruit/Adafruit_NeoPixel
+ https://github.com/knolleary/pubsubclient
build_flags =
upload_port = 10.0.0.116
upload_protocol = espota
diff --git a/src/display/Color.cpp b/src/display/Color.cpp
index 6176f7d..3be724d 100644
--- a/src/display/Color.cpp
+++ b/src/display/Color.cpp
@@ -8,6 +8,8 @@ const Color RED = {FULL, ____, ____};
const Color GREEN = {____, FULL, ____};
+const Color ORANGE = {FULL, HALF, ____};
+
const Color BLUE = {____, ____, FULL};
const Color YELLOW = {FULL, FULL, ____};
diff --git a/src/display/Color.h b/src/display/Color.h
index a44b4f8..280fe8b 100644
--- a/src/display/Color.h
+++ b/src/display/Color.h
@@ -21,6 +21,8 @@ extern const Color RED;
extern const Color GREEN;
+extern const Color ORANGE;
+
extern const Color BLUE;
extern const Color YELLOW;
diff --git a/src/display/Display.h b/src/display/Display.h
index f1c2ba5..2b4cb1f 100644
--- a/src/display/Display.h
+++ b/src/display/Display.h
@@ -6,6 +6,7 @@
#include "Vector.h"
#define SYMBOL_COUNT 15
+#define SYMBOL_DASH 13
#define DISPLAY_CHAR_WIDTH 3
#define DISPLAY_CHAR_HEIGHT 5
@@ -89,7 +90,10 @@ public:
memset(buffer, 0, pixelByteCount);
}
- uint8_t print(uint8_t xPos, uint8_t yPos, uint8_t index, Color color) {
+ uint8_t print(uint8_t xPos, uint8_t yPos, uint8_t index, Color color, bool showIfZero) {
+ if (index == 0 && !showIfZero) {
+ return DISPLAY_CHAR_WIDTH;
+ }
if (index >= SYMBOL_COUNT) {
Serial.printf("Cannot print symbol #%u.\n", index);
index = SYMBOL_COUNT - 1;
diff --git a/src/main.cpp b/src/main.cpp
index 2d03460..6ae0c79 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -6,6 +6,7 @@
#include "mode.h"
#include "display.h"
+#include "mqtt.h"
void setup() {
delay(500);
@@ -23,6 +24,7 @@ void setup() {
void loop() {
serial_loop();
wifi_loop();
+ mqtt_loop();
server_loop();
mode_loop();
config_loop();
diff --git a/src/mode.cpp b/src/mode.cpp
index 3b044ec..88e4a3c 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -9,6 +9,7 @@
#include "mode/Starfield/Starfield.h"
#include "mode/Matrix/Matrix.h"
#include "display.h"
+#include "mode/Electricity/Electricity.h"
ModeId currentModeId = NONE;
@@ -108,6 +109,9 @@ void loadNewMode() {
case MATRIX:
mode = new Matrix(display);
break;
+ case ELECTRICITY:
+ mode = new Electricity(display);
+ break;
default:
Serial.print("No mode loaded.\n");
display.clear();
diff --git a/src/mode/Clock/Clock.h b/src/mode/Clock/Clock.h
index 30b1587..ac9c18c 100644
--- a/src/mode/Clock/Clock.h
+++ b/src/mode/Clock/Clock.h
@@ -28,17 +28,17 @@ protected:
display.clear();
uint8_t x = 2;
- x += display.print(x, 1, realtimeOK ? now.tm_hour / 10 : 13, WHITE);
+ x += display.print(x, 1, realtimeOK ? now.tm_hour / 10 : SYMBOL_DASH, WHITE, true);
x++;
- x += display.print(x, 1, realtimeOK ? now.tm_hour % 10 : 13, WHITE);
- x += display.print(x, 1, 10, WHITE);
- x += display.print(x, 1, realtimeOK ? now.tm_min / 10 : 13, WHITE);
+ x += display.print(x, 1, realtimeOK ? now.tm_hour % 10 : SYMBOL_DASH, WHITE, true);
+ x += display.print(x, 1, 10, WHITE, true);
+ x += display.print(x, 1, realtimeOK ? now.tm_min / 10 : SYMBOL_DASH, WHITE, true);
x++;
- x += display.print(x, 1, realtimeOK ? now.tm_min % 10 : 13, WHITE);
- x += display.print(x, 1, 10, WHITE);
- x += display.print(x, 1, realtimeOK ? now.tm_sec / 10 : 13, WHITE);
+ x += display.print(x, 1, realtimeOK ? now.tm_min % 10 : SYMBOL_DASH, WHITE, true);
+ x += display.print(x, 1, 10, WHITE, true);
+ x += display.print(x, 1, realtimeOK ? now.tm_sec / 10 : SYMBOL_DASH, WHITE, true);
x++;
- x += display.print(x, 1, realtimeOK ? now.tm_sec % 10 : 13, WHITE);
+ x += display.print(x, 1, realtimeOK ? now.tm_sec % 10 : SYMBOL_DASH, WHITE, true);
}
};
diff --git a/src/mode/CountDown/CountDown.h b/src/mode/CountDown/CountDown.h
index 6f66e05..329b234 100644
--- a/src/mode/CountDown/CountDown.h
+++ b/src/mode/CountDown/CountDown.h
@@ -151,15 +151,15 @@ private:
uint8_t x = 0;
if (days > 0) {
drawDay(display, days, &x);
- x += display.print(x, 1, 10, WHITE);
+ x += display.print(x, 1, 10, WHITE, true);
} else {
x += 2;
}
drawHour(display, days, hours, &x);
- x += display.print(x, 1, 10, WHITE);
+ x += display.print(x, 1, 10, WHITE, true);
draw2Digit(display, minutes, &x);
if (days <= 0) {
- x += display.print(x, 1, 10, WHITE);
+ x += display.print(x, 1, 10, WHITE, true);
draw2Digit(display, seconds, &x);
drawSubSecondsBar(display);
} else {
@@ -169,51 +169,51 @@ private:
static void drawNoTime(Display &display) {
uint8_t x = 2;
- x += display.print(x, 1, 13, WHITE);
+ x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
x++;
- x += display.print(x, 1, 13, WHITE);
- x += display.print(x, 1, 10, WHITE);
- x += display.print(x, 1, 13, WHITE);
+ 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, 13, WHITE);
- x += display.print(x, 1, 10, WHITE);
- x += display.print(x, 1, 13, WHITE);
+ 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, 13, WHITE);
+ 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);
+ *x += display.print(*x, 1, days / 100, WHITE, true);
} else {
*x += 3;
}
(*x)++;
if (days >= 10) {
- *x += display.print(*x, 1, days / 10 % 10, WHITE);
+ *x += display.print(*x, 1, days / 10 % 10, WHITE, true);
} else {
*x += 3;
}
(*x)++;
- *x += display.print(*x, 1, days % 10, WHITE);
+ *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);
+ *x += display.print(*x, 1, hours / 10, WHITE, true);
} else {
*x += 3;
}
(*x)++;
- *x += display.print(*x, 1, hours % 10, WHITE);
+ *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);
+ *x += display.print(*x, 1, value / 10, WHITE, true);
(*x)++;
- *x += display.print(*x, 1, value % 10, WHITE);
+ *x += display.print(*x, 1, value % 10, WHITE, true);
}
static void drawSecondsBar(Display &display, int seconds) {
@@ -244,13 +244,13 @@ private:
static void drawYear(Display &display, int year) {
uint8_t x = 8;
- x += display.print(x, 1, year / 1000 % 10, WHITE);
+ x += display.print(x, 1, year / 1000 % 10, WHITE, true);
x++;
- x += display.print(x, 1, year / 100 % 10, WHITE);
+ x += display.print(x, 1, year / 100 % 10, WHITE, true);
x++;
- x += display.print(x, 1, year / 10 % 10, WHITE);
+ x += display.print(x, 1, year / 10 % 10, WHITE, true);
x++;
- x += display.print(x, 1, year / 1 % 10, WHITE);
+ x += display.print(x, 1, year / 1 % 10, WHITE, true);
}
};
diff --git a/src/mode/Electricity/Electricity.h b/src/mode/Electricity/Electricity.h
new file mode 100644
index 0000000..254f369
--- /dev/null
+++ b/src/mode/Electricity/Electricity.h
@@ -0,0 +1,67 @@
+#ifndef MODE_ELECTRICITY_H
+#define MODE_ELECTRICITY_H
+
+#include "mode/Mode.h"
+#include "mqtt.h"
+
+#pragma clang diagnostic push
+#pragma ide diagnostic ignored "UnusedValue"
+
+class Electricity : public Mode {
+
+public:
+
+ explicit Electricity(Display &display) :
+ Mode(display) {
+ // nothing
+ }
+
+ const char *getName() override {
+ return "Electricity";
+ }
+
+protected:
+
+ void step(microseconds_t microseconds) override {
+ if (realtimeChanged) {
+ markDirty();
+ }
+ }
+
+ void draw(Display &display) override {
+ display.clear();
+ uint8_t x = 0;
+
+ int pv = (int) round(getPhotovoltaicPowerW());
+ int pv100 = (pv / 100) % 10;
+ int pv10 = (pv / 10) % 10;
+ int pv1 = pv % 10;
+ Serial.printf("pv100=%d, pv10=%d, pv1=%d, pv=%f\n", pv100, pv10, pv1, getPhotovoltaicPowerW());
+ x += display.print(x, 1, isnan(pv) ? SYMBOL_DASH : pv100, GREEN, pv >= 100) + 1;
+ x += display.print(x, 1, isnan(pv) ? SYMBOL_DASH : pv10, GREEN, pv >= 10) + 1;
+ x += display.print(x, 1, isnan(pv) ? SYMBOL_DASH : pv1, GREEN, true) + 1;
+
+ x += 5;
+
+ int grid = (int) round(getGridPowerW());
+ Color color = ORANGE;
+ if (grid < 0) {
+ color = MAGENTA;
+ grid = -grid;
+ }
+ int grid1000 = (grid / 1000) % 10;
+ int grid100 = (grid / 100) % 10;
+ int grid10 = (grid / 10) % 10;
+ int grid1 = grid % 10;
+ Serial.printf("grid100=%d, grid10=%d, grid1=%d, grid=%f\n", grid100, grid10, grid1, getGridPowerW());
+ x += display.print(x, 1, isnan(grid) ? SYMBOL_DASH : grid1000, color, grid >= 1000) + 1;
+ x += display.print(x, 1, isnan(grid) ? SYMBOL_DASH : grid100, color, grid >= 100) + 1;
+ x += display.print(x, 1, isnan(grid) ? SYMBOL_DASH : grid10, color, grid >= 10) + 1;
+ x += display.print(x, 1, isnan(grid) ? SYMBOL_DASH : grid1, color, true) + 1;
+ }
+
+};
+
+#pragma clang diagnostic pop
+
+#endif
diff --git a/src/mode/Mode.h b/src/mode/Mode.h
index afa3049..c74ffe4 100644
--- a/src/mode/Mode.h
+++ b/src/mode/Mode.h
@@ -23,6 +23,7 @@ enum ModeId {
COUNT_DOWN_BARS,
STARFIELD,
MATRIX,
+ ELECTRICITY,
};
class Mode {
diff --git a/src/mode/Pong/Pong.h b/src/mode/Pong/Pong.h
index 3b30ff9..cae5325 100644
--- a/src/mode/Pong/Pong.h
+++ b/src/mode/Pong/Pong.h
@@ -97,8 +97,8 @@ protected:
display.clear();
switch (status) {
case SCORE:
- display.print(1, 1, player0.score, GREEN);
- display.print(width - 1 - DISPLAY_CHAR_WIDTH, 1, player1.score, RED);
+ display.print(1, 1, player0.score, GREEN, true);
+ display.print(width - 1 - DISPLAY_CHAR_WIDTH, 1, player1.score, RED, true);
break;
case PLAY:
for (int i = 0; i < player0.size; ++i) {
@@ -111,11 +111,11 @@ protected:
break;
case OVER:
if (player0.score > player1.score) {
- display.print(1, 1, 11, GREEN);
- display.print(width - 1 - DISPLAY_CHAR_WIDTH, 1, 12, RED);
+ display.print(1, 1, 11, GREEN, true);
+ display.print(width - 1 - DISPLAY_CHAR_WIDTH, 1, 12, RED, true);
} else if (player0.score < player1.score) {
- display.print(1, 1, 12, RED);
- display.print(width - 1 - DISPLAY_CHAR_WIDTH, 1, 11, GREEN);
+ display.print(1, 1, 12, RED, true);
+ display.print(width - 1 - DISPLAY_CHAR_WIDTH, 1, 11, GREEN, true);
}
break;
}
diff --git a/src/mqtt.cpp b/src/mqtt.cpp
new file mode 100644
index 0000000..2c2c085
--- /dev/null
+++ b/src/mqtt.cpp
@@ -0,0 +1,94 @@
+#include
)");
server.sendContent(R"(STARFIELD
)");
server.sendContent(R"(MATRIX
)");
+ server.sendContent(R"(ELECTRICITY
)");
server.sendContent(R"(
)");
diff --git a/src/wifi.cpp b/src/wifi.cpp
index 6f7708a..bb3fff1 100644
--- a/src/wifi.cpp
+++ b/src/wifi.cpp
@@ -1,13 +1,14 @@
#include "wifi.h"
#include "display.h"
+#include "mqtt.h"
#include