- Implement ThermoproBLE class for handling BLE communication with ThermoPro BBQ thermometer. - Create ThermoproReading structure to hold thermometer data. - Develop Dashboard class for displaying thermometer readings and WiFi status on a TFT display. - Configure display settings and touch input handling. - Introduce SettingsManager for managing user settings stored in NVS. - Implement WiFiManager for handling WiFi connections and captive portal setup. - Add HTML interface for user to input WiFi credentials and ThermoPro MAC address. - Ensure proper state management for WiFi and BLE connections in the main application loop.
173 lines
5.6 KiB
C++
173 lines
5.6 KiB
C++
#include "Dashboard.hpp"
|
|
#include <WiFi.h>
|
|
#include <math.h>
|
|
|
|
namespace cyd {
|
|
|
|
Dashboard::Dashboard(CYD_Display& display, SettingsManager& settings, ThermoproBLE& bleClient)
|
|
: display_(display), settings_(settings), bleClient_(bleClient) {
|
|
}
|
|
|
|
void Dashboard::begin() {
|
|
display_.init();
|
|
display_.initBacklight();
|
|
display_.setRotation(0); // Portrait 240x320
|
|
display_.fillScreen(TFT_BLACK);
|
|
display_.setTextDatum(middle_center);
|
|
|
|
drawStatusBar_();
|
|
for (size_t i = 0; i < 4; ++i) {
|
|
int x = (i % 2) * 120;
|
|
int y = 40 + (i / 2) * 110;
|
|
drawProbeTile_(i, x, y, 120, 110);
|
|
}
|
|
drawFooter_("Touch here for settings");
|
|
}
|
|
|
|
void Dashboard::update(bool force) {
|
|
if (!force && millis() - lastUpdateMillis_ < 1000) {
|
|
return;
|
|
}
|
|
lastUpdateMillis_ = millis();
|
|
|
|
ThermoproReading reading = bleClient_.getReading();
|
|
char targetUnit = settings_.getUnit();
|
|
|
|
if (force || reading.connected != lastBleConnected_ || reading.battery != lastBattery_) {
|
|
lastBleConnected_ = reading.connected;
|
|
lastBattery_ = reading.battery;
|
|
drawStatusBar_();
|
|
}
|
|
|
|
for (size_t i = 0; i < 4; ++i) {
|
|
float raw = reading.rawTemperatures[i];
|
|
bool conn = isValidTemperature(raw);
|
|
float displayTemp = conn ? convertTemperature(raw, reading.deviceUnit, targetUnit) : -9999.0f;
|
|
|
|
if (force || conn != lastConnected_[i] || fabsf(displayTemp - lastTemps_[i]) > 0.05f) {
|
|
lastConnected_[i] = conn;
|
|
lastTemps_[i] = displayTemp;
|
|
int x = (i % 2) * 120;
|
|
int y = 40 + (i / 2) * 110;
|
|
drawProbeTile_(i, x, y, 120, 110);
|
|
}
|
|
}
|
|
|
|
String footer = "IP: " + WiFi.localIP().toString();
|
|
if (WiFi.status() != WL_CONNECTED) {
|
|
footer = "AP: CYD-ThermoPro-Setup";
|
|
}
|
|
drawFooter_(footer);
|
|
}
|
|
|
|
bool Dashboard::checkTouch() {
|
|
uint16_t x, y;
|
|
if (display_.getTouch(&x, &y)) {
|
|
// The footer area is at the bottom 40 px of the screen in portrait mode.
|
|
if (y > 280) {
|
|
// Debounce: consume all touch events for 300 ms.
|
|
unsigned long start = millis();
|
|
while (display_.getTouch(&x, &y) && millis() - start < 300) {
|
|
delay(10);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Dashboard::showMessage(const String& title, const String& line2, const String& line3) {
|
|
display_.fillScreen(TFT_BLACK);
|
|
display_.setTextColor(TFT_WHITE, TFT_BLACK);
|
|
display_.setTextDatum(top_center);
|
|
display_.setTextSize(2);
|
|
display_.drawString(title.c_str(), display_.width() / 2, 60);
|
|
|
|
display_.setTextSize(1);
|
|
if (line2.length()) {
|
|
display_.drawString(line2.c_str(), display_.width() / 2, 120);
|
|
}
|
|
if (line3.length()) {
|
|
display_.drawString(line3.c_str(), display_.width() / 2, 150);
|
|
}
|
|
display_.setTextDatum(middle_center); // restore default
|
|
}
|
|
|
|
void Dashboard::drawStatusBar_() {
|
|
int w = display_.width();
|
|
display_.fillRect(0, 0, w, 36, TFT_DARKGREY);
|
|
display_.drawLine(0, 36, w, 36, TFT_LIGHTGREY);
|
|
|
|
ThermoproReading reading = bleClient_.getReading();
|
|
|
|
// WiFi icon placeholder: small circle + text
|
|
display_.setTextColor(TFT_WHITE, TFT_DARKGREY);
|
|
display_.setTextDatum(middle_left);
|
|
display_.setTextSize(1);
|
|
display_.drawString("WiFi", 4, 18);
|
|
|
|
String wifiStatus = (WiFi.status() == WL_CONNECTED) ? "OK" : "--";
|
|
display_.drawString(wifiStatus.c_str(), 34, 18);
|
|
|
|
// BLE status
|
|
display_.setTextDatum(middle_right);
|
|
String ble = reading.connected ? "BLE OK" : "BLE --";
|
|
display_.drawString(ble.c_str(), w - 54, 18);
|
|
|
|
// Battery
|
|
String batt = String(reading.battery) + "%";
|
|
display_.drawString(batt.c_str(), w - 4, 18);
|
|
}
|
|
|
|
void Dashboard::drawProbeTile_(size_t index, int x, int y, int tileW, int tileH) {
|
|
ThermoproReading reading = bleClient_.getReading();
|
|
char targetUnit = settings_.getUnit();
|
|
float raw = reading.rawTemperatures[index];
|
|
bool connected = isValidTemperature(raw);
|
|
float temp = connected ? convertTemperature(raw, reading.deviceUnit, targetUnit) : -9999.0f;
|
|
|
|
// Background
|
|
uint16_t bgColor = (index % 2 == 0) ? TFT_DARKGREY : TFT_BLACK;
|
|
display_.fillRect(x + 1, y + 1, tileW - 2, tileH - 2, bgColor);
|
|
display_.drawRect(x, y, tileW, tileH, TFT_LIGHTGREY);
|
|
|
|
// Probe name
|
|
display_.setTextColor(TFT_WHITE, bgColor);
|
|
display_.setTextDatum(top_center);
|
|
display_.setTextSize(1);
|
|
display_.drawString(settings_.getProbeName(index).c_str(), x + tileW / 2, y + 8);
|
|
|
|
// Temperature
|
|
display_.setTextSize(2);
|
|
if (connected) {
|
|
String t = formatTemperature_(temp);
|
|
display_.drawString(t.c_str(), x + tileW / 2, y + tileH / 2 - 8);
|
|
display_.setTextSize(1);
|
|
display_.drawString((String("°") + targetUnit).c_str(), x + tileW / 2, y + tileH / 2 + 22);
|
|
} else {
|
|
display_.setTextColor(TFT_LIGHTGREY, bgColor);
|
|
display_.drawString("---", x + tileW / 2, y + tileH / 2);
|
|
}
|
|
|
|
// Connection dot
|
|
display_.fillCircle(x + tileW - 12, y + 12, 4, connected ? TFT_GREEN : TFT_RED);
|
|
}
|
|
|
|
void Dashboard::drawFooter_(const String& message) {
|
|
int y = display_.height() - 40;
|
|
display_.fillRect(0, y, display_.width(), 40, TFT_NAVY);
|
|
display_.drawLine(0, y, display_.width(), y, TFT_LIGHTGREY);
|
|
display_.setTextColor(TFT_WHITE, TFT_NAVY);
|
|
display_.setTextDatum(middle_center);
|
|
display_.setTextSize(1);
|
|
display_.drawString(message.c_str(), display_.width() / 2, y + 20);
|
|
}
|
|
|
|
String Dashboard::formatTemperature_(float temp) {
|
|
char buf[12];
|
|
snprintf(buf, sizeof(buf), "%.1f", temp);
|
|
return String(buf);
|
|
}
|
|
|
|
} // namespace cyd
|