Change error status on display to icon

This commit is contained in:
samuelbles07
2025-03-24 03:52:46 +07:00
parent ea5e23b307
commit ef87cde9d6
5 changed files with 133 additions and 57 deletions

View File

@ -34,6 +34,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
#include "AgValue.h" #include "AgValue.h"
#include "AgWiFiConnector.h" #include "AgWiFiConnector.h"
#include "AirGradient.h" #include "AirGradient.h"
#include "App/AppDef.h"
#include "Arduino.h" #include "Arduino.h"
#include "EEPROM.h" #include "EEPROM.h"
#include "ESPmDNS.h" #include "ESPmDNS.h"
@ -1111,12 +1112,21 @@ static void updateDisplayAndLedBar(void) {
return; return;
} }
if (wifiConnector.isConnected() == false && networkOption == UseWifi) { if (networkOption == UseWifi) {
if (wifiConnector.isConnected() == false) {
stateMachine.displayHandle(AgStateMachineWiFiLost); stateMachine.displayHandle(AgStateMachineWiFiLost);
stateMachine.handleLeds(AgStateMachineWiFiLost); stateMachine.handleLeds(AgStateMachineWiFiLost);
return; return;
} }
// TODO: Also show for cellular connection problem }
else if (networkOption == UseCellular) {
if (agClient->isClientReady() == false) {
// Same action as wifi
stateMachine.displayHandle(AgStateMachineWiFiLost);
stateMachine.handleLeds(AgStateMachineWiFiLost);
return;
}
}
if (configuration.isCloudConnectionDisabled()) { if (configuration.isCloudConnectionDisabled()) {
// Ignore API related check since cloud is disabled // Ignore API related check since cloud is disabled

View File

@ -5,12 +5,31 @@
/** Cast U8G2 */ /** Cast U8G2 */
#define DISP() ((U8G2_SH1106_128X64_NONAME_F_HW_I2C *)(this->u8g2)) #define DISP() ((U8G2_SH1106_128X64_NONAME_F_HW_I2C *)(this->u8g2))
static const unsigned char wifi_issue_bits[] = {
0xd8, 0xc6, 0xde, 0xde, 0xc7, 0xf8, 0xd1, 0xe2, 0xdc, 0xce, 0xcc,
0xcc, 0xc0, 0xc0, 0xd0, 0xc2, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
static const unsigned char cloud_issue_bits[] = {
0x70, 0xc0, 0x88, 0xc0, 0x04, 0xc1, 0x04, 0xcf, 0x02, 0xd0, 0x01,
0xe0, 0x01, 0xe0, 0x01, 0xe0, 0xa2, 0xd0, 0x4c, 0xce, 0xa0, 0xc0};
// Offline mode icon
static unsigned char offline_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x62, 0x00,
0xE6, 0x00, 0xFE, 0x1F, 0xFE, 0x1F, 0xE6, 0x00, 0x62, 0x00,
0x30, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// {
// 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x62, 0x00, 0xE2, 0x00,
// 0xFE, 0x1F, 0xFE, 0x1F, 0xE2, 0x00, 0x62, 0x00, 0x60, 0x00, 0x30, 0x00,
// 0x00, 0x00, 0x00, 0x00, };
/** /**
* @brief Show dashboard temperature and humdity * @brief Show dashboard temperature and humdity
* *
* @param hasStatus * @param hasStatus
*/ */
void OledDisplay::showTempHum(bool hasStatus, char *buf, int buf_size) { void OledDisplay::showTempHum(bool hasStatus) {
char buf[10];
/** Temperature */ /** Temperature */
float temp = value.getCorrectedTempHum(Measurements::Temperature, 1); float temp = value.getCorrectedTempHum(Measurements::Temperature, 1);
if (utils::isValidTemperature(temp)) { if (utils::isValidTemperature(temp)) {
@ -23,22 +42,22 @@ void OledDisplay::showTempHum(bool hasStatus, char *buf, int buf_size) {
if (config.isTemperatureUnitInF()) { if (config.isTemperatureUnitInF()) {
if (hasStatus) { if (hasStatus) {
snprintf(buf, buf_size, "%0.1f", t); snprintf(buf, sizeof(buf), "%0.1f", t);
} else { } else {
snprintf(buf, buf_size, "%0.1f°F", t); snprintf(buf, sizeof(buf), "%0.1f°F", t);
} }
} else { } else {
if (hasStatus) { if (hasStatus) {
snprintf(buf, buf_size, "%.1f", t); snprintf(buf, sizeof(buf), "%.1f", t);
} else { } else {
snprintf(buf, buf_size, "%.1f°C", t); snprintf(buf, sizeof(buf), "%.1f°C", t);
} }
} }
} else { /** Show invalid value */ } else { /** Show invalid value */
if (config.isTemperatureUnitInF()) { if (config.isTemperatureUnitInF()) {
snprintf(buf, buf_size, "-°F"); snprintf(buf, sizeof(buf), "-°F");
} else { } else {
snprintf(buf, buf_size, "-°C"); snprintf(buf, sizeof(buf), "-°C");
} }
} }
DISP()->drawUTF8(1, 10, buf); DISP()->drawUTF8(1, 10, buf);
@ -46,9 +65,9 @@ void OledDisplay::showTempHum(bool hasStatus, char *buf, int buf_size) {
/** Show humidity */ /** Show humidity */
int rhum = round(value.getCorrectedTempHum(Measurements::Humidity, 1)); int rhum = round(value.getCorrectedTempHum(Measurements::Humidity, 1));
if (utils::isValidHumidity(rhum)) { if (utils::isValidHumidity(rhum)) {
snprintf(buf, buf_size, "%d%%", rhum); snprintf(buf, sizeof(buf), "%d%%", rhum);
} else { } else {
snprintf(buf, buf_size, "-%%"); snprintf(buf, sizeof(buf), "-%%");
} }
if (rhum > 99.0) { if (rhum > 99.0) {
@ -67,6 +86,9 @@ void OledDisplay::setCentralText(int y, const char *text) {
DISP()->drawStr(x, y, text); DISP()->drawStr(x, y, text);
} }
void OledDisplay::showIcon(int x, int y, xbm_icon_t *icon) {
DISP()->drawXBM(x, y, icon->width, icon->height, icon->icon);
}
/** /**
* @brief Construct a new Ag Oled Display:: Ag Oled Display object * @brief Construct a new Ag Oled Display:: Ag Oled Display object
* *
@ -252,36 +274,60 @@ void OledDisplay::setText(const char *line1, const char *line2,
* @brief Update dashboard content * @brief Update dashboard content
* *
*/ */
void OledDisplay::showDashboard(void) { showDashboard(NULL); } void OledDisplay::showDashboard(void) { showDashboard(DashBoardStatusNone); }
/** /**
* @brief Update dashboard content and error status * @brief Update dashboard content and error status
* *
*/ */
void OledDisplay::showDashboard(const char *status) { void OledDisplay::showDashboard(DashboardStatus status) {
if (isDisplayOff) { if (isDisplayOff) {
return; return;
} }
char strBuf[16]; char strBuf[16];
const int icon_pos_x = 64;
xbm_icon_t xbm_icon = {
.width = 0,
.height = 0,
.icon = nullptr,
};
if (ag->isOne() || ag->isPro3_3() || ag->isPro4_2()) { if (ag->isOne() || ag->isPro3_3() || ag->isPro4_2()) {
DISP()->firstPage(); DISP()->firstPage();
do { do {
DISP()->setFont(u8g2_font_t0_16_tf); DISP()->setFont(u8g2_font_t0_16_tf);
if ((status == NULL) || (strlen(status) == 0)) { switch (status) {
showTempHum(false, strBuf, sizeof(strBuf)); case DashBoardStatusNone: {
} else { // Maybe show signal strength?
String strStatus = "Show status: " + String(status); showTempHum(false);
logInfo(strStatus); break;
int strWidth = DISP()->getStrWidth(status);
DISP()->drawStr((DISP()->getWidth() - strWidth) / 2, 10, status);
/** Show WiFi NA*/
if (strcmp(status, "WiFi N/A") == 0) {
DISP()->setFont(u8g2_font_t0_12_tf);
showTempHum(true, strBuf, sizeof(strBuf));
} }
case DashBoardStatusWiFiIssue: {
DISP()->drawXBM(icon_pos_x, 0, 14, 11, wifi_issue_bits);
showTempHum(false);
break;
}
case DashBoardStatusServerIssue: {
DISP()->drawXBM(icon_pos_x, 0, 14, 11, cloud_issue_bits);
showTempHum(false);
break;
}
case DashBoardStatusAddToDashboard: {
setCentralText(10, "Add To Dashboard");
break;
}
case DashBoardStatusDeviceId: {
setCentralText(10, ag->deviceId().c_str());
break;
}
case DashBoardStatusOfflineMode: {
DISP()->drawXBM(icon_pos_x, 0, 14, 14, offline_bits);
showTempHum(false); // First true
break;
}
default:
break;
} }
/** Draw horizonal line */ /** Draw horizonal line */
@ -392,7 +438,8 @@ void OledDisplay::showDashboard(const char *status) {
float temp = value.getCorrectedTempHum(Measurements::Temperature, 1); float temp = value.getCorrectedTempHum(Measurements::Temperature, 1);
if (utils::isValidTemperature(temp)) { if (utils::isValidTemperature(temp)) {
if (config.isTemperatureUnitInF()) { if (config.isTemperatureUnitInF()) {
snprintf(strBuf, sizeof(strBuf), "T:%0.1f F", utils::degreeC_To_F(temp)); snprintf(strBuf, sizeof(strBuf), "T:%0.1f F",
utils::degreeC_To_F(temp));
} else { } else {
snprintf(strBuf, sizeof(strBuf), "T:%0.1f C", temp); snprintf(strBuf, sizeof(strBuf), "T:%0.1f C", temp);
} }
@ -442,8 +489,7 @@ void OledDisplay::setBrightness(int percent) {
// Clear display. // Clear display.
ag->display.clear(); ag->display.clear();
ag->display.show(); ag->display.show();
} } else {
else {
isDisplayOff = false; isDisplayOff = false;
ag->display.setContrast((255 * percent) / 100); ag->display.setContrast((255 * percent) / 100);
} }

View File

@ -16,15 +16,30 @@ private:
Measurements &value; Measurements &value;
bool isDisplayOff = false; bool isDisplayOff = false;
void showTempHum(bool hasStatus, char* buf, int buf_size); typedef struct {
int width;
int height;
unsigned char *icon;
} xbm_icon_t;
void showTempHum(bool hasStatus);
void setCentralText(int y, String text); void setCentralText(int y, String text);
void setCentralText(int y, const char *text); void setCentralText(int y, const char *text);
void showIcon(int x, int y, xbm_icon_t *icon);
public: public:
OledDisplay(Configuration &config, Measurements &value, OledDisplay(Configuration &config, Measurements &value, Stream &log);
Stream &log);
~OledDisplay(); ~OledDisplay();
enum DashboardStatus {
DashBoardStatusNone,
DashBoardStatusWiFiIssue,
DashBoardStatusServerIssue,
DashBoardStatusAddToDashboard,
DashBoardStatusDeviceId,
DashBoardStatusOfflineMode,
};
void setAirGradient(AirGradient *ag); void setAirGradient(AirGradient *ag);
bool begin(void); bool begin(void);
void end(void); void end(void);
@ -34,7 +49,7 @@ public:
void setText(const char *line1, const char *line2, const char *line3, void setText(const char *line1, const char *line2, const char *line3,
const char *line4); const char *line4);
void showDashboard(void); void showDashboard(void);
void showDashboard(const char *status); void showDashboard(DashboardStatus status);
void setBrightness(int percent); void setBrightness(int percent);
#ifdef ESP32 #ifdef ESP32
void showFirmwareUpdateVersion(String version); void showFirmwareUpdateVersion(String version);

View File

@ -1,4 +1,5 @@
#include "AgStateMachine.h" #include "AgStateMachine.h"
#include "AgOledDisplay.h"
#define LED_TEST_BLINK_DELAY 50 /** ms */ #define LED_TEST_BLINK_DELAY 50 /** ms */
#define LED_FAST_BLINK_DELAY 250 /** ms */ #define LED_FAST_BLINK_DELAY 250 /** ms */
@ -369,8 +370,7 @@ void StateMachine::ledBarTest(void) {
} else { } else {
ledBarRunTest(); ledBarRunTest();
} }
} } else if (ag->isOpenAir()) {
else if(ag->isOpenAir()) {
ledBarRunTest(); ledBarRunTest();
} }
} }
@ -544,11 +544,11 @@ void StateMachine::displayHandle(AgStateMachineState state) {
break; break;
} }
case AgStateMachineWiFiLost: { case AgStateMachineWiFiLost: {
disp.showDashboard("WiFi N/A"); disp.showDashboard(OledDisplay::DashBoardStatusWiFiIssue);
break; break;
} }
case AgStateMachineServerLost: { case AgStateMachineServerLost: {
disp.showDashboard("AG Server N/A"); disp.showDashboard(OledDisplay::DashBoardStatusServerIssue);
break; break;
} }
case AgStateMachineSensorConfigFailed: { case AgStateMachineSensorConfigFailed: {
@ -557,19 +557,24 @@ void StateMachine::displayHandle(AgStateMachineState state) {
if (ms >= 5000) { if (ms >= 5000) {
addToDashboardTime = millis(); addToDashboardTime = millis();
if (addToDashBoardToggle) { if (addToDashBoardToggle) {
disp.showDashboard("Add to AG Dashb."); disp.showDashboard(OledDisplay::DashBoardStatusAddToDashboard);
} else { } else {
disp.showDashboard(ag->deviceId().c_str()); disp.showDashboard(OledDisplay::DashBoardStatusDeviceId);
} }
addToDashBoardToggle = !addToDashBoardToggle; addToDashBoardToggle = !addToDashBoardToggle;
} }
} else { } else {
disp.showDashboard(""); disp.showDashboard();
} }
break; break;
} }
case AgStateMachineNormal: { case AgStateMachineNormal: {
if (config.isOfflineMode()) {
disp.showDashboard(
OledDisplay::DashBoardStatusOfflineMode);
} else {
disp.showDashboard(); disp.showDashboard();
}
break; break;
} }
case AgStateMachineCo2Calibration: case AgStateMachineCo2Calibration: