Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions esp32_microcontroller_code/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ MegaCommunication megaCommunication;
IntervalFetcher heartbeatTimer = IntervalFetcher(HEARTBEAT_INTERVAL_MS);
WiFiProvisioner provisioner;

// Last notification batch received — re-sent to Mega on poll request
String lastBatch = "";

// ── MQTT message handler ──────────────────────────────────────────────────────

void messageHandler(String &topic, String &payload)
{
if (topic != NOTIFICATIONS_SUBSCRIBE_TOPIC) return;
lastBatch = payload;
megaCommunication.sendRaw(payload.c_str());
}

Expand Down Expand Up @@ -139,6 +143,13 @@ void loop()
connectAWS();
}

// Respond to poll requests from the Mega ('P' byte sent when its idle timeout fires)
if (Serial1.available() && Serial1.read() == 'P' && lastBatch.length() > 0)
{
Serial.println("Poll request received — re-sending last batch");
megaCommunication.sendRaw(lastBatch.c_str());
}

if (heartbeatTimer.shouldFetch())
{
client.publish("weatherbox/heartbeat", "{\"status\":\"alive\"}");
Expand Down
6 changes: 6 additions & 0 deletions mega_microcontroller_code/lib/Communication/Communication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ void Communication::setNewData(bool newDataFlag){
newData = newDataFlag;
}

// Sends a single poll byte to the ESP32, asking it to re-send its last batch.
void Communication::sendPollRequest()
{
Serial1.write('P');
}

Communication::~Communication()
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Communication
bool receiveData();
char * getReceivedChars();
void setNewData(bool newDataFlag);
void sendPollRequest();
};

#endif
27 changes: 10 additions & 17 deletions mega_microcontroller_code/lib/LCD/LCD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,22 @@ void LCD::drawScreen(char *receivedChars)
row++;
}

if (row == 0) drawIdleScreen();

lastDataMs = millis();
isIdle = false;
_idle = false;
_pollSent = false;
}

// Called from loop() to show idle screen after IDLE_TIMEOUT_MS with no data
void LCD::checkIdle()
// Returns true once when the idle timeout first fires — caller sends a poll request.
// Resets automatically when drawScreen() is called with new data.
bool LCD::checkIdle()
{
if (!isIdle && millis() - lastDataMs > IDLE_TIMEOUT_MS)
if (!_pollSent && millis() - lastDataMs > IDLE_TIMEOUT_MS)
{
refreshScreen();
drawIdleScreen();
isIdle = true;
_idle = true;
_pollSent = true;
return true;
}
return false;
}

// ── Private drawing helpers ───────────────────────────────────────────────────
Expand Down Expand Up @@ -162,14 +163,6 @@ void LCD::drawRow(int rowIndex, const char *source, const char *sender,
tft.drawFastHLine(0, y + ROW_H - 1, SCREEN_W, DARKGREY);
}

void LCD::drawIdleScreen()
{
tft.setTextColor(DARKGREY, BLACK);
tft.setTextSize(2);
int msgLen = 22 * 12; // "No new notifications" × 12px/char
tft.setCursor((SCREEN_W - msgLen) / 2, SCREEN_H / 2 - 8);
tft.print("No new notifications");
}

uint16_t LCD::sourceColor(const char *source)
{
Expand Down
7 changes: 4 additions & 3 deletions mega_microcontroller_code/lib/LCD/LCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ class LCD
private:
MCUFRIEND_kbv tft;
unsigned long lastDataMs = 0;
bool isIdle = false;
bool _idle = false;
bool _pollSent = false;

void drawHeader();
void drawRow(int rowIndex, const char *source, const char *sender,
const char *channel, const char *preview,
const char *timeStr, uint8_t priority);
void drawIdleScreen();
uint16_t sourceColor(const char *source);
void truncate(const char *src, char *dst, uint8_t maxLen);

Expand All @@ -51,7 +51,8 @@ class LCD
void startScreen();
void refreshScreen();
void drawScreen(char *receivedChars);
void checkIdle();
// Returns true once when idle timeout first fires — caller should send a poll request.
bool checkIdle();
};

#endif
8 changes: 6 additions & 2 deletions mega_microcontroller_code/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ void loop()
myCommunication.setNewData(false);
}

// Show idle screen after 5 minutes without new notifications
myLCD.checkIdle();
// After 5 minutes with no new data, ask the ESP32 to re-send its last batch
if (myLCD.checkIdle())
{
Serial.println("Idle timeout — polling ESP32 for last batch");
myCommunication.sendPollRequest();
}
}