浏览代码

Added master alarm override control via MQTT

Thomas Chef 4 月之前
父节点
当前提交
7b15ef65ac
共有 4 个文件被更改,包括 70 次插入10 次删除
  1. 1 0
      main/main.c
  2. 14 0
      main/mqtt.c
  3. 47 10
      main/sound.c
  4. 8 0
      main/sound.h

+ 1 - 0
main/main.c

@@ -30,4 +30,5 @@ void app_main(void)
     setup_photo_sensor();
     initSound();
 
+    alarmMasterControl(ALARM_ON);
 }

+ 14 - 0
main/mqtt.c

@@ -29,6 +29,7 @@
 
 #include "esp_log.h"
 #include "mqtt_client.h"
+#include "sound.h"
 
 #include "wifi.h"
 
@@ -51,6 +52,7 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
             connected = true;
             ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
             esp_mqtt_client_publish(client, "kitchen/fridge/available", "online", 0, 1, true);
+            esp_mqtt_client_subscribe(client, "kitchen/fridge/doorAlarmControl", 0);
             break;
         case MQTT_EVENT_DISCONNECTED:
             connected = false;
@@ -64,6 +66,18 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
             ESP_LOGI(TAG, "MQTT_EVENT_DATA");
             printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
             printf("DATA=%.*s\r\n", event->data_len, event->data);
+            if (strncmp(event->topic, "kitchen/fridge/doorAlarmControl", event->topic_len) == 0) {
+                if (strncmp(event->data, "OFF", event->data_len) == 0) {
+                    ESP_LOGI("MQTT", "Fridge alarm disabled");
+                    alarmMasterControl(ALARM_OFF);
+                } else if (strncmp(event->data, "ON", event->data_len) == 0) {
+                    ESP_LOGI("MQTT", "Fridge alarm enabled");
+                    alarmMasterControl(ALARM_ON);
+                } else if (strncmp(event->data, "TEST", event->data_len) == 0) {
+                    ESP_LOGI("MQTT", "Fridge alarm test");
+                    alarmMasterControl(ALARM_TEST);
+                }
+            }
             break;
         case MQTT_EVENT_ERROR:
             ESP_LOGI(TAG, "MQTT_EVENT_ERROR");

+ 47 - 10
main/sound.c

@@ -18,9 +18,11 @@
 #define TONE_DURATION     1000          // Duration of the tone in ms
 #define QUIET_DURATION    1000          // Duration of the quiet period in ms
 
-bool soundEnabled = false;
+// Internal variable used to control the actual sound state
+static bool soundEnabled = false;
+static bool alarmMasterEnabled = true;  // Master control, default ON
 
-static void play_tone(int frequency, float duration, int quietDuration) {
+static void play_tone(int frequency, float duration, int quietDuration, bool override) {
 
     int semitones = 0;
 
@@ -39,7 +41,7 @@ static void play_tone(int frequency, float duration, int quietDuration) {
     // Loop with 50mS loops until the duration is complete
     for(int i = 0; i < duration; i+=50) {
         vTaskDelay(pdMS_TO_TICKS(50));
-        if( soundEnabled == false ) {
+        if( soundEnabled == false && override == false ) {
             break;
         }
     }
@@ -68,7 +70,7 @@ static void sound_task(void *pvParameters) {
     while (1) {
         vTaskDelay(pdMS_TO_TICKS(1000));
         if( soundEnabled ) {
-            play_tone(TONE_FREQ, TONE_DURATION, QUIET_DURATION);
+            play_tone(TONE_FREQ, TONE_DURATION, QUIET_DURATION, false);
         }
     }
 }
@@ -79,22 +81,57 @@ void initSound() {
     ESP_LOGI("SOUND", "Sound initialized");
 }
 
-void enableNotificationSound(bool enable)
-{
-    if (soundEnabled != enable) {
+// FreeRTOS Task: Handles the test beep asynchronously
+static void alarm_test_task(void *pvParameters) {
+    play_tone(TONE_FREQ, TONE_DURATION, QUIET_DURATION, true);
+    vTaskDelete(NULL);  // Delete task after completion
+}
+
+
+// Function to enable/disable the notification sound (called by door sensor)
+void enableNotificationSound(bool enable) {
+    if (!alarmMasterEnabled) {
+        // If master is OFF, sound should always be OFF
+        enable = false;
+    }
+
+    if (soundEnabled != enable) {  // Only send MQTT if there's a change
         ESP_LOGI("SOUND", "Notification sound %s", enable ? "enabled" : "disabled");
+
         char mqtt_s[50];
         char value_s[10];
 
-        sprintf(mqtt_s,"kitchen/fridge/doorAlarm");
-        sprintf(value_s,"%s",enable ? "active" : "inactive");
+        sprintf(mqtt_s, "kitchen/fridge/doorAlarm");
+        sprintf(value_s, "%s", enable ? "active" : "inactive");
+
         sendMQTTMessage(mqtt_s, value_s);
+        soundEnabled = enable;  // Update state AFTER sending message
+    }
+}
+
+// Master control for the alarm system (called by Home Assistant)
+void alarmMasterControl(alarmState_t state) {
+    switch (state) {
+        case ALARM_OFF:
+            alarmMasterEnabled = false;  // Master disables alarm
+            enableNotificationSound(false);  // Ensure sound is OFF
+            break;
+
+        case ALARM_ON:
+            alarmMasterEnabled = true;   // Master enables alarm
+            break;
+
+        case ALARM_TEST:
+            // Create a background task for the test beep, even if master is OFF
+            xTaskCreate(alarm_test_task, "alarm_test_task", 2048, NULL, 5, NULL);
+            break;
     }
-    soundEnabled = enable;
 }
 
+
 #else
 void initSound() {};
 void enableNotificationSound(bool enable) {};
+void alarmMasterControl(alarmState_t state) {};
 #endif
 

+ 8 - 0
main/sound.h

@@ -3,9 +3,17 @@
 
 #include <stdbool.h>
 
+typedef enum {
+    ALARM_OFF,
+    ALARM_ON,
+    ALARM_TEST
+} alarmState_t;
+
 void initSound();
 
 void enableNotificationSound(bool enable);
 
+void alarmMasterControl(alarmState_t state);
+
 
 #endif