You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

202 lines
5.3 KiB

#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 <string.h>
#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);
}
}