diff --git a/components/firmware/include/nx/firmware/MqttClient.h b/components/firmware/include/nx/firmware/MqttClient.h index 9fca9b4..4556dbb 100644 --- a/components/firmware/include/nx/firmware/MqttClient.h +++ b/components/firmware/include/nx/firmware/MqttClient.h @@ -2,10 +2,12 @@ #define COMPONENTS_FIRMWARE_INCLUDE_NX_FIRMWARE_MQTTCLIENT_H_ #include +#include +#include #define MQTT_BROKER_URI_MAX_LEN 128 #define MQTT_TOPIC_MAX_LEN 128 -#define MQTT_USER_MAX_LEN 16 +#define MQTT_USER_MAX_LEN 32 typedef void (*MqttConnectedCallback)(); typedef void (*MqttDisconnectedCallback)(); @@ -17,6 +19,7 @@ typedef struct MqttSettings char brokerAddr[MQTT_BROKER_URI_MAX_LEN]; char apiTopic[MQTT_TOPIC_MAX_LEN]; char hbTopic[MQTT_TOPIC_MAX_LEN]; + char clientId[MQTT_USER_MAX_LEN]; char user[MQTT_USER_MAX_LEN]; char password[MQTT_USER_MAX_LEN]; uint16_t hbIntervalSec; @@ -30,6 +33,8 @@ typedef struct MqttSettings void nxStartMqttClient(const MqttSettings* settings); -void nxMqttHeartbeatTask(void*); +bool nxMqttSubscribe(const char* topic, uint8_t qos); + +uint32_t nxMqttPublish(const char* topic, uint8_t qos, const char* data, size_t size, uint8_t retain); #endif /* COMPONENTS_FIRMWARE_INCLUDE_NX_FIRMWARE_MQTTCLIENT_H_ */ diff --git a/components/firmware/include/nx/firmware/Wifi.h b/components/firmware/include/nx/firmware/Wifi.h index d80c043..78ce942 100644 --- a/components/firmware/include/nx/firmware/Wifi.h +++ b/components/firmware/include/nx/firmware/Wifi.h @@ -31,6 +31,7 @@ bool nxInitWifi(WifiSettings* wifiSettings); void nxSetWifiConnectedCallback(WifiCallback callback); void nxSetWifiErrorCallback(WifiCallback callback); +const char* nxGetWifiDeviceName(void); #endif // COMPONENTS_FIRMWARE_WIFI_H diff --git a/components/firmware/src/HttpHelpers.h b/components/firmware/src/HttpHelpers.h index 17daf20..3897c71 100644 --- a/components/firmware/src/HttpHelpers.h +++ b/components/firmware/src/HttpHelpers.h @@ -6,7 +6,7 @@ typedef void(*RequestCallback)(const uint8_t* content, size_t ctLen, const char** response, size_t* respLen); -#define REQ_CONTENT_MAX_SIZE 1024 +#define REQ_CONTENT_MAX_SIZE 2048 // Request handler helper macro #define ADD_HTTP_HANDLER(_URI, _NAME, _METHOD)\ diff --git a/components/firmware/src/MqTriggerHttpServer.c b/components/firmware/src/MqTriggerHttpServer.c index 08934be..f49c695 100644 --- a/components/firmware/src/MqTriggerHttpServer.c +++ b/components/firmware/src/MqTriggerHttpServer.c @@ -82,6 +82,7 @@ bool nxStartMqTriggerHttpServer(void) config.server_port = 80; config.max_uri_handlers = 16; config.uri_match_fn = httpd_uri_match_wildcard; + config.stack_size = 8192; // ... if (server != NULL) { diff --git a/components/firmware/src/MqttClient.c b/components/firmware/src/MqttClient.c index b879341..2a082b5 100644 --- a/components/firmware/src/MqttClient.c +++ b/components/firmware/src/MqttClient.c @@ -17,12 +17,6 @@ #define UNUSED(x) (void)(x) static const char* TAG = "MQTT"; -static const int CMD_QOS = 2; -//static const int HB_QOS = 1; - -//static const long int MINIMAL_HB_INTERVAL_MS = 1000 * 60; - -static const char* CLIENT_ID = "p10-dev"; static const MqttSettings* settings = NULL; @@ -32,8 +26,6 @@ esp_mqtt_client_handle_t clientHandle = NULL; static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { esp_mqtt_client_handle_t client = event->client; - int msg_id; - // your_context_t *context = event->context; switch (event->event_id) { case MQTT_EVENT_CONNECTED: ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); @@ -42,15 +34,6 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) if (settings->connectedCb) { settings->connectedCb(); } - - msg_id = esp_mqtt_client_subscribe(client, settings->apiTopic, CMD_QOS); - if (msg_id == -1) { - ESP_LOGE(TAG, "Subscribtion failed"); - if (settings->errorCb) { - settings->errorCb(); - } - } - break; case MQTT_EVENT_DISCONNECTED: @@ -78,8 +61,6 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) settings->messageCb(event->data); } - printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); - printf("DATA=%.*s\r\n", event->data_len, event->data); break; case MQTT_EVENT_ERROR: ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); @@ -116,59 +97,42 @@ void nxStartMqttClient(const MqttSettings* mqttSettings) esp_mqtt_client_config_t mqtt_cfg = {}; - mqtt_cfg.uri = settings->brokerAddr; + mqtt_cfg.uri = settings->brokerAddr; + mqtt_cfg.client_id = settings->clientId; + mqtt_cfg.cert_pem = settings->caCrt; + mqtt_cfg.username = settings->user; + mqtt_cfg.password = settings->password; - mqtt_cfg.client_id = CLIENT_ID; - mqtt_cfg.cert_pem = settings->caCrt; - mqtt_cfg.username = settings->user; - mqtt_cfg.password = settings->password; + esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); + esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client); + esp_mqtt_client_start(client); +} - if (mqtt_cfg.host) { - ESP_LOGI(TAG, "host: %s", mqtt_cfg.host); +bool nxMqttSubscribe(const char* topic, uint8_t qos) +{ + if (!clientHandle) { + ESP_LOGE(TAG, "MQTT client not initialized, aborting subscription of topic %s", topic); + return false; } - if (mqtt_cfg.uri) { - ESP_LOGI(TAG, "uri: %s", mqtt_cfg.uri); + + int msg_id = esp_mqtt_client_subscribe(clientHandle, settings->apiTopic, qos); + if (msg_id == -1) { + ESP_LOGE(TAG, "Subscribtion of topic %s failed", topic); + if (settings->errorCb) { + settings->errorCb(); + } + return false; } - ESP_LOGI(TAG, "client: %s", mqtt_cfg.client_id); - ESP_LOGI(TAG, "user: %s", mqtt_cfg.username); - ESP_LOGI(TAG, "pass: %s", mqtt_cfg.password); - ESP_LOGI(TAG, "cert: %s", mqtt_cfg.cert_pem); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client); - esp_mqtt_client_start(client); + return true; } -void nxMqttHeartbeatTask(void* param) +uint32_t nxMqttPublish(const char* topic, uint8_t qos, const char* data, size_t size, uint8_t retain) { - UNUSED(param); - // ESP_LOGI(TAG, "Starting MQTT heartbeat task"); - // - // ESP_LOGI(TAG, "hbIntervalMin: %d", settings->hbIntervalMin); - // - // long int hbIntervalMs = 1000 * 60 * settings->hbIntervalMin; - // - // ESP_LOGI(TAG, "hbIntervalMs: %li", hbIntervalMs); - // - // - // if (hbIntervalMs < MINIMAL_HB_INTERVAL_MS) { - // hbIntervalMs = MINIMAL_HB_INTERVAL_MS; - // } - // - // while (1) { - // if (clientHandle) { - // ESP_LOGI(TAG, "Sending MQTT heartbeat"); - // - // char timeStr[DT_FORMAT_LEN]; - // getTimeStr(timeStr); - // char hbMessage[DT_FORMAT_LEN + strlen(DEVICE_ID) + 2]; - // strcpy(hbMessage, DEVICE_ID); - // strcat(hbMessage, " "); - // strcat(hbMessage, timeStr); - // - // esp_mqtt_client_publish(clientHandle, HEARTBEAT_TOPIC, - // hbMessage, strlen(hbMessage), HB_QOS, 1); - // } - // vTaskDelay(hbIntervalMs / portTICK_PERIOD_MS); - // } + if (!clientHandle) { + ESP_LOGE(TAG, "MQTT client not initialized, aborting data publishing in topic %s", topic); + return -1; + } + return esp_mqtt_client_publish(clientHandle, topic, data, size, qos, retain); } + diff --git a/components/firmware/src/SntpClient.c b/components/firmware/src/SntpClient.c index 91a7890..973f6d1 100644 --- a/components/firmware/src/SntpClient.c +++ b/components/firmware/src/SntpClient.c @@ -8,7 +8,7 @@ static const char* TAG = "SNTP_CLIENT"; -static const char* tzString = "CET-1CEST,M3.5.0,M10.5.0/3"; +static const char* tzString = NULL; bool nxInitSntpClient(int retries, const char* serverAddr, const char* timezoneString) { @@ -35,8 +35,10 @@ void nxGetTimeStr(char buf[DT_FORMAT_LEN]) struct tm timeinfo; time(&now); - setenv("TZ", tzString, 1); - tzset(); + if (tzString) { + setenv("TZ", tzString, 1); + tzset(); + } localtime_r(&now, &timeinfo); strftime(buf, DT_FORMAT_LEN, "%Y-%m-%d %H:%M:%S", &timeinfo); } diff --git a/components/firmware/src/Wifi.c b/components/firmware/src/Wifi.c index 5918c89..fd5100f 100644 --- a/components/firmware/src/Wifi.c +++ b/components/firmware/src/Wifi.c @@ -43,7 +43,7 @@ static WifiSettings* settings = NULL; static WifiCallback errorCallback = NULL; static WifiCallback connectedCallback = NULL; -static char deviceName[DEVICE_NAME_MAX_LEN]; +static char deviceName[DEVICE_NAME_MAX_LEN] = {0}; static bool initWifiStation(void); @@ -342,3 +342,15 @@ static bool initWifiStation(void) return waitForStaConnection(); } +const char* nxGetWifiDeviceName(void) +{ + if (settings && settings->devicePrefix && strlen(deviceName) == 0) { + generateDeviceName(); + return deviceName; + } + else if (strlen(deviceName)) { + return deviceName; + } + return "unknown"; +} + diff --git a/components/software/include/nx/software/AppSettings.h b/components/software/include/nx/software/AppSettings.h index e31e946..25559a8 100644 --- a/components/software/include/nx/software/AppSettings.h +++ b/components/software/include/nx/software/AppSettings.h @@ -8,6 +8,8 @@ #define WIFI_STRINGS_MAX_LEN 32 #define URI_MAX_SIZE 64 #define USER_DATA_MAX_SIZE 16 +#define CA_CERT_MAX_SIZE 1500 +#define DEVICE_NAME_MAX_LEN 64 typedef bool (*StorageReadFn)(const char* key, void* data, size_t size); @@ -23,7 +25,9 @@ typedef struct AppSettings { char mqttPassword[USER_DATA_MAX_SIZE]; uint16_t mqttHbIntervalSec; uint8_t mqttUseTls; - + char caCert[CA_CERT_MAX_SIZE]; + bool overrideDevName; + char customDevName[DEVICE_NAME_MAX_LEN]; } AppSettings; diff --git a/components/software/include/nx/software/SystemSettings.h b/components/software/include/nx/software/SystemSettings.h index 6cdeb92..b27de1f 100644 --- a/components/software/include/nx/software/SystemSettings.h +++ b/components/software/include/nx/software/SystemSettings.h @@ -26,6 +26,7 @@ typedef struct SystemSettings { char sntpAddr[URI_MAX_LEN]; char tzEnv[TZ_ENV_LEN]; char rsSchedule[RESTART_SCHEDULE_SIZE]; + const char* deviceName; // set in the main component } SystemSettings; diff --git a/components/software/src/AppSettings.c b/components/software/src/AppSettings.c index c74194b..8ff3f11 100644 --- a/components/software/src/AppSettings.c +++ b/components/software/src/AppSettings.c @@ -10,6 +10,9 @@ #define KEY_MQTT_TLS "mqtls" #define KEY_MQTT_USER "mquser" #define KEY_MQTT_PASS "mqpass" +#define KEY_OVR_DEVNAME "ovdn" +#define KEY_CUSTOM_DEVNAME "cdn" +#define KEY_CA_CERT "cacert" #define STORAGE_READ(_KEY, _NAME)\ storageRead(_KEY, &settings._NAME, sizeof(settings._NAME)); @@ -19,13 +22,16 @@ static const uint8_t INIT_FLAG_VALUE = 1; -static const char* DEFAULT_MQTT_HOST = ""; -static const char* DEFAULT_MQTT_API_URI = "dev/api"; -static const char* DEFAULT_MQTT_HB_URI = "dev/hb"; -static const uint16_t DEFAULT_MQTT_HB_SEC = 60 * 15; -static const uint8_t DEFAULT_MQTT_TLS = 0; -static const char* DEFAULT_MQTT_USER = ""; -static const char* DEFAULT_MQTT_PASS = ""; +static const char* DEFAULT_MQTT_HOST = ""; +static const char* DEFAULT_MQTT_API_URI = "dev/api"; +static const char* DEFAULT_MQTT_HB_URI = "dev/hb"; +static const uint16_t DEFAULT_MQTT_HB_SEC = 60 * 15; +static const uint8_t DEFAULT_MQTT_TLS = 0; +static const char* DEFAULT_MQTT_USER = ""; +static const char* DEFAULT_MQTT_PASS = ""; +static const bool DEFAULT_OV_DEVNAME = false; +static const char* DEFAULT_CUSTOM_DEVNAME = "esp-dev"; +static const char* DEFAULT_CA_CERT = "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n"; static StorageWriteFn storageWrite = NULL; @@ -46,13 +52,16 @@ static bool firstRun(void) static void loadSettings(void) { printf("Loading application settings\n"); - STORAGE_READ(KEY_MQTT_HOST , mqttHost ); - STORAGE_READ(KEY_MQTT_API_URI, mqttApiUri ); - STORAGE_READ(KEY_MQTT_HB_URI , mqttHbUri ); - STORAGE_READ(KEY_MQTT_HB_SEC , mqttHbIntervalSec); - STORAGE_READ(KEY_MQTT_TLS , mqttUseTls ); - STORAGE_READ(KEY_MQTT_USER , mqttUser ); - STORAGE_READ(KEY_MQTT_PASS , mqttPassword ); + STORAGE_READ(KEY_MQTT_HOST , mqttHost ); + STORAGE_READ(KEY_MQTT_API_URI , mqttApiUri ); + STORAGE_READ(KEY_MQTT_HB_URI , mqttHbUri ); + STORAGE_READ(KEY_MQTT_HB_SEC , mqttHbIntervalSec); + STORAGE_READ(KEY_MQTT_TLS , mqttUseTls ); + STORAGE_READ(KEY_MQTT_USER , mqttUser ); + STORAGE_READ(KEY_MQTT_PASS , mqttPassword ); + STORAGE_READ(KEY_OVR_DEVNAME , overrideDevName ); + STORAGE_READ(KEY_CUSTOM_DEVNAME , customDevName ); + STORAGE_READ(KEY_CA_CERT , caCert ); } @@ -87,11 +96,15 @@ void nxRestoreAppDefaultSettings(void) settings.mqttHbIntervalSec = DEFAULT_MQTT_HB_SEC; settings.mqttUseTls = DEFAULT_MQTT_TLS; - strcpy(settings.mqttHbUri , DEFAULT_MQTT_HB_URI ); - strcpy(settings.mqttApiUri , DEFAULT_MQTT_API_URI); - strcpy(settings.mqttHost , DEFAULT_MQTT_HOST ); - strcpy(settings.mqttUser , DEFAULT_MQTT_USER ); - strcpy(settings.mqttPassword, DEFAULT_MQTT_PASS ); + strcpy(settings.mqttHbUri , DEFAULT_MQTT_HB_URI ); + strcpy(settings.mqttApiUri , DEFAULT_MQTT_API_URI ); + strcpy(settings.mqttHost , DEFAULT_MQTT_HOST ); + strcpy(settings.mqttUser , DEFAULT_MQTT_USER ); + strcpy(settings.mqttPassword , DEFAULT_MQTT_PASS ); + strcpy(settings.caCert , DEFAULT_CA_CERT ); + strcpy(settings.customDevName , DEFAULT_CUSTOM_DEVNAME); + + settings.overrideDevName = DEFAULT_OV_DEVNAME; nxWriteAppSettings(); } @@ -102,14 +115,16 @@ void nxWriteAppSettings(void) printf("WRITING APPLICATION SETTINGS\n"); storageWrite(KEY_INIT_FLAG , &INIT_FLAG_VALUE , 1); - STORAGE_WRITE(KEY_MQTT_HOST , mqttHost ); - STORAGE_WRITE(KEY_MQTT_API_URI, mqttApiUri ); - STORAGE_WRITE(KEY_MQTT_HB_URI , mqttHbUri ); - STORAGE_WRITE(KEY_MQTT_HB_SEC , mqttHbIntervalSec); - STORAGE_WRITE(KEY_MQTT_TLS , mqttUseTls ); - STORAGE_WRITE(KEY_MQTT_USER , mqttUser ); - STORAGE_WRITE(KEY_MQTT_PASS , mqttPassword ); - + STORAGE_WRITE(KEY_MQTT_HOST , mqttHost ); + STORAGE_WRITE(KEY_MQTT_API_URI , mqttApiUri ); + STORAGE_WRITE(KEY_MQTT_HB_URI , mqttHbUri ); + STORAGE_WRITE(KEY_MQTT_HB_SEC , mqttHbIntervalSec); + STORAGE_WRITE(KEY_MQTT_TLS , mqttUseTls ); + STORAGE_WRITE(KEY_MQTT_USER , mqttUser ); + STORAGE_WRITE(KEY_MQTT_PASS , mqttPassword ); + STORAGE_WRITE(KEY_CA_CERT , caCert ); + STORAGE_WRITE(KEY_CUSTOM_DEVNAME , customDevName ); + STORAGE_WRITE(KEY_OVR_DEVNAME , overrideDevName ); settingsUpdatedCb(); } diff --git a/components/software/src/AppSettingsApi.c b/components/software/src/AppSettingsApi.c index dc350ce..3e0b586 100644 --- a/components/software/src/AppSettingsApi.c +++ b/components/software/src/AppSettingsApi.c @@ -15,23 +15,26 @@ #define API_KEY_MQTT_TLS "mqtls" #define API_KEY_MQTT_USER "mquser" #define API_KEY_MQTT_PASS "mqpass" +#define API_KEY_CA_CERT "cacert" +#define API_KEY_OV_DEVNAME "ovdn" +#define API_KEY_CUSTOM_DEVNAME "cdn" #define UNUSED(x) (void)(x) -#define RESP_BUF_SIZE 1024 +#define RESP_BUF_SIZE 2048 char responseBuffer[RESP_BUF_SIZE]; static void handleKvPair(const char* key, const char* value, const void* userData, bool* done) { - printf("LED display settings update; Key: %s, Value: %s\n", key, value); + printf("App settings update; Key: %s, Value: %s\n", key, value); AppSettings* settings = nxGetAppSettings(); if (strcmp(key, API_KEY_RESTORE) == 0) { nxRestoreAppDefaultSettings(); } else if (strcmp(key, API_KEY_MQTT_HOST) == 0) { - strcpy(settings->mqttHost, value); + strcpy(settings->mqttHost, value); } else if (strcmp(key, API_KEY_MQTT_API_URI) == 0) { strcpy(settings->mqttApiUri, value); @@ -46,10 +49,19 @@ static void handleKvPair(const char* key, const char* value, const void* userDat strcpy(settings->mqttPassword, value); } else if (strcmp(key, API_KEY_MQTT_HB_SEC) == 0) { - settings->mqttHbIntervalSec = atoi(value); + settings->mqttHbIntervalSec = atoi(value); } else if (strcmp(key, API_KEY_MQTT_TLS) == 0) { - settings->mqttUseTls = atoi(value); + settings->mqttUseTls = atoi(value); + } + else if (strcmp(key, API_KEY_CA_CERT) == 0) { + strcpy(settings->caCert, value); + } + else if (strcmp(key, API_KEY_CUSTOM_DEVNAME) == 0) { + strcpy(settings->customDevName, value); + } + else if (strcmp(key, API_KEY_OV_DEVNAME) == 0) { + settings->overrideDevName = atoi(value); } else { fprintf(stderr, "Unknown key: %s\n", key); @@ -59,7 +71,7 @@ static void handleKvPair(const char* key, const char* value, const void* userDat // --------- Public API --------- // void nxApiGetAppSettings(const uint8_t* msg, size_t msgLen, - const char** response, size_t* respLen) + const char** response, size_t* respLen) { UNUSED(msg); UNUSED(msgLen); memset(responseBuffer, 0, RESP_BUF_SIZE); @@ -72,14 +84,18 @@ void nxApiGetAppSettings(const uint8_t* msg, size_t msgLen, "\"%s\":\"%s\", " "\"%s\":%i, " // hb interval "\"%s\":%i, " - "\"%s\":\"%s\" " // mqtt user + "\"%s\":\"%s\", " // mqtt user + "\"%s\":%i," // ovdn + "\"%s\":\"%s\"" // cdn "}", - API_KEY_MQTT_HOST , settings->mqttHost , - API_KEY_MQTT_API_URI, settings->mqttApiUri , - API_KEY_MQTT_HB_URI , settings->mqttHbUri , - API_KEY_MQTT_HB_SEC , settings->mqttHbIntervalSec, - API_KEY_MQTT_TLS , settings->mqttUseTls , - API_KEY_MQTT_USER , settings->mqttUser + API_KEY_MQTT_HOST , settings->mqttHost , + API_KEY_MQTT_API_URI , settings->mqttApiUri , + API_KEY_MQTT_HB_URI , settings->mqttHbUri , + API_KEY_MQTT_HB_SEC , settings->mqttHbIntervalSec, + API_KEY_MQTT_TLS , settings->mqttUseTls , + API_KEY_MQTT_USER , settings->mqttUser , + API_KEY_OV_DEVNAME , settings->overrideDevName , + API_KEY_CUSTOM_DEVNAME, settings->customDevName ); *response = responseBuffer; *respLen = strlen(responseBuffer); diff --git a/components/software/src/KeyValueParser.c b/components/software/src/KeyValueParser.c index 6edfb3e..fd0196c 100644 --- a/components/software/src/KeyValueParser.c +++ b/components/software/src/KeyValueParser.c @@ -1,24 +1,25 @@ #include "KeyValueParser.h" #include +#include #include #define MAX_KEY_SIZE 32 -#define MAX_VALUE_SIZE 32 #define MAX_PAIRS 16 void nxParseKeyValueString(const char* string, KeyValueHandler handler, const void* userData) { bool done = false; char key[MAX_KEY_SIZE]; - char value[MAX_VALUE_SIZE]; + char* value = calloc(1, strlen(string)); FILE *stream; stream = fmemopen((void*)string, strlen(string), "r"); int maxPairs = MAX_PAIRS; - while (fscanf(stream, "%127[^=]=%127[^&]%*c", key, value) == 2 && maxPairs > 0 && !done) { + while (fscanf(stream, "%32[^=]=%2048[^&]%*c", key, value) == 2 && maxPairs > 0 && !done) { handler(key, value, userData, &done); maxPairs -= 1; } fclose(stream); + free(value); } diff --git a/components/software/src/SystemSettings.c b/components/software/src/SystemSettings.c index 7387bf6..ec4c685 100644 --- a/components/software/src/SystemSettings.c +++ b/components/software/src/SystemSettings.c @@ -54,15 +54,15 @@ static bool firstRun(void) static void loadSystemSettings(void) { printf("Loading system settings\n"); - storageRead(KEY_WIFI_SSID , settings.wifiSsid , WIFI_STRINGS_MAX_LEN); - storageRead(KEY_WIFI_PASS , settings.wifiPassword, WIFI_STRINGS_MAX_LEN); - storageRead(KEY_WIFI_ADDR , settings.ip4addr , IPV4_ADDR_SIZE); - storageRead(KEY_WIFI_GW , settings.ip4gw , IPV4_ADDR_SIZE); - storageRead(KEY_WIFI_MASK , settings.ip4mask , IPV4_ADDR_SIZE); - storageRead(KEY_DNS_ADDR , settings.dnsAddr , IPV4_ADDR_SIZE); - storageRead(KEY_SNTP_ADDR , settings.sntpAddr , URI_MAX_LEN); - storageRead(KEY_TZ_ENV , settings.tzEnv , TZ_ENV_LEN); - storageRead(KEY_RS_SCHEDULE , settings.rsSchedule , RESTART_SCHEDULE_SIZE); + storageRead(KEY_WIFI_SSID , settings.wifiSsid , WIFI_STRINGS_MAX_LEN); + storageRead(KEY_WIFI_PASS , settings.wifiPassword , WIFI_STRINGS_MAX_LEN); + storageRead(KEY_WIFI_ADDR , settings.ip4addr , IPV4_ADDR_SIZE); + storageRead(KEY_WIFI_GW , settings.ip4gw , IPV4_ADDR_SIZE); + storageRead(KEY_WIFI_MASK , settings.ip4mask , IPV4_ADDR_SIZE); + storageRead(KEY_DNS_ADDR , settings.dnsAddr , IPV4_ADDR_SIZE); + storageRead(KEY_SNTP_ADDR , settings.sntpAddr , URI_MAX_LEN); + storageRead(KEY_TZ_ENV , settings.tzEnv , TZ_ENV_LEN); + storageRead(KEY_RS_SCHEDULE , settings.rsSchedule , RESTART_SCHEDULE_SIZE); STORAGE_READ(KEY_WIFI_POWER_SAVE, wifiPowerSave); STORAGE_READ(KEY_WIFI_USE_STATIC, useStaticAddr); @@ -115,18 +115,18 @@ void nxWriteSystemSettings(void) printf("WRITING SYSTEM SETTINGS\n"); storageWrite(KEY_INIT_FLAG, &INIT_FLAG_VALUE, 1); - storageWrite(KEY_WIFI_SSID , settings.wifiSsid , WIFI_STRINGS_MAX_LEN ); - storageWrite(KEY_WIFI_PASS , settings.wifiPassword, WIFI_STRINGS_MAX_LEN ); - storageWrite(KEY_WIFI_ADDR , settings.ip4addr , IPV4_ADDR_SIZE ); - storageWrite(KEY_WIFI_GW , settings.ip4gw , IPV4_ADDR_SIZE ); - storageWrite(KEY_WIFI_MASK , settings.ip4mask , IPV4_ADDR_SIZE ); - storageWrite(KEY_DNS_ADDR , settings.dnsAddr , IPV4_ADDR_SIZE ); - storageWrite(KEY_SNTP_ADDR , settings.sntpAddr , URI_MAX_LEN ); - storageWrite(KEY_TZ_ENV , settings.tzEnv , TZ_ENV_LEN ); - storageWrite(KEY_RS_SCHEDULE , settings.rsSchedule , RESTART_SCHEDULE_SIZE ); - - STORAGE_WRITE(KEY_WIFI_POWER_SAVE, wifiPowerSave); - STORAGE_WRITE(KEY_WIFI_USE_STATIC, useStaticAddr); + storageWrite(KEY_WIFI_SSID , settings.wifiSsid , WIFI_STRINGS_MAX_LEN ); + storageWrite(KEY_WIFI_PASS , settings.wifiPassword , WIFI_STRINGS_MAX_LEN ); + storageWrite(KEY_WIFI_ADDR , settings.ip4addr , IPV4_ADDR_SIZE ); + storageWrite(KEY_WIFI_GW , settings.ip4gw , IPV4_ADDR_SIZE ); + storageWrite(KEY_WIFI_MASK , settings.ip4mask , IPV4_ADDR_SIZE ); + storageWrite(KEY_DNS_ADDR , settings.dnsAddr , IPV4_ADDR_SIZE ); + storageWrite(KEY_SNTP_ADDR , settings.sntpAddr , URI_MAX_LEN ); + storageWrite(KEY_TZ_ENV , settings.tzEnv , TZ_ENV_LEN ); + storageWrite(KEY_RS_SCHEDULE , settings.rsSchedule , RESTART_SCHEDULE_SIZE ); + + STORAGE_WRITE(KEY_WIFI_POWER_SAVE, wifiPowerSave ); + STORAGE_WRITE(KEY_WIFI_USE_STATIC, useStaticAddr ); } SystemSettings* nxGetSystemSettings(void) diff --git a/components/software/src/SystemSettingsApi.c b/components/software/src/SystemSettingsApi.c index 1915cd8..005e5e7 100644 --- a/components/software/src/SystemSettingsApi.c +++ b/components/software/src/SystemSettingsApi.c @@ -14,18 +14,19 @@ ssid=myssid&wpass=mypassword&wpwsave=1&wstatic=1&ip=3232237657&gw=3232237569&mask=4294967040 */ -#define API_KEY_SSID "ssid" -#define API_KEY_WPASS "wpass" -#define API_KEY_WPWSAVE "wpwsave" -#define API_KEY_USE_STATIC "wstatic" -#define API_KEY_IPV4ADDR "ip" -#define API_KEY_IPV4GW "gw" -#define API_KEY_IPV4MASK "mask" -#define API_KEY_DNS_ADDR "dns" -#define API_KEY_SNTP_ADDR "sntp" -#define API_KEY_TZ_ENV "tz" -#define API_KEY_RS_SCHEDULE "rsch" -#define API_KEY_RESTORE "restore_default" +#define API_KEY_SSID "ssid" +#define API_KEY_WPASS "wpass" +#define API_KEY_WPWSAVE "wpwsave" +#define API_KEY_USE_STATIC "wstatic" +#define API_KEY_IPV4ADDR "ip" +#define API_KEY_IPV4GW "gw" +#define API_KEY_IPV4MASK "mask" +#define API_KEY_DNS_ADDR "dns" +#define API_KEY_SNTP_ADDR "sntp" +#define API_KEY_TZ_ENV "tz" +#define API_KEY_RS_SCHEDULE "rsch" +#define API_KEY_DEVNAME "dn" +#define API_KEY_RESTORE "restore_default" #define UNUSED(x) (void)(x) @@ -111,7 +112,8 @@ void nxApiGetSystemSettings(const uint8_t* msg, size_t msgLen, "\"%s\":\"%i.%i.%i.%i\"," // dns "\"%s\":\"%s\"," // sntp "\"%s\":\"%s\"," // tz - "\"%s\":\"%s\"" // rsch + "\"%s\":\"%s\"," // rsch + "\"%s\":\"%s\"" // dn "}", API_KEY_SSID, settings->wifiSsid, API_KEY_WPWSAVE, settings->wifiPowerSave ? "true" : "false", @@ -122,7 +124,8 @@ void nxApiGetSystemSettings(const uint8_t* msg, size_t msgLen, API_KEY_DNS_ADDR, settings->dnsAddr[0], settings->dnsAddr[1], settings->dnsAddr[2], settings->dnsAddr[3], API_KEY_SNTP_ADDR, settings->sntpAddr, API_KEY_TZ_ENV, settings->tzEnv, - API_KEY_RS_SCHEDULE, settings->rsSchedule + API_KEY_RS_SCHEDULE, settings->rsSchedule, + API_KEY_DEVNAME, settings->deviceName ); *response = responseBuffer; *respLen = strlen(responseBuffer); diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 951a46b..8f41576 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -12,4 +12,3 @@ target_add_binary_data(${COMPONENT_TARGET} "static/min/index.css" TEXT) target_add_binary_data(${COMPONENT_TARGET} "static/min/index.js" TEXT) target_add_binary_data(${COMPONENT_TARGET} "static/min/sys.html" TEXT) target_add_binary_data(${COMPONENT_TARGET} "static/min/app.html" TEXT) -target_add_binary_data(${COMPONENT_TARGET} "static/ca.crt" TEXT) diff --git a/main/Main.c b/main/Main.c index 839b6bf..1df392d 100644 --- a/main/Main.c +++ b/main/Main.c @@ -24,10 +24,10 @@ #define TAG "MAIN" #define SNTP_RETRIES 8 +#define API_QOS 2 +#define HB_QOS 1 -static const char* DEVICE_NAME_PREFIX = "mqtrigger-"; - -extern const char ca_crt_start[] asm("_binary_ca_crt_start"); +static const char* DEVICE_NAME_PREFIX = "mqt-"; static void startWifi(void); static void onWifiConnected(void); @@ -38,6 +38,8 @@ 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; @@ -53,7 +55,7 @@ static const MqTriggerHttpCallbacks httpCallbacks = { .postSysSet = nxApiUpdateSystemSettings, .getAppSet = nxApiGetAppSettings, .postAppSet = nxApiUpdateAppSettings -// .postCmd = nxApiHandleLedCmd + // .postCmd = nxApiHandleCmd }; void app_main(void) @@ -81,8 +83,6 @@ void app_main(void) static void startWifi(void) { - strcpy(systemSettings->wifiSsid, "cintra"); - strcpy(systemSettings->wifiPassword, "fffefdfcfb"); systemSettings->useStaticAddr = true; systemSettings->ip4addr[3] = 91; @@ -106,15 +106,22 @@ static void startWifi(void) 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 ? ca_crt_start : NULL; + mqttSettings.caCrt = appSettings->mqttUseTls ? appSettings->caCert : NULL; mqttSettings.messageCb = onMqttMessage; mqttSettings.connectedCb = onMqttConnected; mqttSettings.disconnectedCb = onMqttDisconnected; @@ -147,7 +154,10 @@ static void onWifiError() static void onMqttConnected() { ESP_LOGI(TAG, "MQTT CONNECTED"); - nxUpdateStatus(STATUS_OK); + if (nxMqttSubscribe(appSettings->mqttApiUri, API_QOS)) { + xTaskCreate(&hbTask, "hb_task", 2048, NULL, 1, NULL); + nxUpdateStatus(STATUS_OK); + } } static void onMqttDisconnected() @@ -161,3 +171,32 @@ 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); + } +} diff --git a/main/static/app.html b/main/static/app.html index 5fcb15a..c0f088e 100644 --- a/main/static/app.html +++ b/main/static/app.html @@ -48,6 +48,27 @@

