@@ -83,6 +83,119 @@ class dispDrvThinkInkGrayscale4T5 : public dispDrvBase {
8383 return true ;
8484 }
8585
86+ /* !
87+ @brief Draws a status bar at the top of the display.
88+ @param io_username
89+ The Adafruit IO username to display on the status bar.
90+ */
91+ virtual void drawStatusBar (const char *io_username) override {
92+ if (!_display)
93+ return ;
94+
95+ // Clear the entire display buffer to remove splash screen
96+ _display->clearBuffer ();
97+
98+ // Draw status bar
99+ _display->fillRect (0 , 0 , _display->width (), STATUS_BAR_HEIGHT, EPD_BLACK);
100+ _display->fillRect (STATUS_BAR_BORDER, STATUS_BAR_BORDER,
101+ _display->width () - (2 * STATUS_BAR_BORDER),
102+ STATUS_BAR_HEIGHT - (2 * STATUS_BAR_BORDER), EPD_WHITE);
103+
104+ // Draw username on left side of the status bar
105+ _display->setTextSize (1 );
106+ _display->setTextColor (EPD_BLACK);
107+ _display->setCursor (5 , 6 );
108+ _display->print (io_username);
109+
110+ // Calculate status bar icon positions and center vertically
111+ _statusbar_icons_y =
112+ STATUS_BAR_BORDER +
113+ ((STATUS_BAR_HEIGHT - 2 * STATUS_BAR_BORDER - STATUS_BAR_ICON_SZ) / 2 );
114+ _statusbar_icon_battery_x =
115+ _display->width () - STATUS_BAR_ICON_SZ - STATUS_BAR_ICON_MARGIN;
116+ _statusbar_icon_wifi_x = _statusbar_icon_battery_x - STATUS_BAR_ICON_SZ -
117+ STATUS_BAR_ICON_SPACING;
118+ _statusbar_icon_cloud_x =
119+ _statusbar_icon_wifi_x - STATUS_BAR_ICON_SZ - STATUS_BAR_ICON_SPACING;
120+ // Draw icons on right side of the status bar
121+ _display->drawBitmap (_statusbar_icon_cloud_x, _statusbar_icons_y,
122+ epd_bmp_cloud_online, STATUS_BAR_ICON_SZ,
123+ STATUS_BAR_ICON_SZ, EPD_BLACK);
124+ _display->drawBitmap (_statusbar_icon_wifi_x, _statusbar_icons_y,
125+ epd_bmp_wifi_full, STATUS_BAR_ICON_SZ,
126+ STATUS_BAR_ICON_SZ, EPD_BLACK);
127+ _display->drawBitmap (_statusbar_icon_battery_x, _statusbar_icons_y,
128+ epd_bmp_bat_full, STATUS_BAR_ICON_SZ,
129+ STATUS_BAR_ICON_SZ, EPD_BLACK);
130+
131+ _display->display ();
132+ }
133+
134+ /* !
135+ @brief Updates the status bar with current information (battery level,
136+ connectivity status, etc).
137+ @param rssi
138+ The current WiFi RSSI (signal strength) in dB.
139+ @param bat
140+ The current battery level as a percentage (0-100).
141+ @param mqtt_status
142+ The current MQTT connection status.
143+ */
144+ void updateStatusBar (int8_t rssi, uint8_t bat, bool mqtt_status) override {
145+ if (!_display)
146+ return ;
147+
148+ // Only update wifi icon if the RSSI has changed significantly (+/- 5dB)
149+ bool update_rssi = abs (rssi - _statusbar_rssi) >= 5 ;
150+ // Only update cloud icon if MQTT status has changed
151+ bool update_mqtt = mqtt_status != _statusbar_mqtt_connected;
152+
153+ // No need to update if nothing has changed
154+ if (!update_rssi && !update_mqtt)
155+ return ;
156+
157+ if (update_mqtt) {
158+ // updating the RSSI occurs too frequently to be practical
159+ _display->fillRect (_statusbar_icon_cloud_x, _statusbar_icons_y,
160+ STATUS_BAR_ICON_SZ, STATUS_BAR_ICON_SZ, EPD_WHITE);
161+ if (mqtt_status) {
162+ _display->drawBitmap (_statusbar_icon_cloud_x, _statusbar_icons_y,
163+ epd_bmp_cloud_online, STATUS_BAR_ICON_SZ,
164+ STATUS_BAR_ICON_SZ, EPD_BLACK);
165+ } else {
166+ _display->drawBitmap (_statusbar_icon_cloud_x, _statusbar_icons_y,
167+ epd_bmp_cloud_offline, STATUS_BAR_ICON_SZ,
168+ STATUS_BAR_ICON_SZ, EPD_BLACK);
169+ }
170+ _statusbar_mqtt_connected = mqtt_status;
171+ }
172+
173+ // Update WiFi icon only if RSSI has changed significantly (+/-3dB)
174+ if (update_rssi) {
175+ const unsigned char *wifi_icon = epd_bmp_wifi_no_signal;
176+ if (rssi >= -50 ) {
177+ wifi_icon = epd_bmp_wifi_full;
178+ } else if (rssi < -50 && rssi >= -60 ) {
179+ wifi_icon = epd_bmp_wifi_fair;
180+ } else if (rssi < -60 && rssi >= -70 ) {
181+ wifi_icon = epd_bmp_wifi_weak;
182+ } else if (rssi < -70 && rssi >= -80 ) {
183+ wifi_icon = epd_bmp_wifi_no_signal;
184+ } else {
185+ wifi_icon = epd_bmp_wifi_no_signal;
186+ }
187+ // Clear and draw the new WiFi icon, based on RSSI
188+ _display->fillRect (_statusbar_icon_wifi_x, _statusbar_icons_y,
189+ STATUS_BAR_ICON_SZ, STATUS_BAR_ICON_SZ, EPD_WHITE);
190+ _display->drawBitmap (_statusbar_icon_wifi_x, _statusbar_icons_y,
191+ wifi_icon, STATUS_BAR_ICON_SZ, STATUS_BAR_ICON_SZ,
192+ EPD_BLACK);
193+ _statusbar_rssi = rssi;
194+ }
195+
196+ _display->display ();
197+ }
198+
86199 /* !
87200 @brief Writes a message to the display.
88201 @param message
@@ -94,16 +207,22 @@ class dispDrvThinkInkGrayscale4T5 : public dispDrvBase {
94207 if (_display == nullptr )
95208 return ;
96209
97- // Start with a fresh display buffer
98- _display->clearBuffer ();
99- int16_t y_idx = 0 ;
210+ // Clear only the area below the status bar
211+ _display->fillRect (0 , STATUS_BAR_HEIGHT, _display->width (),
212+ _display->height () - STATUS_BAR_HEIGHT, EPD_WHITE);
213+ // Add padding between status bar and text content
214+ int16_t y_idx = STATUS_BAR_HEIGHT + 4 ;
100215 _display->setCursor (0 , y_idx);
101216
102217 // Calculate the line height based on the text size (NOTE: base height is
103218 // 8px)
104219 int16_t line_height = 8 * _text_sz;
105220 uint16_t c_idx = 0 ;
106221 size_t msg_size = strlen (message);
222+
223+ // Reset the text size to the configured value before we write
224+ _display->setTextSize (_text_sz);
225+
107226 for (size_t i = 0 ; i < msg_size && c_idx < msg_size; i++) {
108227 if (y_idx + line_height > _height)
109228 break ;
@@ -127,6 +246,7 @@ class dispDrvThinkInkGrayscale4T5 : public dispDrvBase {
127246 i++;
128247 }
129248 } else if (message[i] == 0xC2 && message[i + 1 ] == 0xB0 ) {
249+ // Degree symbol
130250 _display->write (char (248 ));
131251 i++;
132252 } else {
0 commit comments