#include "nx/software/SystemSettings.h" #include "nx/software/SystemSettingsApi.h" #include "nx/software/AppSettings.h" #include "nx/software/AppSettingsApi.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "nx/firmware/Storage.h" #include "nx/firmware/Wifi.h" #include "nx/firmware/MqTriggerHttpServer.h" #include "nx/firmware/MqttClient.h" #include "nx/firmware/SntpClient.h" #include "nx/firmware/StatusIndicator.h" #include "nx/firmware/Restarter.h" #include "HttpHandlers.h" #include "esp_log.h" #include #define TAG "MAIN" #define SNTP_RETRIES 8 #define API_QOS 2 #define HB_QOS 1 static const char* DEVICE_NAME_PREFIX = "mqt-"; static void startWifi(void); static void onWifiConnected(void); static void onWifiError(void); static void onAppSettingsUpdate(void); static void onMqttConnected(); static void onMqttDisconnected(); static void onMqttError(); static void onMqttMessage(const char* msg); static void hbTask(void*); static SystemSettings* systemSettings = NULL; static AppSettings* appSettings = NULL; static WifiSettings wifiSettings; static MqttSettings mqttSettings; static const MqTriggerHttpCallbacks httpCallbacks = { .getRoot = rootHandler, .getJs = jsHandler, .getCss = cssHandler, .getSysSetForm = sysFormHandler, .getAppSetForm = appFormHandler, .getSysSet = nxApiGetSystemSettings, .postSysSet = nxApiUpdateSystemSettings, .getAppSet = nxApiGetAppSettings, .postAppSet = nxApiUpdateAppSettings // .postCmd = nxApiHandleCmd }; void app_main(void) { nxInitStatusIndicator(); nxUpdateStatus(STATUS_BOOT); xTaskCreate(&nxStatusIndicatorTask, "status_task", 2048, NULL, 1, NULL); nxInitStorage(); nxInitSystemSettings(nxStorageWrite, nxStorageRead); nxInitAppSettings(nxStorageWrite, nxStorageRead, onAppSettingsUpdate); systemSettings = nxGetSystemSettings(); appSettings = nxGetAppSettings(); nxStartRestarter(systemSettings->rsSchedule, systemSettings->tzEnv); nxSetWifiConnectedCallback(onWifiConnected); nxSetWifiErrorCallback(onWifiError); startWifi(); } // ----- static void startWifi(void) { systemSettings->useStaticAddr = true; systemSettings->ip4addr[3] = 91; wifiSettings = (struct WifiSettings){ .wname = systemSettings->wifiSsid, .wpass = systemSettings->wifiPassword, .devicePrefix = DEVICE_NAME_PREFIX, .usePowerSave = &(systemSettings->wifiPowerSave), .useStaticAddr = &(systemSettings->useStaticAddr), .ip4addr = systemSettings->ip4addr, .ip4gw = systemSettings->ip4gw, .ip4mask = systemSettings->ip4mask, .dns = systemSettings->dnsAddr }; ESP_LOGI(TAG, "Initializing WiFi"); if (!nxInitWifi(&wifiSettings)) { nxUpdateStatus(STATUS_SYSTEM_ERROR); } } static void onWifiConnected(void) { systemSettings->deviceName = nxGetWifiDeviceName(); nxInitSntpClient(SNTP_RETRIES, systemSettings->sntpAddr, systemSettings->tzEnv); strcpy(mqttSettings.brokerAddr, appSettings->mqttHost); strcpy(mqttSettings.apiTopic, appSettings->mqttApiUri); strcpy(mqttSettings.hbTopic, appSettings->mqttHbUri); strcpy(mqttSettings.user, appSettings->mqttUser); strcpy(mqttSettings.password, appSettings->mqttPassword); strcpy(mqttSettings.clientId, appSettings->overrideDevName ? appSettings->customDevName : systemSettings->deviceName); mqttSettings.hbIntervalSec = appSettings->mqttHbIntervalSec; mqttSettings.caCrt = appSettings->mqttUseTls ? appSettings->caCert : NULL; mqttSettings.messageCb = onMqttMessage; mqttSettings.connectedCb = onMqttConnected; mqttSettings.disconnectedCb = onMqttDisconnected; mqttSettings.errorCb = onMqttError; nxStartMqttClient(&mqttSettings); nxSetMqTriggerHttpCallbacks(&httpCallbacks); nxStartMqTriggerHttpServer(); } static void onAppSettingsUpdate(void) { ESP_LOGI(TAG, "App settings updated"); nxUpdateStatus(STATUS_OK_WORKING); } static void onMqttMessage(const char* msg) { ESP_LOGI(TAG, "MQTT MESSAGE RECEIVED: %s", msg); nxUpdateStatus(STATUS_OK_WORKING); } static void onWifiError() { ESP_LOGE(TAG, "WiFi ERROR"); nxUpdateStatus(STATUS_SYSTEM_ERROR); } static void onMqttConnected() { ESP_LOGI(TAG, "MQTT CONNECTED"); if (nxMqttSubscribe(appSettings->mqttApiUri, API_QOS)) { xTaskCreate(&hbTask, "hb_task", 2048, NULL, 1, NULL); nxUpdateStatus(STATUS_OK); } } static void onMqttDisconnected() { ESP_LOGW(TAG, "MQTT DISCONNECTED"); nxUpdateStatus(STATUS_APP_ERROR); } static void onMqttError() { ESP_LOGE(TAG, "MQTT ERROR"); nxUpdateStatus(STATUS_APP_ERROR); } static void hbTask(void* param) { // UNUSED(param); ESP_LOGI(TAG, "Starting MQTT heartbeat task"); ESP_LOGI(TAG, "hbIntervalSec: %d", appSettings->mqttHbIntervalSec); if (appSettings->mqttHbIntervalSec < 1) { ESP_LOGI(TAG, "Heartbeat interval < 1 sec, skipping"); vTaskDelete(NULL); return; } while (1) { ESP_LOGI(TAG, "Sending MQTT heartbeat"); char timeStr[DT_FORMAT_LEN]; nxGetTimeStr(timeStr); char hbMessage[DT_FORMAT_LEN + strlen(nxGetWifiDeviceName()) + 2]; strcpy(hbMessage, nxGetWifiDeviceName()); strcat(hbMessage, " "); strcat(hbMessage, timeStr); nxMqttPublish(appSettings->mqttHbUri, HB_QOS, hbMessage, strlen(hbMessage), 1); vTaskDelay(appSettings->mqttHbIntervalSec*1000 / portTICK_PERIOD_MS); } }