+

+ +

+ +

+ +

+ +

+

+ +

+

@@ -61,7 +82,6 @@ -

Restore defaults

diff --git a/main/static/index.js b/main/static/index.js index ad716af..821a946 100644 --- a/main/static/index.js +++ b/main/static/index.js @@ -1,3 +1,5 @@ +var valuesCache = {}; + function ip2int(ip) { return ip.split('.').reduce(function(ipInt, octet) { return (ipInt<<8) + parseInt(octet, 10)}, 0) >>> 0; } @@ -70,16 +72,37 @@ function loadContent(url) { } function loadValues(element) { + const forms = element.querySelectorAll('form'); for (i = 0; i < forms.length; ++i) { const srcUrl = forms[i].getAttribute('data-values-src'); if (!srcUrl) { continue; } + + if (valuesCache[srcUrl]) { + console.log("Source values already cached: " + valuesCache[srcUrl]); + //TODO: dry + let obj = JSON.parse(valuesCache[srcUrl]); + if (obj) { + for (var key of Object.keys(obj)) { + console.log(key + " -> " + obj[key]) + let input = element.querySelector("[name='" + key + "'"); + if (input) { //TODO: checkbox/radio + input.value = obj[key]; + if (input.hasAttribute('data-onset')) { + eval(input.getAttribute("data-onset")); + } + } + } + } + continue; + } + console.log("Getting values from " + srcUrl); let http = new XMLHttpRequest(); - http.open('GET', srcUrl, true); + http.open('GET', srcUrl, false); //Send the proper header information along with the request //http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); @@ -87,6 +110,9 @@ function loadValues(element) { http.onreadystatechange = function () {//Call a function when the state changes. if (http.readyState == 4 && http.status == 200) { console.log("Values received: " + http.responseText); + valuesCache[srcUrl] = http.responseText; + + //TODO: dry let obj = JSON.parse(http.responseText); if (obj) { for (var key of Object.keys(obj)) { diff --git a/main/static/min/app.html b/main/static/min/app.html index 4f715c8..c9a2f61 100644 --- a/main/static/min/app.html +++ b/main/static/min/app.html @@ -7,4 +7,8 @@

NOTE: device reboot is required

Restore defaults


Reboot

\ No newline at end of file +