diff --git a/code/components/jomjol_controlGPIO/server_GPIO.cpp b/code/components/jomjol_controlGPIO/server_GPIO.cpp index 19953b85..bb2901a8 100644 --- a/code/components/jomjol_controlGPIO/server_GPIO.cpp +++ b/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::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 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::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::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) { diff --git a/code/components/jomjol_controlGPIO/server_GPIO.h b/code/components/jomjol_controlGPIO/server_GPIO.h index 5745579b..14d88412 100644 --- a/code/components/jomjol_controlGPIO/server_GPIO.h +++ b/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 *gpioMap = NULL; - TaskHandle_t xHandletaskGpioHandler = NULL; + TaskHandle_t xHandleTaskGpio = NULL; bool _isEnabled = false; bool readConfig(); diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index 580761d5..3230cb8f 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/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>* connectFunktionMap = NULL; std::map>* 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>::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 func){ + ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str()); + if (connectFunktionMap == NULL) { + connectFunktionMap = new std::map>(); + } + + 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 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>(); } @@ -145,16 +168,23 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function>::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>::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); } } } diff --git a/code/components/jomjol_mqtt/interface_mqtt.h b/code/components/jomjol_mqtt/interface_mqtt.h index 81685d88..50990e6f 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.h +++ b/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 func); +void MQTTunregisterConnectFunction(std::string name); void MQTTregisterSubscribeFunction(std::string topic, std::function func); void MQTTdestroySubscribeFunction(); -void MQTTsubscribeFunctions(); +void MQTTconnected(); #endif //INTERFACE_MQTT_H \ No newline at end of file