2 Commits

Author SHA1 Message Date
cbb6b77f01 Version 1.0.4
Added saving configuration in NVS memory.
2024-06-12 07:03:26 +03:00
482903cecf Version 1.0.3
Added checking device availability.
2024-06-10 18:46:44 +03:00
4 changed files with 337 additions and 179 deletions

View File

@ -12,13 +12,14 @@ Gateway for ESP32 ESP-IDF for data exchange between ESP-NOW devices and MQTT bro
2. Automatically adds supported devices configurations to Home Assistan via MQTT discovery.
3. Update firmware from HTTPS server via OTA.
4. Update firmware of supported devices from HTTPS server via ESP-NOW.
5. Direct or mesh work mode.
5. LAN or WiFi connection to router.
6. Direct or mesh work mode.
## Notes
1. All devices on the network must have the same work mode.
2. ESP-NOW mesh network based on the [zh_network](https://github.com/aZholtikov/zh_network).
3. For initial settings use "menuconfig -> ZH Gateway Configuration".
3. For initial settings use "menuconfig -> ZH Gateway Configuration". After first boot all settings (except work mode) will be stored in NVS memory for prevente change during OTA firmware update.
4. To restart the gateway, send the "restart" command to the root topic of the gateway (example - "homeassistant/gateway/70-03-9F-44-BE-F7").
5. To update the gateway firmware, send the "update" command to the root topic of the gateway (example - "homeassistant/gateway/70-03-9F-44-BE-F7"). The update path should be like as "https://your_server/zh_gateway_esp32.bin". The online status of the update is displayed in the root gateway topic.
@ -37,7 +38,7 @@ idf.py flash
## Attention
1. The program is written for and tested only on [LILYGO T-ETH-Lite ESP32](https://github.com/Xinyuan-LilyGO/LilyGO-T-ETH-Series). To work on another module it will be necessary change ZH_LAN_MODULE_TYPE and ZH_LAN_MODULE_POWER_PIN (for using LAN connection only). No changes are required when using a WiFi connection.
1. The program is tested on [LILYGO T-ETH-Lite ESP32](https://github.com/Xinyuan-LilyGO/LilyGO-T-ETH-Series) and [Wireless-Tag WT32-ETH01](https://github.com/ldijkman/WT32-ETH01-LAN-8720-RJ45-). To work on another module it will be necessary change ZH_LAN_MODULE_TYPE and ZH_LAN_MODULE_POWER_PIN (for using LAN connection only). No changes are required when using a WiFi connection.
2. If using a WiFi connection, the WiFi router must be set to the same channel as ESP-NOW.
3. Only one device can be updated via ESP-NOW at a time. During the device upgrade, there may be delays in the response of others devices on the network.
4. The certificate (certificate.pem) must match the upgrade server.

View File

@ -8,73 +8,78 @@ void app_main(void)
nvs_flash_init();
esp_netif_init();
esp_event_loop_create_default();
#ifdef CONFIG_CONNECTION_TYPE_LAN
gpio_config_t config = {0};
config.intr_type = GPIO_INTR_DISABLE;
config.mode = GPIO_MODE_OUTPUT;
config.pin_bit_mask = (1ULL << ZH_LAN_MODULE_POWER_PIN);
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
config.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&config);
gpio_set_level(ZH_LAN_MODULE_POWER_PIN, 1);
esp_netif_config_t esp_netif_config = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *esp_netif_eth = esp_netif_new(&esp_netif_config);
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
esp_eth_phy_t *phy = ZH_LAN_MODULE_TYPE(&phy_config);
esp_eth_config_t esp_eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t esp_eth_handle = NULL;
esp_eth_driver_install(&esp_eth_config, &esp_eth_handle);
esp_netif_attach(esp_netif_eth, esp_eth_new_netif_glue(esp_eth_handle));
esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &zh_eth_event_handler, gateway_config, NULL);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &zh_eth_event_handler, gateway_config, NULL);
esp_eth_start(esp_eth_handle);
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config);
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B);
esp_wifi_start();
esp_read_mac(gateway_config->self_mac, ESP_MAC_WIFI_STA);
#else
esp_netif_create_default_wifi_sta();
wifi_init_config_t wifi_init_sta_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_sta_config);
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID_NAME,
.password = CONFIG_WIFI_PASSWORD,
},
};
esp_wifi_set_mode(WIFI_MODE_APSTA);
esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B);
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &zh_wifi_event_handler, gateway_config, NULL);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &zh_wifi_event_handler, gateway_config, NULL);
esp_wifi_start();
esp_read_mac(gateway_config->self_mac, ESP_MAC_WIFI_SOFTAP);
#endif
zh_load_config(gateway_config);
if (gateway_config->software_config.is_lan_mode == true)
{
gpio_config_t config = {0};
config.intr_type = GPIO_INTR_DISABLE;
config.mode = GPIO_MODE_OUTPUT;
config.pin_bit_mask = (1ULL << ZH_LAN_MODULE_POWER_PIN);
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
config.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&config);
gpio_set_level(ZH_LAN_MODULE_POWER_PIN, 1);
esp_netif_config_t esp_netif_config = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *esp_netif_eth = esp_netif_new(&esp_netif_config);
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
esp_eth_phy_t *phy = ZH_LAN_MODULE_TYPE(&phy_config);
esp_eth_config_t esp_eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t esp_eth_handle = NULL;
esp_eth_driver_install(&esp_eth_config, &esp_eth_handle);
esp_netif_attach(esp_netif_eth, esp_eth_new_netif_glue(esp_eth_handle));
esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &zh_eth_event_handler, gateway_config, NULL);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &zh_eth_event_handler, gateway_config, NULL);
esp_eth_start(esp_eth_handle);
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config);
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B);
esp_wifi_start();
esp_read_mac(gateway_config->self_mac, ESP_MAC_WIFI_STA);
}
else
{
esp_netif_create_default_wifi_sta();
wifi_init_config_t wifi_init_sta_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_sta_config);
wifi_config_t wifi_config = {0};
memcpy(wifi_config.sta.ssid, gateway_config->software_config.ssid_name, 6);
memcpy(wifi_config.sta.password, gateway_config->software_config.ssid_password, 10);
esp_wifi_set_mode(WIFI_MODE_APSTA);
esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B);
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &zh_wifi_event_handler, gateway_config, NULL);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &zh_wifi_event_handler, gateway_config, NULL);
esp_wifi_start();
esp_read_mac(gateway_config->self_mac, ESP_MAC_WIFI_SOFTAP);
}
#ifdef CONFIG_NETWORK_TYPE_DIRECT
zh_espnow_init_config_t zh_espnow_init_config = ZH_ESPNOW_INIT_CONFIG_DEFAULT();
zh_espnow_init_config.queue_size = 128;
#ifdef CONFIG_CONNECTION_TYPE_WIFI
zh_espnow_init_config.wifi_interface = WIFI_IF_AP;
#endif
if (gateway_config->software_config.is_lan_mode == false)
{
zh_espnow_init_config.wifi_interface = WIFI_IF_AP;
}
zh_espnow_init(&zh_espnow_init_config);
esp_event_handler_instance_register(ZH_EVENT, ESP_EVENT_ANY_ID, &zh_espnow_event_handler, gateway_config, NULL);
#else
zh_network_init_config_t zh_network_init_config = ZH_NETWORK_INIT_CONFIG_DEFAULT();
zh_network_init_config.queue_size = 128;
#ifdef CONFIG_CONNECTION_TYPE_WIFI
zh_network_init_config.wifi_interface = WIFI_IF_AP;
#endif
if (gateway_config->software_config.is_lan_mode == false)
{
zh_network_init_config.wifi_interface = WIFI_IF_AP;
}
zh_network_init(&zh_network_init_config);
esp_event_handler_instance_register(ZH_EVENT, ESP_EVENT_ANY_ID, &zh_espnow_event_handler, gateway_config, NULL);
#endif
gateway_config->espnow_ota_data_semaphore = xSemaphoreCreateBinary();
gateway_config->self_ota_in_progress_mutex = xSemaphoreCreateMutex();
gateway_config->espnow_ota_in_progress_mutex = xSemaphoreCreateMutex();
gateway_config->device_check_in_progress_mutex = xSemaphoreCreateMutex();
zh_vector_init(&gateway_config->available_device_vector, sizeof(available_device_t), false);
const esp_partition_t *running = esp_ota_get_running_partition();
esp_ota_img_states_t ota_state = {0};
esp_ota_get_state_partition(running, &ota_state);
@ -85,7 +90,66 @@ void app_main(void)
}
}
void zh_load_config(gateway_config_t *gateway_config)
{
nvs_handle_t nvs_handle = 0;
nvs_open("config", NVS_READWRITE, &nvs_handle);
uint8_t config_is_present = 0;
if (nvs_get_u8(nvs_handle, "present", &config_is_present) == ESP_ERR_NVS_NOT_FOUND)
{
nvs_set_u8(nvs_handle, "present", 0xFE);
nvs_close(nvs_handle);
#ifdef CONFIG_CONNECTION_TYPE_LAN
gateway_config->software_config.is_lan_mode = true;
strcpy(gateway_config->software_config.ssid_name, "ssid");
strcpy(gateway_config->software_config.ssid_password, "password");
#else
gateway_config->software_config.is_lan_mode = false;
strcpy(gateway_config->software_config.ssid_name, CONFIG_WIFI_SSID_NAME);
strcpy(gateway_config->software_config.ssid_password, CONFIG_WIFI_PASSWORD);
#endif
strcpy(gateway_config->software_config.mqtt_broker_url, CONFIG_MQTT_BROKER_URL);
strcpy(gateway_config->software_config.mqtt_topic_prefix, CONFIG_MQTT_TOPIC_PREFIX);
strcpy(gateway_config->software_config.ntp_server_url, CONFIG_NTP_SERVER_URL);
strcpy(gateway_config->software_config.ntp_time_zone, CONFIG_NTP_TIME_ZONE);
strcpy(gateway_config->software_config.firmware_upgrade_url, CONFIG_FIRMWARE_UPGRADE_URL);
zh_save_config(gateway_config);
return;
}
nvs_get_u8(nvs_handle, "lan_mode", (uint8_t *)&gateway_config->software_config.is_lan_mode);
size_t size = 0;
nvs_get_str(nvs_handle, "ssid_name", NULL, &size);
nvs_get_str(nvs_handle, "ssid_name", gateway_config->software_config.ssid_name, &size);
nvs_get_str(nvs_handle, "ssid_password", NULL, &size);
nvs_get_str(nvs_handle, "ssid_password", gateway_config->software_config.ssid_password, &size);
nvs_get_str(nvs_handle, "mqtt_url", NULL, &size);
nvs_get_str(nvs_handle, "mqtt_url", gateway_config->software_config.mqtt_broker_url, &size);
nvs_get_str(nvs_handle, "topic_prefix", NULL, &size);
nvs_get_str(nvs_handle, "topic_prefix", gateway_config->software_config.mqtt_topic_prefix, &size);
nvs_get_str(nvs_handle, "ntp_url", NULL, &size);
nvs_get_str(nvs_handle, "ntp_url", gateway_config->software_config.ntp_server_url, &size);
nvs_get_str(nvs_handle, "time_zone", NULL, &size);
nvs_get_str(nvs_handle, "time_zone", gateway_config->software_config.ntp_time_zone, &size);
nvs_get_str(nvs_handle, "upgrade_url", NULL, &size);
nvs_get_str(nvs_handle, "upgrade_url", gateway_config->software_config.firmware_upgrade_url, &size);
nvs_close(nvs_handle);
}
void zh_save_config(const gateway_config_t *gateway_config)
{
nvs_handle_t nvs_handle = 0;
nvs_open("config", NVS_READWRITE, &nvs_handle);
nvs_set_u8(nvs_handle, "lan_mode", gateway_config->software_config.is_lan_mode);
nvs_set_str(nvs_handle, "ssid_name", gateway_config->software_config.ssid_name);
nvs_set_str(nvs_handle, "ssid_password", gateway_config->software_config.ssid_password);
nvs_set_str(nvs_handle, "mqtt_url", gateway_config->software_config.mqtt_broker_url);
nvs_set_str(nvs_handle, "topic_prefix", gateway_config->software_config.mqtt_topic_prefix);
nvs_set_str(nvs_handle, "ntp_url", gateway_config->software_config.ntp_server_url);
nvs_set_str(nvs_handle, "time_zone", gateway_config->software_config.ntp_time_zone);
nvs_set_str(nvs_handle, "upgrade_url", gateway_config->software_config.firmware_upgrade_url);
nvs_close(nvs_handle);
}
void zh_eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
gateway_config_t *gateway_config = arg;
@ -107,10 +171,9 @@ void zh_eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_
case IP_EVENT_ETH_GOT_IP:
if (gateway_config->mqtt_is_enable == false)
{
esp_mqtt_client_config_t mqtt_config = {
.broker.address.uri = CONFIG_MQTT_BROKER_URL,
.buffer.size = 2048,
};
esp_mqtt_client_config_t mqtt_config = {0};
mqtt_config.buffer.size = 2048;
mqtt_config.broker.address.uri = gateway_config->software_config.mqtt_broker_url;
gateway_config->mqtt_client = esp_mqtt_client_init(&mqtt_config);
esp_mqtt_client_register_event(gateway_config->mqtt_client, ESP_EVENT_ANY_ID, zh_mqtt_event_handler, gateway_config);
esp_mqtt_client_start(gateway_config->mqtt_client);
@ -120,7 +183,7 @@ void zh_eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_
{
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH);
esp_sntp_setservername(0, CONFIG_NTP_SERVER_URL);
esp_sntp_setservername(0, gateway_config->software_config.ntp_server_url);
esp_sntp_init();
gateway_config->sntp_is_enable = true;
xTaskCreatePinnedToCore(&zh_send_espnow_current_time_task, "NULL", ZH_SNTP_STACK_SIZE, gateway_config, ZH_SNTP_TASK_PRIORITY, (TaskHandle_t *)&gateway_config->gateway_current_time_task, tskNO_AFFINITY);
@ -130,9 +193,7 @@ void zh_eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_
break;
}
}
#endif
#ifdef CONFIG_CONNECTION_TYPE_WIFI
void zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
gateway_config_t *gateway_config = arg;
@ -171,10 +232,9 @@ void zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event
gateway_config->wifi_reconnect_retry_num = 0;
if (gateway_config->mqtt_is_enable == false)
{
esp_mqtt_client_config_t mqtt_config = {
.broker.address.uri = CONFIG_MQTT_BROKER_URL,
.buffer.size = 2048,
};
esp_mqtt_client_config_t mqtt_config = {0};
mqtt_config.buffer.size = 2048;
mqtt_config.broker.address.uri = gateway_config->software_config.mqtt_broker_url;
gateway_config->mqtt_client = esp_mqtt_client_init(&mqtt_config);
esp_mqtt_client_register_event(gateway_config->mqtt_client, ESP_EVENT_ANY_ID, zh_mqtt_event_handler, gateway_config);
esp_mqtt_client_start(gateway_config->mqtt_client);
@ -184,7 +244,7 @@ void zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event
{
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH);
esp_sntp_setservername(0, CONFIG_NTP_SERVER_URL);
esp_sntp_setservername(0, gateway_config->software_config.ntp_server_url);
esp_sntp_init();
gateway_config->sntp_is_enable = true;
xTaskCreatePinnedToCore(&zh_send_espnow_current_time_task, "NULL", ZH_SNTP_STACK_SIZE, gateway_config, ZH_SNTP_TASK_PRIORITY, (TaskHandle_t *)&gateway_config->gateway_current_time_task, tskNO_AFFINITY);
@ -194,7 +254,6 @@ void zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event
break;
}
}
#endif
void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
@ -217,15 +276,33 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
}
#endif
zh_espnow_data_t *data = (zh_espnow_data_t *)recv_data->data;
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(data->device_type)) + 20, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(data->device_type)) + 20);
sprintf(topic, "%s/%s/" MAC_STR, CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(data->device_type), MAC2STR(recv_data->mac_addr));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(data->device_type)) + 20, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(data->device_type)) + 20);
sprintf(topic, "%s/%s/" MAC_STR, gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(data->device_type), MAC2STR(recv_data->mac_addr));
switch (data->payload_type)
{
case ZHPT_ATTRIBUTES:
zh_espnow_send_mqtt_json_attributes_message(data, recv_data->mac_addr, gateway_config);
break;
case ZHPT_KEEP_ALIVE:
if (xSemaphoreTake(gateway_config->device_check_in_progress_mutex, portTICK_PERIOD_MS) == pdTRUE)
{
for (uint16_t i = 0; i < zh_vector_get_size(&gateway_config->available_device_vector); ++i)
{
available_device_t *available_device = zh_vector_get_item(&gateway_config->available_device_vector, i);
if (memcmp(recv_data->mac_addr, available_device->mac_addr, 6) == 0)
{
zh_vector_delete_item(&gateway_config->available_device_vector, i);
}
}
available_device_t available_device = {0};
available_device.device_type = data->device_type;
memcpy(available_device.mac_addr, recv_data->mac_addr, 6);
available_device.frequency = data->payload_data.keep_alive_message.message_frequency;
available_device.time = esp_timer_get_time() / 1000000;
zh_vector_push_back(&gateway_config->available_device_vector, &available_device);
xSemaphoreGive(gateway_config->device_check_in_progress_mutex);
}
zh_espnow_send_mqtt_json_keep_alive_message(data, recv_data->mac_addr, gateway_config);
break;
case ZHPT_CONFIG:
@ -339,15 +416,16 @@ void zh_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event
for (zh_device_type_t i = 1; i <= ZHDT_MAX; ++i)
{
supported_device_type = zh_get_device_type_value_name(i);
topic_for_subscribe = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(supported_device_type) + 4, MALLOC_CAP_8BIT);
memset(topic_for_subscribe, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(supported_device_type) + 4);
sprintf(topic_for_subscribe, "%s/%s/#", CONFIG_MQTT_TOPIC_PREFIX, supported_device_type);
topic_for_subscribe = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(supported_device_type) + 4, MALLOC_CAP_8BIT);
memset(topic_for_subscribe, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(supported_device_type) + 4);
sprintf(topic_for_subscribe, "%s/%s/#", gateway_config->software_config.mqtt_topic_prefix, supported_device_type);
esp_mqtt_client_subscribe(gateway_config->mqtt_client, topic_for_subscribe, 2);
heap_caps_free(topic_for_subscribe);
}
zh_gateway_send_mqtt_json_config_message(gateway_config);
xTaskCreatePinnedToCore(&zh_gateway_send_mqtt_json_attributes_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, gateway_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&gateway_config->gateway_attributes_message_task, tskNO_AFFINITY);
xTaskCreatePinnedToCore(&zh_gateway_send_mqtt_json_keep_alive_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, gateway_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&gateway_config->gateway_keep_alive_message_task, tskNO_AFFINITY);
xTaskCreatePinnedToCore(&zh_device_availability_check_task, "NULL", ZH_CHECK_STACK_SIZE, gateway_config, ZH_CHECK_TASK_PRIORITY, (TaskHandle_t *)&gateway_config->device_availability_check_task, tskNO_AFFINITY);
}
gateway_config->mqtt_is_connected = true;
break;
@ -356,6 +434,7 @@ void zh_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event
{
vTaskDelete(gateway_config->gateway_attributes_message_task);
vTaskDelete(gateway_config->gateway_keep_alive_message_task);
vTaskDelete(gateway_config->device_availability_check_task);
zh_espnow_data_t data = {0};
data.device_type = ZHDT_GATEWAY;
data.payload_type = ZHPT_KEEP_ALIVE;
@ -701,17 +780,17 @@ void zh_self_ota_update_task(void *pvParameter)
{
gateway_config_t *gateway_config = pvParameter;
xSemaphoreTake(gateway_config->self_ota_in_progress_mutex, portMAX_DELAY);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(ZHDT_GATEWAY)) + 20, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(ZHDT_GATEWAY)) + 20);
sprintf(topic, "%s/%s/" MAC_STR, CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(ZHDT_GATEWAY), MAC2STR(gateway_config->self_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(ZHDT_GATEWAY)) + 20, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(ZHDT_GATEWAY)) + 20);
sprintf(topic, "%s/%s/" MAC_STR, gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(ZHDT_GATEWAY), MAC2STR(gateway_config->self_mac));
char self_ota_write_data[1025] = {0};
esp_ota_handle_t update_handle = {0};
const esp_partition_t *update_partition = NULL;
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, "update_begin", 0, 2, true);
const esp_app_desc_t *app_info = esp_app_get_description();
char *app_name = (char *)heap_caps_malloc(strlen(CONFIG_FIRMWARE_UPGRADE_URL) + strlen(app_info->project_name) + 6, MALLOC_CAP_8BIT);
memset(app_name, 0, strlen(CONFIG_FIRMWARE_UPGRADE_URL) + strlen(app_info->project_name) + 6);
sprintf(app_name, "%s/%s.bin", CONFIG_FIRMWARE_UPGRADE_URL, app_info->project_name);
char *app_name = (char *)heap_caps_malloc(strlen(gateway_config->software_config.firmware_upgrade_url) + strlen(app_info->project_name) + 6, MALLOC_CAP_8BIT);
memset(app_name, 0, strlen(gateway_config->software_config.firmware_upgrade_url) + strlen(app_info->project_name) + 6);
sprintf(app_name, "%s/%s.bin", gateway_config->software_config.firmware_upgrade_url, app_info->project_name);
esp_http_client_config_t config = {
.url = app_name,
.cert_pem = (char *)server_certificate_pem_start,
@ -771,14 +850,14 @@ void zh_espnow_ota_update_task(void *pvParameter)
xSemaphoreTake(gateway_config->espnow_ota_in_progress_mutex, portMAX_DELAY);
zh_espnow_data_t data = {0};
data.device_type = ZHDT_GATEWAY;
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(gateway_config->espnow_ota_data.device_type)) + 20, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(gateway_config->espnow_ota_data.device_type)) + 20);
sprintf(topic, "%s/%s/" MAC_STR, CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(gateway_config->espnow_ota_data.device_type), MAC2STR(gateway_config->espnow_ota_data.mac_addr));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(gateway_config->espnow_ota_data.device_type)) + 20, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(gateway_config->espnow_ota_data.device_type)) + 20);
sprintf(topic, "%s/%s/" MAC_STR, gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(gateway_config->espnow_ota_data.device_type), MAC2STR(gateway_config->espnow_ota_data.mac_addr));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, "update_begin", 0, 2, true);
char espnow_ota_write_data[sizeof(data.payload_data.ota_message.espnow_ota_message.data) + 1] = {0};
char *app_name = (char *)heap_caps_malloc(strlen(CONFIG_FIRMWARE_UPGRADE_URL) + strlen(gateway_config->espnow_ota_data.app_name) + 6, MALLOC_CAP_8BIT);
memset(app_name, 0, strlen(CONFIG_FIRMWARE_UPGRADE_URL) + strlen(gateway_config->espnow_ota_data.app_name) + 6);
sprintf(app_name, "%s/%s.bin", CONFIG_FIRMWARE_UPGRADE_URL, gateway_config->espnow_ota_data.app_name);
char *app_name = (char *)heap_caps_malloc(strlen(gateway_config->software_config.firmware_upgrade_url) + strlen(gateway_config->espnow_ota_data.app_name) + 6, MALLOC_CAP_8BIT);
memset(app_name, 0, strlen(gateway_config->software_config.firmware_upgrade_url) + strlen(gateway_config->espnow_ota_data.app_name) + 6);
sprintf(app_name, "%s/%s.bin", gateway_config->software_config.firmware_upgrade_url, gateway_config->espnow_ota_data.app_name);
esp_http_client_config_t config = {
.url = app_name,
.cert_pem = (char *)server_certificate_pem_start,
@ -851,13 +930,13 @@ void zh_espnow_ota_update_task(void *pvParameter)
void zh_send_espnow_current_time_task(void *pvParameter)
{
// gateway_config_t *gateway_config = pvParameter;
gateway_config_t *gateway_config = pvParameter;
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED)
{
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
time_t now;
setenv("TZ", CONFIG_NTP_TIME_ZONE, 1);
setenv("TZ", gateway_config->software_config.ntp_time_zone, 1);
tzset();
for (;;)
{
@ -868,6 +947,37 @@ void zh_send_espnow_current_time_task(void *pvParameter)
vTaskDelete(NULL);
}
void zh_device_availability_check_task(void *pvParameter)
{
gateway_config_t *gateway_config = pvParameter;
for (;;)
{
xSemaphoreTake(gateway_config->device_check_in_progress_mutex, portMAX_DELAY);
for (uint16_t i = 0; i < zh_vector_get_size(&gateway_config->available_device_vector); ++i)
{
CHECK:
available_device_t *available_device = zh_vector_get_item(&gateway_config->available_device_vector, i);
if (available_device == NULL)
{
break;
}
if (esp_timer_get_time() / 1000000 > available_device->time + (available_device->frequency * 3))
{
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(available_device->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(available_device->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/status", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(available_device->device_type), MAC2STR(available_device->mac_addr));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, "offline", 0, 2, true);
heap_caps_free(topic);
zh_vector_delete_item(&gateway_config->available_device_vector, i);
goto CHECK; // Since the vector is shifted after item deletion, the item needs to be re-checked.
}
}
xSemaphoreGive(gateway_config->device_check_in_progress_mutex);
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
uint8_t zh_gpio_number_check(int gpio)
{
return (gpio >= 0 && gpio <= ZH_MAX_GPIO_NUMBERS) ? gpio : ZH_NOT_USED;
@ -992,9 +1102,9 @@ void zh_espnow_send_mqtt_json_attributes_message(zh_espnow_data_t *device_data,
zh_json_add(&json, "Uptime", uptime);
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(topic, "%s/%s/" MAC_STR "/attributes", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(topic, "%s/%s/" MAC_STR "/attributes", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(mac);
heap_caps_free(uptime);
@ -1008,9 +1118,9 @@ void zh_espnow_send_mqtt_json_attributes_message(zh_espnow_data_t *device_data,
void zh_espnow_send_mqtt_json_keep_alive_message(const zh_espnow_data_t *device_data, const uint8_t *device_mac, const gateway_config_t *gateway_config)
{
char *status = (device_data->payload_data.keep_alive_message.online_status == ZH_ONLINE) ? "online" : "offline";
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/status", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/status", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, status, 0, 2, true);
heap_caps_free(topic);
}
@ -1023,18 +1133,18 @@ void zh_espnow_switch_send_mqtt_json_config_message(const zh_espnow_data_t *devi
char *unique_id = (char *)heap_caps_malloc(22, MALLOC_CAP_8BIT);
memset(unique_id, 0, 22);
sprintf(unique_id, "" MAC_STR "-%d", MAC2STR(device_mac), device_data->payload_data.config_message.switch_config_message.unique_id);
char *state_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *availability_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(availability_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(availability_topic, "%s/%s/" MAC_STR "/status", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *command_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24, MALLOC_CAP_8BIT);
memset(command_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24);
sprintf(command_topic, "%s/%s/" MAC_STR "/set", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *state_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *availability_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(availability_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(availability_topic, "%s/%s/" MAC_STR "/status", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *command_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24, MALLOC_CAP_8BIT);
memset(command_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24);
sprintf(command_topic, "%s/%s/" MAC_STR "/set", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *qos = (char *)heap_caps_malloc(4, MALLOC_CAP_8BIT);
memset(qos, 0, 4);
sprintf(qos, "%d", device_data->payload_data.config_message.switch_config_message.qos);
@ -1058,9 +1168,9 @@ void zh_espnow_switch_send_mqtt_json_config_message(const zh_espnow_data_t *devi
zh_json_add(&json, "retain", (device_data->payload_data.config_message.switch_config_message.retain == true) ? "true" : "false");
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 16, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 16);
sprintf(topic, "%s/switch/%s/config", CONFIG_MQTT_TOPIC_PREFIX, unique_id);
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 16, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 16);
sprintf(topic, "%s/switch/%s/config", gateway_config->software_config.mqtt_topic_prefix, unique_id);
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(name);
heap_caps_free(unique_id);
@ -1145,9 +1255,9 @@ void zh_espnow_switch_send_mqtt_json_hardware_config_message(const zh_espnow_dat
}
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/config", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/config", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(relay_pin);
heap_caps_free(led_pin);
@ -1165,9 +1275,9 @@ void zh_espnow_switch_send_mqtt_json_status_message(const zh_espnow_data_t *devi
zh_json_add(&json, "state", zh_get_on_off_type_value_name(device_data->payload_data.status_message.switch_status_message.status));
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(topic);
}
@ -1180,30 +1290,30 @@ void zh_espnow_led_send_mqtt_json_config_message(const zh_espnow_data_t *device_
char *unique_id = (char *)heap_caps_malloc(22, MALLOC_CAP_8BIT);
memset(unique_id, 0, 22);
sprintf(unique_id, "" MAC_STR "-%d", MAC2STR(device_mac), device_data->payload_data.config_message.led_config_message.unique_id);
char *state_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *availability_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(availability_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(availability_topic, "%s/%s/" MAC_STR "/status", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *command_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24, MALLOC_CAP_8BIT);
memset(command_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24);
sprintf(command_topic, "%s/%s/" MAC_STR "/set", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *state_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *availability_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(availability_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(availability_topic, "%s/%s/" MAC_STR "/status", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *command_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24, MALLOC_CAP_8BIT);
memset(command_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24);
sprintf(command_topic, "%s/%s/" MAC_STR "/set", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *qos = (char *)heap_caps_malloc(4, MALLOC_CAP_8BIT);
memset(qos, 0, 4);
sprintf(qos, "%d", device_data->payload_data.config_message.led_config_message.qos);
char *brightness_command_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(brightness_command_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(brightness_command_topic, "%s/%s/" MAC_STR "/brightness", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *color_temp_command_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 32, MALLOC_CAP_8BIT);
memset(color_temp_command_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 32);
sprintf(color_temp_command_topic, "%s/%s/" MAC_STR "/temperature", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *rgb_command_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24, MALLOC_CAP_8BIT);
memset(rgb_command_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24);
sprintf(rgb_command_topic, "%s/%s/" MAC_STR "/rgb", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *brightness_command_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(brightness_command_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(brightness_command_topic, "%s/%s/" MAC_STR "/brightness", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *color_temp_command_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 32, MALLOC_CAP_8BIT);
memset(color_temp_command_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 32);
sprintf(color_temp_command_topic, "%s/%s/" MAC_STR "/temperature", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *rgb_command_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24, MALLOC_CAP_8BIT);
memset(rgb_command_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 24);
sprintf(rgb_command_topic, "%s/%s/" MAC_STR "/rgb", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
zh_json_t json = {0};
char buffer[1024] = {0};
zh_json_init(&json);
@ -1238,9 +1348,9 @@ void zh_espnow_led_send_mqtt_json_config_message(const zh_espnow_data_t *device_
}
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 15, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 15);
sprintf(topic, "%s/light/%s/config", CONFIG_MQTT_TOPIC_PREFIX, unique_id);
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 15, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 15);
sprintf(topic, "%s/light/%s/config", gateway_config->software_config.mqtt_topic_prefix, unique_id);
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(name);
heap_caps_free(unique_id);
@ -1275,9 +1385,9 @@ void zh_espnow_led_send_mqtt_json_status_message(const zh_espnow_data_t *device_
zh_json_add(&json, "rgb", rgb);
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(topic);
}
@ -1290,15 +1400,15 @@ void zh_espnow_sensor_send_mqtt_json_config_message(zh_espnow_data_t *device_dat
char *unique_id = (char *)heap_caps_malloc(22, MALLOC_CAP_8BIT);
memset(unique_id, 0, 22);
sprintf(unique_id, "" MAC_STR "-%d", MAC2STR(device_mac), device_data->payload_data.config_message.sensor_config_message.unique_id);
char *state_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *state_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *value_template = (char *)heap_caps_malloc(strlen(zh_get_sensor_device_class_value_name(device_data->payload_data.config_message.sensor_config_message.sensor_device_class)) + 18, MALLOC_CAP_8BIT);
memset(value_template, 0, strlen(zh_get_sensor_device_class_value_name(device_data->payload_data.config_message.sensor_config_message.sensor_device_class)) + 18);
sprintf(value_template, "{{ value_json.%s }}", zh_get_sensor_device_class_value_name(device_data->payload_data.config_message.sensor_config_message.sensor_device_class));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *qos = (char *)heap_caps_malloc(4, MALLOC_CAP_8BIT);
memset(qos, 0, 4);
sprintf(qos, "%d", device_data->payload_data.config_message.sensor_config_message.qos);
@ -1327,9 +1437,9 @@ void zh_espnow_sensor_send_mqtt_json_config_message(zh_espnow_data_t *device_dat
zh_json_add(&json, "unit_of_measurement", device_data->payload_data.config_message.sensor_config_message.unit_of_measurement);
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 16, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 16);
sprintf(topic, "%s/sensor/%s/config", CONFIG_MQTT_TOPIC_PREFIX, unique_id);
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 16, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 16);
sprintf(topic, "%s/sensor/%s/config", gateway_config->software_config.mqtt_topic_prefix, unique_id);
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(name);
heap_caps_free(unique_id);
@ -1402,9 +1512,9 @@ void zh_espnow_sensor_send_mqtt_json_hardware_config_message(const zh_espnow_dat
zh_json_add(&json, "Power mode", (device_data->payload_data.config_message.sensor_hardware_config_message.battery_power == true) ? "Battery" : "External");
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/config", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 27);
sprintf(topic, "%s/%s/" MAC_STR "/config", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(sensor_pin_1);
heap_caps_free(sensor_pin_2);
@ -1445,9 +1555,9 @@ void zh_espnow_sensor_send_mqtt_json_status_message(const zh_espnow_data_t *devi
}
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(temperature);
heap_caps_free(humidity);
@ -1462,15 +1572,15 @@ void zh_espnow_binary_sensor_send_mqtt_json_config_message(const zh_espnow_data_
char *unique_id = (char *)heap_caps_malloc(22, MALLOC_CAP_8BIT);
memset(unique_id, 0, 22);
sprintf(unique_id, "" MAC_STR "-%d", MAC2STR(device_mac), device_data->payload_data.config_message.binary_sensor_config_message.unique_id);
char *state_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *state_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26, MALLOC_CAP_8BIT);
memset(state_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 26);
sprintf(state_topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *value_template = (char *)heap_caps_malloc(strlen(zh_get_binary_sensor_device_class_value_name(device_data->payload_data.config_message.binary_sensor_config_message.binary_sensor_device_class)) + 18, MALLOC_CAP_8BIT);
memset(value_template, 0, strlen(zh_get_binary_sensor_device_class_value_name(device_data->payload_data.config_message.binary_sensor_config_message.binary_sensor_device_class)) + 18);
sprintf(value_template, "{{ value_json.%s }}", zh_get_binary_sensor_device_class_value_name(device_data->payload_data.config_message.binary_sensor_config_message.binary_sensor_device_class));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *json_attributes_topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(json_attributes_topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(json_attributes_topic, "%s/%s/" MAC_STR "/attributes", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *qos = (char *)heap_caps_malloc(4, MALLOC_CAP_8BIT);
memset(qos, 0, 4);
sprintf(qos, "%d", device_data->payload_data.config_message.binary_sensor_config_message.qos);
@ -1506,9 +1616,9 @@ void zh_espnow_binary_sensor_send_mqtt_json_config_message(const zh_espnow_data_
}
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 23, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(unique_id) + 23);
sprintf(topic, "%s/binary_sensor/%s/config", CONFIG_MQTT_TOPIC_PREFIX, unique_id);
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 23, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(unique_id) + 23);
sprintf(topic, "%s/binary_sensor/%s/config", gateway_config->software_config.mqtt_topic_prefix, unique_id);
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(name);
heap_caps_free(unique_id);
@ -1548,9 +1658,9 @@ void zh_espnow_binary_sensor_send_mqtt_json_status_message(const zh_espnow_data_
}
zh_json_create(&json, buffer);
zh_json_free(&json);
char *topic = (char *)heap_caps_malloc(strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(CONFIG_MQTT_TOPIC_PREFIX) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(topic, "%s/%s/" MAC_STR "/state", CONFIG_MQTT_TOPIC_PREFIX, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
char *topic = (char *)heap_caps_malloc(strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31, MALLOC_CAP_8BIT);
memset(topic, 0, strlen(gateway_config->software_config.mqtt_topic_prefix) + strlen(zh_get_device_type_value_name(device_data->device_type)) + 31);
sprintf(topic, "%s/%s/" MAC_STR "/state", gateway_config->software_config.mqtt_topic_prefix, zh_get_device_type_value_name(device_data->device_type), MAC2STR(device_mac));
esp_mqtt_client_publish(gateway_config->mqtt_client, topic, buffer, 0, 2, true);
heap_caps_free(topic);
}

View File

@ -16,6 +16,7 @@
#include "esp_mac.h"
#include "mqtt_client.h"
#include "zh_json.h"
#include "zh_vector.h"
#include "zh_config.h"
#ifdef CONFIG_NETWORK_TYPE_DIRECT
@ -42,8 +43,10 @@
#define ZH_CHIP_TYPE HACHT_ESP32C6
#endif
#define ZH_LAN_MODULE_TYPE(x) esp_eth_phy_new_rtl8201(x) // Change it according to the LAN module used.
#define ZH_LAN_MODULE_POWER_PIN GPIO_NUM_12 // Change it according to the LAN module used.
#define ZH_LAN_MODULE_TYPE(x) esp_eth_phy_new_rtl8201(x) // For LILYGO T-ETH-Lite ESP32.
#define ZH_LAN_MODULE_POWER_PIN GPIO_NUM_12 // For LILYGO T-ETH-Lite ESP32.
// #define ZH_LAN_MODULE_TYPE(x) esp_eth_phy_new_lan87xx(x) // For Wireless-Tag WT32-ETH01.
// #define ZH_LAN_MODULE_POWER_PIN GPIO_NUM_16 // For Wireless-Tag WT32-ETH01.
#define ZH_WIFI_MAXIMUM_RETRY 5 // Maximum number of unsuccessful WiFi connection attempts.
#define ZH_WIFI_RECONNECT_TIME 5 // Waiting time (in seconds) between attempts to reconnect to WiFi (if number of attempts of unsuccessful connections is exceeded).
@ -53,6 +56,8 @@
#define ZH_MESSAGE_STACK_SIZE 3072 // The stack size of the task of sending messages to the MQTT.
#define ZH_SNTP_TASK_PRIORITY 2 // Prioritize the task to get the current time.
#define ZH_SNTP_STACK_SIZE 2048 // The stack size of the task to get the current time.
#define ZH_CHECK_TASK_PRIORITY 2 // Prioritize the task to checking device availability.
#define ZH_CHECK_STACK_SIZE 2048 // The stack size of the task to checking device availability.
#define ZH_OTA_TASK_PRIORITY 3 // Prioritize the task of OTA updates.
#define ZH_OTA_STACK_SIZE 8192 // The stack size of the task of OTA updates.
@ -60,6 +65,17 @@
typedef struct // Structure of data exchange between tasks, functions and event handlers.
{
struct // Storage structure of gateway configuration data.
{
bool is_lan_mode; // Ethernet work mode flag.
char ssid_name[32]; // WiFi SSID name.
char ssid_password[64]; // WiFi password.
char mqtt_broker_url[64]; // MQTT broker url.
char mqtt_topic_prefix[32]; // MQTT topic prefix.
char ntp_server_url[64]; // NTP server url.
char ntp_time_zone[10]; // NTP time zone.
char firmware_upgrade_url[64]; // Firmware upgrade url.
} software_config;
uint8_t self_mac[6]; // Gateway MAC address. @note Depends at WiFi operation mode.
bool sntp_is_enable; // SNTP client operation status flag. @note Used to control the SNTP functions when the network connection is established / lost.
bool mqtt_is_enable; // MQTT client operation status flag. @note Used to control the MQTT functions when the network connection is established / lost.
@ -70,6 +86,7 @@ typedef struct // Structure of data exchange between tasks, functions and event
TaskHandle_t gateway_attributes_message_task; // Unique task handle for zh_gateway_send_mqtt_json_attributes_message_task().
TaskHandle_t gateway_keep_alive_message_task; // Unique task handle for zh_gateway_send_mqtt_json_keep_alive_message_task().
TaskHandle_t gateway_current_time_task; // Unique task handle for zh_send_espnow_current_time_task().
TaskHandle_t device_availability_check_task; // Unique task handle for zh_device_availability_check_task().
struct // Structure for initial transfer system data to the node update task.
{
zh_device_type_t device_type; // ESP-NOW device type.
@ -77,29 +94,52 @@ typedef struct // Structure of data exchange between tasks, functions and event
char app_version[32]; // Firmware application version.
uint8_t mac_addr[6]; // ESP-NOW node MAC address.
} espnow_ota_data;
SemaphoreHandle_t espnow_ota_data_semaphore; // Semaphore for control the acknowledgement of successful receipt of an update package from a node.
SemaphoreHandle_t self_ota_in_progress_mutex; // Mutex blocking the second run of the gateway update task.
SemaphoreHandle_t espnow_ota_in_progress_mutex; // Mutex blocking the second run of the node update task.
SemaphoreHandle_t espnow_ota_data_semaphore; // Semaphore for control the acknowledgement of successful receipt of an update package from a node.
SemaphoreHandle_t self_ota_in_progress_mutex; // Mutex blocking the second run of the gateway update task.
SemaphoreHandle_t espnow_ota_in_progress_mutex; // Mutex blocking the second run of the node update task.
SemaphoreHandle_t device_check_in_progress_mutex; // Mutex blocking the second access to the vector for struct for storing data about available nodes.
zh_vector_t available_device_vector; // Vector for struct for storing data about available nodes.
} gateway_config_t;
typedef struct // Struct for storing data about available nodes.
{
zh_device_type_t device_type; // ESP-NOW device type.
uint8_t mac_addr[6]; // ESP-NOW node MAC address.
uint8_t frequency; // Keep alive message frequency.
uint64_t time; // Last keep alive message time.
} available_device_t;
extern const uint8_t server_certificate_pem_start[] asm("_binary_certificate_pem_start");
extern const uint8_t server_certificate_pem_end[] asm("_binary_certificate_pem_end");
#ifdef CONFIG_CONNECTION_TYPE_LAN
/**
* @brief Function for loading the gateway configuration from NVS memory.
*
* @param[out] switch_config Pointer to structure of data exchange between tasks, functions and event handlers.
*/
void zh_load_config(gateway_config_t *gateway_config);
/**
* @brief Function for saving the gateway configuration to NVS memory.
*
* @param[in] switch_config Pointer to structure of data exchange between tasks, functions and event handlers.
*/
void zh_save_config(const gateway_config_t *gateway_config);
/**
* @brief Function for LAN event processing.
*
* @param[in,out] arg Pointer to the structure of data exchange between tasks, functions and event handlers.
*/
void zh_eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
#else
/**
* @brief Function for WiFi event processing.
*
* @param[in,out] arg Pointer to the structure of data exchange between tasks, functions and event handlers.
*/
void zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
#endif
/**
* @brief Function for ESP-NOW event processing
*
@ -137,6 +177,13 @@ void zh_espnow_ota_update_task(void *pvParameter);
*/
void zh_send_espnow_current_time_task(void *pvParameter);
/**
* @brief The task of checking device availability and sending a message to the MQTT broker in case of unavailability.
*
* @param[in,out] pvParameter Pointer to the structure of data exchange between tasks, functions and event handlers.
*/
void zh_device_availability_check_task(void *pvParameter);
/**
* @brief Function for checking the correctness of the GPIO number value.
*

View File

@ -1 +1 @@
1.0.2
1.0.4