@@ -54,7 +54,7 @@ CDevice::CDevice() {
5454
5555 virtualCanvas->setTextSize (1 );
5656 virtualCanvas->setCursor (0 , 10 );
57- virtualCanvas->print (" Init... " );
57+ virtualCanvas->print (" Starting up " );
5858
5959 // Initialize scrolling
6060 scrollOffset = 0 ;
@@ -68,13 +68,21 @@ CDevice::CDevice() {
6868 showingTempMessage = false ;
6969 tempMessageEndTime = 0 ;
7070
71+ // Boot progress
72+ bootProgress = 0 ;
73+
74+ // WiFi connected banner
75+ wifiConnectedShownAt = 0 ;
76+ wifiConnectedBannerDone = false ;
77+
7178 // Calculate content bounds
7279 updateContentBounds ();
7380
7481 tMillisDisplayToggle = millis ();
7582 displayToggleState = false ;
7683 wifiConnected = false ;
7784 strcpy (wifiSSID, " " );
85+ strcpy (wifiPass, " " );
7886 strcpy (wifiIP, " " );
7987 #endif
8088
@@ -86,9 +94,41 @@ void CDevice::setState(DeviceState state) {
8694 if (_state != state) {
8795 Log.infoln (" Device state: %s -> %s" , deviceStateToString (_state), deviceStateToString (state));
8896 _state = state;
97+ #ifdef OLED
98+ if (state == DeviceState::WIFI_CONNECTED ) {
99+ wifiConnectedShownAt = millis ();
100+ wifiConnectedBannerDone = false ;
101+ lastTimeUpdate = 0 ; // Force time update after banner
102+ }
103+ #endif
89104 }
90105}
91106
107+ void CDevice::setBootProgress (uint8_t percent) {
108+ #ifdef OLED
109+ if (percent > 100 ) percent = 100 ;
110+ bootProgress = percent;
111+ #endif
112+ }
113+
114+ void CDevice::setWifiAPInfo (const char * ssid, const char * password, const char * ip) {
115+ #ifdef OLED
116+ strncpy (wifiSSID, ssid, sizeof (wifiSSID) - 1 );
117+ wifiSSID[sizeof (wifiSSID) - 1 ] = ' \0 ' ;
118+ strncpy (wifiPass, password, sizeof (wifiPass) - 1 );
119+ wifiPass[sizeof (wifiPass) - 1 ] = ' \0 ' ;
120+ strncpy (wifiIP, ip, sizeof (wifiIP) - 1 );
121+ wifiIP[sizeof (wifiIP) - 1 ] = ' \0 ' ;
122+ #endif
123+ }
124+
125+ void CDevice::setWifiConnectedInfo (const char * ip) {
126+ #ifdef OLED
127+ strncpy (wifiIP, ip, sizeof (wifiIP) - 1 );
128+ wifiIP[sizeof (wifiIP) - 1 ] = ' \0 ' ;
129+ #endif
130+ }
131+
92132CDevice::~CDevice () {
93133#ifdef OLED
94134 if (virtualCanvas) {
@@ -108,36 +148,24 @@ void CDevice::loop() {
108148 // Check if temporary message has expired
109149 if (showingTempMessage && millis () >= tempMessageEndTime) {
110150 showingTempMessage = false ;
111- lastTimeUpdate = 0 ; // Force time update
151+ lastTimeUpdate = 0 ; // Force time update after temp message
112152 }
113153
114- // Update time display once per minute (60000 ms) if not showing temp message
115- if (_state == DeviceState::WIFI_CONNECTED && !showingTempMessage && millis () - lastTimeUpdate >= 60000 ) {
116- struct tm timeinfo;
117- lastTimeUpdate = millis ();
118- virtualCanvas->fillScreen (0 );
119-
120- if (getLocalTime (&timeinfo, 100 )) { // Short timeout to avoid blocking when NTP is unavailable
121- virtualCanvas->setTextColor (1 ); // White text
122- virtualCanvas->setTextSize (2 );
123-
124- // Format time as HH:MM AM/PM
125- int hour12 = timeinfo.tm_hour % 12 ;
126- if (hour12 == 0 ) hour12 = 12 ; // Convert 0 to 12 for 12-hour format
127-
128- char timeStr[16 ];
129- snprintf (timeStr, sizeof (timeStr), " %02d:%02d" , hour12, timeinfo.tm_min );
130- int16_t textWidth = strlen (timeStr) * 12 ;
131-
132- virtualCanvas->setCursor ((72 - textWidth) / 2 , 0 );
133- virtualCanvas->print (timeStr);
134- virtualCanvas->setCursor (72 / 2 - 16 , 16 );
135- virtualCanvas->print ((timeinfo.tm_hour >= 12 ) ? " PM" : " AM" );
136- } else {
137- Log.warningln (" Failed to get local time for display update" );
154+ // State-based rendering (only when not showing a temporary message)
155+ if (!showingTempMessage) {
156+ switch (_state) {
157+ case DeviceState::INITIALIZING :
158+ drawInitializing ();
159+ break ;
160+ case DeviceState::WIFI_AP_CREATED :
161+ drawWifiAP ();
162+ break ;
163+ case DeviceState::WIFI_CONNECTED :
164+ drawWifiConnected ();
165+ break ;
166+ default :
167+ break ;
138168 }
139- // Update content bounds after drawing
140- updateContentBounds ();
141169 }
142170
143171 // Update scroll position every 50ms
@@ -257,4 +285,136 @@ void CDevice::displayTemporaryMessage(const char* message, unsigned long duratio
257285 tempMessageEndTime = millis () + durationMs;
258286 #endif
259287}
288+
289+ void CDevice::drawInitializing () {
290+ #ifdef CONFIG_IDF_TARGET_ESP32C3
291+ if (!virtualCanvas) return ;
292+
293+ virtualCanvas->fillScreen (0 );
294+ virtualCanvas->setTextColor (1 );
295+ virtualCanvas->setTextSize (1 ); // 6x8 font
296+
297+ // "Starting up" centered
298+ const char * msg = " Starting up" ;
299+ int16_t textWidth = strlen (msg) * 6 ;
300+ virtualCanvas->setCursor ((OLED_SCREEN_WIDTH - textWidth) / 2 , 4 );
301+ virtualCanvas->print (msg);
302+
303+ // Progress bar: 4px padding each side, 2px below text
304+ int16_t barX = 4 ;
305+ int16_t barY = 18 ;
306+ int16_t barW = OLED_SCREEN_WIDTH - 8 ;
307+ int16_t barH = 10 ;
308+
309+ // Outline
310+ virtualCanvas->drawRect (barX, barY, barW, barH, 1 );
311+
312+ // Filled portion
313+ int16_t fillW = (int16_t )((barW - 2 ) * bootProgress / 100 );
314+ if (fillW > 0 ) {
315+ virtualCanvas->fillRect (barX + 1 , barY + 1 , fillW, barH - 2 , 1 );
316+ }
317+
318+ updateContentBounds ();
319+ #endif
320+ }
321+
322+ void CDevice::drawWifiAP () {
323+ #ifdef CONFIG_IDF_TARGET_ESP32C3
324+ if (!virtualCanvas) return ;
325+
326+ virtualCanvas->fillScreen (0 );
327+ virtualCanvas->setTextColor (1 );
328+ virtualCanvas->setTextSize (1 ); // Smallest font (6x8)
329+
330+ // Line 1: "WiFi Created"
331+
332+
333+ // Line 2: SSID
334+ virtualCanvas->setCursor (0 , 9 );
335+ virtualCanvas->print (wifiSSID);
336+
337+ // Line 3: Password
338+ virtualCanvas->setCursor (0 , 18 );
339+ virtualCanvas->print (wifiPass);
340+
341+ // Line 4: IP address
342+ virtualCanvas->setCursor (0 , 27 );
343+ virtualCanvas->print (wifiIP);
344+
345+ updateContentBounds ();
346+ #endif
347+ }
348+
349+ void CDevice::drawWifiConnected () {
350+ #ifdef CONFIG_IDF_TARGET_ESP32C3
351+ if (!virtualCanvas) return ;
352+
353+ // Show "WiFi connected" + IP for 10 seconds, then switch to time
354+ if (!wifiConnectedBannerDone && millis () - wifiConnectedShownAt < 10000 ) {
355+ virtualCanvas->fillScreen (0 );
356+ virtualCanvas->setTextColor (1 );
357+ virtualCanvas->setTextSize (1 );
358+
359+ const char * msg = " WiFi connected" ;
360+ virtualCanvas->setCursor (0 , 0 );
361+ virtualCanvas->print (msg);
362+
363+ virtualCanvas->setCursor (0 , 9 );
364+ virtualCanvas->print (wifiIP);
365+
366+ virtualCanvas->setCursor (0 , 18 );
367+ virtualCanvas->print (" Web server ready" );
368+
369+ updateContentBounds ();
370+ } else {
371+ if (!wifiConnectedBannerDone) {
372+ wifiConnectedBannerDone = true ;
373+ lastTimeUpdate = 0 ; // Force immediate time draw
374+ }
375+ drawTime ();
376+ }
377+ #endif
378+ }
379+
380+ void CDevice::drawTime () {
381+ #ifdef CONFIG_IDF_TARGET_ESP32C3
382+ if (!virtualCanvas) return ;
383+
384+ // Update once per minute
385+ if (millis () - lastTimeUpdate < 60000 ) return ;
386+ lastTimeUpdate = millis ();
387+
388+ virtualCanvas->fillScreen (0 );
389+
390+ struct tm timeinfo;
391+ if (getLocalTime (&timeinfo, 100 )) {
392+ virtualCanvas->setTextColor (1 );
393+ virtualCanvas->setTextSize (2 ); // Large font for time
394+
395+ int hour12 = timeinfo.tm_hour % 12 ;
396+ if (hour12 == 0 ) hour12 = 12 ;
397+
398+ char timeStr[16 ];
399+ snprintf (timeStr, sizeof (timeStr), " %02d:%02d" , hour12, timeinfo.tm_min );
400+ int16_t textWidth = strlen (timeStr) * 12 ; // textSize 2 = 12px per char
401+
402+ virtualCanvas->setCursor ((OLED_SCREEN_WIDTH - textWidth) / 2 , 0 );
403+ virtualCanvas->print (timeStr);
404+
405+ // AM/PM below
406+ const char * ampm = (timeinfo.tm_hour >= 12 ) ? " PM" : " AM" ;
407+ int16_t ampmWidth = strlen (ampm) * 12 ;
408+ virtualCanvas->setCursor ((OLED_SCREEN_WIDTH - ampmWidth) / 2 , 20 );
409+ virtualCanvas->print (ampm);
410+ } else {
411+ virtualCanvas->setTextColor (1 );
412+ virtualCanvas->setTextSize (1 );
413+ virtualCanvas->setCursor (0 , 10 );
414+ virtualCanvas->print (" Time N/A" );
415+ }
416+
417+ updateContentBounds ();
418+ #endif
419+ }
260420#endif
0 commit comments