فهرست منبع

gpio handler work

Zwer2k 4 سال پیش
والد
کامیت
a44e0d81cc

+ 56 - 9
code/components/jomjol_controlGPIO/server_GPIO.cpp

@@ -7,6 +7,8 @@
 #include "freertos/task.h"
 #include "esp_system.h"
 #include "esp_event.h"
+
+//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
 #include "esp_log.h"
 //#include "errno.h"
 
@@ -51,7 +53,7 @@ static void IRAM_ATTR gpio_isr_handler(void* arg)
 {
     GpioResult gpioResult;
     gpioResult.gpio = *(gpio_num_t*) arg;
-    gpioResult.value = gpio_get_level(gpioResult.gpio) == 1;
+    gpioResult.value = gpio_get_level(gpioResult.gpio);
     BaseType_t ContextSwitchRequest = pdFALSE;
  
     xQueueSendToBackFromISR(gpio_queue_handle,(void*)&gpioResult,&ContextSwitchRequest);
@@ -61,7 +63,8 @@ static void IRAM_ATTR gpio_isr_handler(void* arg)
     }
 }
 
-static void gpioInterruptTask(void *arg) {
+static void gpioHandlerTask(void *arg) {
+    ESP_LOGD(TAG_SERVERGPIO,"start interrupt task");
     while(1){
         if(uxQueueMessagesWaiting(gpio_queue_handle)){
             while(uxQueueMessagesWaiting(gpio_queue_handle)){
@@ -71,15 +74,18 @@ static void gpioInterruptTask(void *arg) {
                 ((GpioHandler*)arg)->gpioInterrupt(&gpioResult);
             }  
         }
+
+        ((GpioHandler*)arg)->taskHandler();
         vTaskDelay(pdMS_TO_TICKS(1000));
     }
 }
 
-void GpioPin::gpioInterrupt(bool value) {
+void GpioPin::gpioInterrupt(int value) {
     if (_mqttTopic != "") {
         ESP_LOGD(TAG_SERVERGPIO, "gpioInterrupt %s %d", _mqttTopic.c_str(), value);
 
         MQTTPublish(_mqttTopic, value ? "true" : "false");
+        currentState = value;
     }
 }
 
@@ -101,6 +107,7 @@ void GpioPin::init()
 
     if (_interruptType != GPIO_INTR_DISABLE) {
         //hook isr handler for specific gpio pin
+        ESP_LOGD(TAG_SERVERGPIO, "GpioPin::init add isr handler for GPIO %d\r\n", _gpio);
         gpio_isr_handler_add(_gpio, gpio_isr_handler, (void*)&_gpio);
     }
 
@@ -134,6 +141,15 @@ void GpioPin::setValue(bool value, gpio_set_source setSource, std::string* error
     }
 }
 
+void GpioPin::publishState() {
+    int newState = gpio_get_level(_gpio);
+    if (newState != currentState) {
+        ESP_LOGD(TAG_SERVERGPIO,"publish state of GPIO %d new state %d", _gpio, newState);
+        MQTTPublish(_mqttTopic, newState ? "true" : "false");
+        currentState = newState;
+    }
+}
+
 bool GpioPin::handleMQTT(std::string, char* data, int data_len) {
     ESP_LOGD(TAG_SERVERGPIO, "GpioPin::handleMQTT data %.*s\r\n", data_len, data);
 
@@ -179,8 +195,6 @@ GpioHandler::GpioHandler(std::string configFile, httpd_handle_t httpServer)
 
     ESP_LOGI(TAG_SERVERGPIO, "register GPIO Uri");
     registerGpioUri();
-
-    //xTaskCreate((TaskFunction_t)&taskGpioHandler, "taskGpioHandler", configMINIMAL_STACK_SIZE * 64, this, tskIDLE_PRIORITY+1, &xHandletaskGpioHandler);
 }
 
 GpioHandler::~GpioHandler()  {
@@ -207,18 +221,51 @@ void GpioHandler::init()
 
     for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
         it->second->init();
-        
-        if ((it->second->getInterruptType() != GPIO_INTR_DISABLE) && (gpio_queue_handle == NULL)) {
-            gpio_queue_handle = xQueueCreate(10,sizeof(GpioResult));
-            xTaskCreate(gpioInterruptTask, "GPIO Task", configMINIMAL_STACK_SIZE * 64, (void *)this, 10, NULL);
+    }
+
+    std::function<void()> f = std::bind(&GpioHandler::handleMQTTconnect, this);
+    MQTTregisterConnectFunction("gpio-handler", f);
+
+    if (xHandleTaskGpio == NULL) {
+        gpio_queue_handle = xQueueCreate(10,sizeof(GpioResult));
+        BaseType_t  xReturned = xTaskCreate(&gpioHandlerTask, "gpio_int", configMINIMAL_STACK_SIZE * 8, (void *)this, tskIDLE_PRIORITY + 2, &xHandleTaskGpio);
+        if(xReturned == pdPASS ) {
+            ESP_LOGD(TAG_SERVERGPIO, "xHandletaskGpioHandler started");
+        } else {
+            ESP_LOGD(TAG_SERVERGPIO, "xHandletaskGpioHandler not started %d ", (int)xHandleTaskGpio);
         }
     }
 
     ESP_LOGI(TAG_SERVERGPIO, "GPIO init comleted");
 }
 
+void GpioHandler::taskHandler() {
+    if (gpioMap != NULL) {
+        for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
+            if ((it->second->getInterruptType() == GPIO_INTR_DISABLE))
+                it->second->publishState();
+        }
+    }
+}
+
+
+void GpioHandler::handleMQTTconnect()
+{
+    if (gpioMap != NULL) {
+        for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
+            if ((it->second->getMode() == GPIO_PIN_MODE_INPUT) || (it->second->getMode() == GPIO_PIN_MODE_INPUT_PULLDOWN) || (it->second->getMode() == GPIO_PIN_MODE_INPUT_PULLUP))
+                it->second->publishState();
+        }
+    }
+}
+
 void GpioHandler::deinit() {
+    MQTTunregisterConnectFunction("gpio-handler");
     clear();
+    if (xHandleTaskGpio != NULL) {
+        vTaskDelete(xHandleTaskGpio);
+        xHandleTaskGpio = NULL;
+    }
 }
 
 void GpioHandler::gpioInterrupt(GpioResult* gpioResult) {

+ 8 - 4
code/components/jomjol_controlGPIO/server_GPIO.h

@@ -23,7 +23,7 @@ typedef enum {
 
 struct GpioResult {
     gpio_num_t gpio;
-    bool value;
+    int value;
 };
 
 typedef enum {
@@ -37,11 +37,12 @@ public:
     GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType, uint8_t dutyResolution, std::string mqttTopic, bool httpEnable);
     ~GpioPin();
 
+    void init();
     bool getValue(std::string* errorText);
     void setValue(bool value, gpio_set_source setSource, std::string* errorText);
-    void init();
     bool handleMQTT(std::string, char* data, int data_len);
-    void gpioInterrupt(bool value);
+    void publishState();
+    void gpioInterrupt(int value);
     gpio_int_type_t getInterruptType() { return _interruptType; }
     gpio_pin_mode_t getMode() { return _mode; }
 
@@ -51,6 +52,7 @@ private:
     gpio_pin_mode_t _mode;
     gpio_int_type_t _interruptType;
     std::string _mqttTopic;
+    int currentState = -1;
 };
 
 esp_err_t callHandleHttpRequest(httpd_req_t *req);
@@ -65,15 +67,17 @@ public:
     void deinit();
     void registerGpioUri();
     esp_err_t handleHttpRequest(httpd_req_t *req);
+    void taskHandler();
     void gpioInterrupt(GpioResult* gpioResult);  
     void flashLightEnable(bool value);
     bool isEnabled() { return _isEnabled; }
+    void handleMQTTconnect();
 
 private:
     std::string _configFile;
     httpd_handle_t _httpServer;
     std::map<gpio_num_t, GpioPin*> *gpioMap = NULL;
-    TaskHandle_t xHandletaskGpioHandler = NULL;
+    TaskHandle_t xHandleTaskGpio = NULL;
     bool _isEnabled = false;
 
     bool readConfig();

+ 49 - 19
code/components/jomjol_mqtt/interface_mqtt.cpp

@@ -1,12 +1,13 @@
 #include "interface_mqtt.h"
 
-
+//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
 #include "esp_log.h"
 #include "mqtt_client.h"
 #include "ClassLogFile.h"
 
 static const char *TAG_INTERFACEMQTT = "interface_mqtt";
 
+std::map<std::string, std::function<void()>>* connectFunktionMap = NULL;  
 std::map<std::string, std::function<bool(std::string, char*, int)>>* subscribeFunktionMap = NULL;  
 bool debugdetail = true;
 
@@ -24,10 +25,10 @@ void MQTTPublish(std::string _key, std::string _content, int retained_flag){
         msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
         zw = "sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
         if (debugdetail) LogFile.WriteToFile(zw);
-        ESP_LOGI(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
+        ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
     }
     else {
-        ESP_LOGI(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
+        ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
     }
 }
 
@@ -38,12 +39,12 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
     std::string topic = "";
     switch (event->event_id) {
         case MQTT_EVENT_BEFORE_CONNECT:
-            ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_CONNECTED");
+            ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_BEFORE_CONNECT");
             break;
         case MQTT_EVENT_CONNECTED:
             ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_CONNECTED");
             mqtt_connected = true;
-            MQTTsubscribeFunctions();
+            MQTTconnected();
             break;
         case MQTT_EVENT_DISCONNECTED:
             ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_DISCONNECTED");
@@ -61,19 +62,16 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
             break;
         case MQTT_EVENT_DATA:
             ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_DATA");
-            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
-            printf("DATA=%.*s\r\n", event->data_len, event->data);
+            ESP_LOGI(TAG_INTERFACEMQTT, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
+            ESP_LOGI(TAG_INTERFACEMQTT, "DATA=%.*s\r\n", event->data_len, event->data);
             topic.assign(event->topic, event->topic_len);
             if (subscribeFunktionMap != NULL) {
-                for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
-                    printf("compare %s %s\r\n", it->first.c_str(), topic.c_str());
-                }
                 if (subscribeFunktionMap->find(topic) != subscribeFunktionMap->end()) {
-                    printf("call handler function\r\n");
+                    ESP_LOGD(TAG_INTERFACEMQTT, "call handler function\r\n");
                     (*subscribeFunktionMap)[topic](topic, event->data, event->data_len);
                 }
             } else {
-                printf("no handler available\r\n");
+                ESP_LOGW(TAG_INTERFACEMQTT, "no handler available\r\n");
             }
             break;
         case MQTT_EVENT_ERROR:
@@ -109,7 +107,7 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
     if (_user.length() && _password.length()){
         mqtt_cfg.username = _user.c_str();
         mqtt_cfg.password = _password.c_str();
-        printf("Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
+        ESP_LOGI(TAG_INTERFACEMQTT, "Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
     };
 
     client = esp_mqtt_client_init(&mqtt_cfg);
@@ -130,8 +128,33 @@ bool MQTTisConnected() {
     return mqtt_connected;
 }
 
+void MQTTregisterConnectFunction(std::string name, std::function<void()> func){
+    ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str());
+    if (connectFunktionMap == NULL) {
+        connectFunktionMap = new std::map<std::string, std::function<void()>>();
+    }
+
+    if ((*connectFunktionMap)[name] != NULL) {
+        ESP_LOGW(TAG_INTERFACEMQTT, "connect function %s already registred", name.c_str());
+        return;
+    }
+
+    (*connectFunktionMap)[name] = func;
+
+    if (mqtt_connected) {
+        func();
+    }
+}
+
+void MQTTunregisterConnectFunction(std::string name){
+    ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str());
+    if ((connectFunktionMap != NULL) && (connectFunktionMap->find(name) != connectFunktionMap->end())) {
+        connectFunktionMap->erase(name);
+    }
+}
+
 void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::string, char*, int)> func){
-    printf("MQTTregisterSubscribeFunction %s\r\n", topic.c_str());
+    ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisterSubscribeFunction %s\r\n", topic.c_str());
     if (subscribeFunktionMap == NULL) {
         subscribeFunktionMap = new std::map<std::string, std::function<bool(std::string, char*, int)>>();
     }
@@ -145,16 +168,23 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::st
 
     if (mqtt_connected) {
         int msg_id = esp_mqtt_client_subscribe(client, topic.c_str(), 0);
-        ESP_LOGI(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", topic.c_str(), msg_id);
+        ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", topic.c_str(), msg_id);
     }
 }
 
-void MQTTsubscribeFunctions(){
-    if (subscribeFunktionMap != NULL) {
-        if (mqtt_connected) {
+void MQTTconnected(){
+    if (mqtt_connected) {
+        if (connectFunktionMap != NULL) {
+            for(std::map<std::string, std::function<void()>>::iterator it = connectFunktionMap->begin(); it != connectFunktionMap->end(); ++it) {
+                it->second();
+                ESP_LOGD(TAG_INTERFACEMQTT, "call connect function %s", it->first.c_str());
+            }
+        }
+
+        if (subscribeFunktionMap != NULL) {
             for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
                 int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0);
-                ESP_LOGI(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
+                ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
             }
         }
     }

+ 3 - 1
code/components/jomjol_mqtt/interface_mqtt.h

@@ -14,8 +14,10 @@ void MQTTPublish(std::string _key, std::string _content, int retained_flag = 0);
 
 bool MQTTisConnected();
 
+void MQTTregisterConnectFunction(std::string name, std::function<void()> func);
+void MQTTunregisterConnectFunction(std::string name);
 void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::string, char*, int)> func);
 void MQTTdestroySubscribeFunction();
-void MQTTsubscribeFunctions();
+void MQTTconnected();
 
 #endif //INTERFACE_MQTT_H