diff --git a/esp32_MachineNotify.ino b/esp32_MachineNotify.ino index 49bd240..b8f05d6 100644 --- a/esp32_MachineNotify.ino +++ b/esp32_MachineNotify.ino @@ -4,12 +4,15 @@ // Feature Configuration - Comment out to disable #define ENABLE_SENSORS #define ENABLE_DISPLAY -//#define ENABLE_WIFI -//#define ENABLE_NOTIFICATIONS +#define ENABLE_WIFI +#define ENABLE_NOTIFICATIONS #ifdef ENABLE_WIFI #include #include +#include +#include +#include #endif #ifdef ENABLE_SENSORS @@ -57,6 +60,7 @@ const float LIGHT_DEACTIVATION_THRESHOLD = 20.0; const unsigned long VIBRATION_STATE_CHANGE_INTERVAL = 5000; // 5 seconds const unsigned long VIBRATION_ACTIVE_THRESHOLD = 10000; const int VIBRATION_WINDOW_SIZE = 4; // X * 5s seconds window +const unsigned long WARMUP_DURATION = 20000; // 20 seconds warmup // Device state bool isVibrationActive = false; @@ -77,14 +81,14 @@ const int displayTextLines = 4; int displayDataLines = displayTextLines; #endif -// Notification queue -String queuedMessage1 = ""; -String queuedTitle1 = ""; -String queuedPriority1 = ""; - -String queuedMessage2 = ""; -String queuedTitle2 = ""; -String queuedPriority2 = ""; +// Network Task & Queue +struct NotificationMessage { + char message[64]; + char title[32]; + char priority[10]; +}; +QueueHandle_t notificationQueue; +volatile bool isNetworkActive = false; #ifdef ENABLE_SENSORS unsigned long vibrationHistory[VIBRATION_WINDOW_SIZE]; @@ -110,8 +114,66 @@ void IRAM_ATTR onChange() { } #endif +#ifdef ENABLE_WIFI +void networkTask(void *parameter) { + NotificationMessage msg; + unsigned long lastWifiCheckTime = 0; + const unsigned long WIFI_CHECK_INTERVAL = 30000; + + while (true) { + unsigned long currentTime = millis(); + if (currentTime - lastWifiCheckTime >= WIFI_CHECK_INTERVAL) { + lastWifiCheckTime = currentTime; + if (WiFi.status() != WL_CONNECTED) { + Serial.println("WiFi disconnected. Attempting to reconnect..."); + WiFi.reconnect(); + } + } + + if (xQueueReceive(notificationQueue, &msg, 1000 / portTICK_PERIOD_MS) == pdTRUE) { + isNetworkActive = true; + bool sent = false; + while (!sent) { + if (WiFi.status() == WL_CONNECTED) { + HTTPClient http; + String url = "http://ntfy.sh/" + String(NTFY_TOPIC); + http.begin(url); + http.addHeader("Content-Type", "text/plain"); + http.addHeader("Title", msg.title); + http.addHeader("Priority", msg.priority); + + int httpResponseCode = http.POST(msg.message); + http.end(); + + if (httpResponseCode > 0) { + Serial.print("HTTP Response code: "); + Serial.println(httpResponseCode); + sent = true; + } else { + Serial.print("Error on sending POST: "); + Serial.println(httpResponseCode); + vTaskDelay(2000 / portTICK_PERIOD_MS); + } + } else { + unsigned long now = millis(); + if (now - lastWifiCheckTime >= WIFI_CHECK_INTERVAL) { + lastWifiCheckTime = now; + Serial.println("WiFi disconnected. Attempting to reconnect..."); + WiFi.reconnect(); + } + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } + isNetworkActive = false; + } + } +} +#endif + void setup() { + delay(500); Serial.begin(9600); + delay(100); Serial.println("Setup started."); #if defined(ENABLE_SENSORS) || defined(ENABLE_DISPLAY) @@ -120,7 +182,7 @@ void setup() { #ifdef ENABLE_SENSORS // Initialize vibration sensor pin - pinMode(VIBRATION_PIN, INPUT); + pinMode(VIBRATION_PIN, INPUT_PULLUP); lastChangeTime = micros(); attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), onChange, CHANGE); @@ -161,6 +223,11 @@ void setup() { Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); + + #ifdef ENABLE_NOTIFICATIONS + notificationQueue = xQueueCreate(10, sizeof(NotificationMessage)); + xTaskCreatePinnedToCore(networkTask, "NetworkTask", 8192, NULL, 1, NULL, 0); + #endif #endif #if defined(ENABLE_DISPLAY) && defined(ENABLE_WIFI) @@ -175,30 +242,9 @@ void setup() { Serial.println("Setup finished."); } -bool sendNotification(String message, String title, String priority); void updateDisplay(); void loop() { - #ifdef ENABLE_NOTIFICATIONS - // Try to send any queued notification - if (queuedMessage1 != "") { - if (sendNotification(queuedMessage1, queuedTitle1, queuedPriority1)) { - Serial.println("Successfully sent queued notification 1."); - queuedMessage1 = ""; // Clear queue - queuedTitle1 = ""; - queuedPriority1 = ""; - } - } - if (queuedMessage2 != "") { - if (sendNotification(queuedMessage2, queuedTitle2, queuedPriority2)) { - Serial.println("Successfully sent queued notification 2."); - queuedMessage2 = ""; // Clear queue - queuedTitle2 = ""; - queuedPriority2 = ""; - } - } - #endif - unsigned long currentTime = millis(); // Sensor readings @@ -237,7 +283,7 @@ void loop() { vibrationWindowTotal += vibrationTotalLow; vibrationHistoryIdx = (vibrationHistoryIdx + 1) % VIBRATION_WINDOW_SIZE; - if (vibrationWindowTotal > VIBRATION_ACTIVE_THRESHOLD) { + if (vibrationWindowTotal > VIBRATION_ACTIVE_THRESHOLD && currentTime > WARMUP_DURATION) { isVibrationActive = true; } else { isVibrationActive = false; @@ -250,7 +296,7 @@ void loop() { if (lightHighStartTime == 0) { lightHighStartTime = currentTime; } - if (currentTime - lightHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + if (currentTime - lightHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL && currentTime > WARMUP_DURATION) { isLightActive = true; } lightLowStartTime = 0; @@ -284,11 +330,18 @@ void loop() { } #ifdef ENABLE_NOTIFICATIONS - if (!sendNotification(message, title, priority)) { - queuedMessage1 = message; - queuedTitle1 = title; - queuedPriority1 = priority; - } + #ifdef ENABLE_WIFI + NotificationMessage msg; + strncpy(msg.message, message.c_str(), sizeof(msg.message) - 1); + msg.message[sizeof(msg.message) - 1] = 0; + strncpy(msg.title, title.c_str(), sizeof(msg.title) - 1); + msg.title[sizeof(msg.title) - 1] = 0; + strncpy(msg.priority, priority.c_str(), sizeof(msg.priority) - 1); + msg.priority[sizeof(msg.priority) - 1] = 0; + xQueueSend(notificationQueue, &msg, 0); + #else + Serial.println("WiFi Disabled. Notification skipped: " + message); + #endif #else Serial.println("Notification (Disabled): " + title + " - " + message); #endif @@ -310,11 +363,18 @@ void loop() { } #ifdef ENABLE_NOTIFICATIONS - if (!sendNotification(message, title, priority)) { - queuedMessage2 = message; - queuedTitle2 = title; - queuedPriority2 = priority; - } + #ifdef ENABLE_WIFI + NotificationMessage msg; + strncpy(msg.message, message.c_str(), sizeof(msg.message) - 1); + msg.message[sizeof(msg.message) - 1] = 0; + strncpy(msg.title, title.c_str(), sizeof(msg.title) - 1); + msg.title[sizeof(msg.title) - 1] = 0; + strncpy(msg.priority, priority.c_str(), sizeof(msg.priority) - 1); + msg.priority[sizeof(msg.priority) - 1] = 0; + xQueueSend(notificationQueue, &msg, 0); + #else + Serial.println("WiFi Disabled. Notification skipped: " + message); + #endif #else Serial.println("Notification (Disabled): " + title + " - " + message); #endif @@ -333,38 +393,6 @@ void loop() { #endif } -bool sendNotification(String message, String title, String priority) { - #ifdef ENABLE_WIFI - if (WiFi.status() == WL_CONNECTED) { - HTTPClient http; - String url = "http://ntfy.sh/" + String(NTFY_TOPIC); - http.begin(url); - http.addHeader("Content-Type", "text/plain"); - http.addHeader("Title", title); - http.addHeader("Priority", priority); - - int httpResponseCode = http.POST(message); - http.end(); - - if (httpResponseCode > 0) { - Serial.print("HTTP Response code: "); - Serial.println(httpResponseCode); - return true; - } else { - Serial.print("Error on sending POST: "); - Serial.println(httpResponseCode); - return false; - } - } else { - Serial.println("WiFi Disconnected. Cannot send notification."); - return false; - } - #else - Serial.println("WiFi Disabled. Notification skipped."); - return true; - #endif -} - void updateDisplay() { #ifdef ENABLE_DISPLAY unsigned long currentTime = millis(); @@ -410,6 +438,38 @@ void updateDisplay() { display.fillRect(rectX + 2, rectY2 + 2, step, rectHeight - 4, WHITE); } + // Network Status Indicator + #ifdef ENABLE_WIFI + int r = 8; + int cx = SCREEN_WIDTH - r - 2; + int cy = SCREEN_HEIGHT / 2; + if (WiFi.status() != WL_CONNECTED) { + display.drawLine(cx - r, cy - r, cx + r, cy + r, WHITE); + display.drawLine(cx - r, cy + r, cx + r, cy - r, WHITE); + } else if (isNetworkActive) { + display.fillCircle(cx, cy, r, WHITE); + } else { + display.drawCircle(cx, cy, r, WHITE); + } + + #ifdef ENABLE_NOTIFICATIONS + if (notificationQueue != NULL) { + int waiting = (int)uxQueueMessagesWaiting(notificationQueue); + int startY = cy + r + 2; + int h = SCREEN_HEIGHT - startY; + for (int i = 0; i < waiting; i++) { + int x = (cx - r) + (i * 2); + if (x < SCREEN_WIDTH && h > 0) display.drawFastVLine(x, startY, h, WHITE); + } + } + #endif + #endif + + // Warmup Indicator + if (currentTime < WARMUP_DURATION) { + display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); + } + display.display(); #endif }