4 Commits

Author SHA1 Message Date
a04a1e4544 Version 1.0.5
Fixed small bug.
Updated some components.
2024-07-25 10:42:23 +03:00
6f7e7c5e66 Version 1.0.4
Changed WiFi protocol.
Reduced time threshold for sensor availability.
Changed sensor reading error message.
Added offline message.
Changed task management.
 Added multiple attempts to read the sensor.
2024-07-19 21:26:10 +03:00
d1d9c79369 Version 1.0.3
Added keep_alive_message_task.
Added sensor reading error message.
Updated components.
2024-07-16 14:01:46 +03:00
2bd120b5d3 Update README.md 2024-07-05 13:47:54 +03:00
12 changed files with 150 additions and 35 deletions

View File

@ -29,7 +29,7 @@ ESP-NOW based sensor for ESP32 ESP-IDF and ESP8266 RTOS SDK.
3. For initial settings use "menuconfig -> ZH ESP-NOW Sensor Configuration". After first boot all settings will be stored in NVS memory for prevente change during OTA firmware update. 3. For initial settings use "menuconfig -> ZH ESP-NOW Sensor Configuration". After first boot all settings will be stored in NVS memory for prevente change during OTA firmware update.
4. Only one sensor can be used at a time. 4. Only one sensor can be used at a time.
5. To restart the sensor, send the "restart" command to the root topic of the sensor (example - "homeassistant/espnow_sensor/24-62-AB-F9-1F-A8"). 5. To restart the sensor, send the "restart" command to the root topic of the sensor (example - "homeassistant/espnow_sensor/24-62-AB-F9-1F-A8").
6. To update the sensor firmware, send the "update" command to the root topic of the sensor (example - "homeassistant/espnow_sensor/70-03-9F-44-BE-F7"). The update path should be like as "https://your_server/zh_espnow_sensor_esp32.bin" (for ESP32) or "https://your_server/zh_espnow_sensor_esp8266.app1.bin + https://your_server/zh_espnow_sensor_esp8266.app2.bin" (for ESP8266). The time and success of the update depends on the load on WiFi channel 1. Average update time is up to five minutes. The online status of the update is displayed in the root sensor topic. 6. To update the sensor firmware, send the "update" command to the root topic of the sensor (example - "homeassistant/espnow_sensor/70-03-9F-44-BE-F7"). The update path should be like as "https://your_server/zh_espnow_sensor_esp32.bin" (for ESP32) or "https://your_server/zh_espnow_sensor_esp8266.app1.bin + https://your_server/zh_espnow_sensor_esp8266.app2.bin" (for ESP8266). Average update time is up to some minutes. The online status of the update is displayed in the root sensor topic.
7. To change initial settings of the sensor (except work mode and power selection GPIO), send the X1,X2,X3,X4,X5,X6 command to the hardware topic of the sensor (example - "homeassistant/espnow_sensor/70-03-9F-44-BE-F7/hardware"). The configuration will only be accepted if it does not cause errors. The current configuration status is displayed in the configuration topic of the sensor (example - "homeassistant/espnow_sensor/70-03-9F-44-BE-F7/config"). 7. To change initial settings of the sensor (except work mode and power selection GPIO), send the X1,X2,X3,X4,X5,X6 command to the hardware topic of the sensor (example - "homeassistant/espnow_sensor/70-03-9F-44-BE-F7/hardware"). The configuration will only be accepted if it does not cause errors. The current configuration status is displayed in the configuration topic of the sensor (example - "homeassistant/espnow_sensor/70-03-9F-44-BE-F7/config").
MQTT configuration message should filled according to the template "X1,X2,X3,X4,X5,X6". Where: MQTT configuration message should filled according to the template "X1,X2,X3,X4,X5,X6". Where:

View File

@ -28,7 +28,11 @@ void app_main(void)
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config); esp_wifi_init(&wifi_init_config);
esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B); #ifdef CONFIG_IDF_TARGET_ESP8266
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
#else
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR);
#endif
esp_wifi_start(); esp_wifi_start();
#ifdef CONFIG_NETWORK_TYPE_DIRECT #ifdef CONFIG_NETWORK_TYPE_DIRECT
zh_espnow_init_config_t espnow_init_config = ZH_ESPNOW_INIT_CONFIG_DEFAULT(); zh_espnow_init_config_t espnow_init_config = ZH_ESPNOW_INIT_CONFIG_DEFAULT();
@ -72,6 +76,7 @@ void zh_load_config(sensor_config_t *sensor_config)
{ {
nvs_set_u8(nvs_handle, "present", 0xFE); nvs_set_u8(nvs_handle, "present", 0xFE);
nvs_close(nvs_handle); nvs_close(nvs_handle);
SETUP_INITIAL_SETTINGS:
#ifdef CONFIG_SENSOR_TYPE_DS18B20 #ifdef CONFIG_SENSOR_TYPE_DS18B20
sensor_config->hardware_config.sensor_type = HAST_DS18B20; sensor_config->hardware_config.sensor_type = HAST_DS18B20;
#elif CONFIG_SENSOR_TYPE_DHT #elif CONFIG_SENSOR_TYPE_DHT
@ -111,13 +116,18 @@ void zh_load_config(sensor_config_t *sensor_config)
zh_save_config(sensor_config); zh_save_config(sensor_config);
return; return;
} }
nvs_get_u8(nvs_handle, "sensor_type", (uint8_t *)&sensor_config->hardware_config.sensor_type); esp_err_t err = ESP_OK;
nvs_get_u8(nvs_handle, "sensor_pin_1", &sensor_config->hardware_config.sensor_pin_1); err += nvs_get_u8(nvs_handle, "sensor_type", (uint8_t *)&sensor_config->hardware_config.sensor_type);
nvs_get_u8(nvs_handle, "sensor_pin_2", &sensor_config->hardware_config.sensor_pin_2); err += nvs_get_u8(nvs_handle, "sensor_pin_1", &sensor_config->hardware_config.sensor_pin_1);
nvs_get_u8(nvs_handle, "power_pin", &sensor_config->hardware_config.power_pin); err += nvs_get_u8(nvs_handle, "sensor_pin_2", &sensor_config->hardware_config.sensor_pin_2);
nvs_get_u16(nvs_handle, "frequency", &sensor_config->hardware_config.measurement_frequency); err += nvs_get_u8(nvs_handle, "power_pin", &sensor_config->hardware_config.power_pin);
nvs_get_u8(nvs_handle, "battery_power", (uint8_t *)&sensor_config->hardware_config.battery_power); err += nvs_get_u16(nvs_handle, "frequency", &sensor_config->hardware_config.measurement_frequency);
err += nvs_get_u8(nvs_handle, "battery_power", (uint8_t *)&sensor_config->hardware_config.battery_power);
nvs_close(nvs_handle); nvs_close(nvs_handle);
if (err != ESP_OK)
{
goto SETUP_INITIAL_SETTINGS;
}
} }
void zh_save_config(const sensor_config_t *sensor_config) void zh_save_config(const sensor_config_t *sensor_config)
@ -291,8 +301,9 @@ void zh_sensor_deep_sleep(sensor_config_t *sensor_config)
#ifndef CONFIG_IDF_TARGET_ESP8266 #ifndef CONFIG_IDF_TARGET_ESP8266
esp_sleep_enable_timer_wakeup(sensor_config->hardware_config.measurement_frequency * 1000000); esp_sleep_enable_timer_wakeup(sensor_config->hardware_config.measurement_frequency * 1000000);
#endif #endif
uint8_t required_message_quantity = 1; uint8_t required_message_quantity = 2;
zh_send_sensor_hardware_config_message(sensor_config); zh_send_sensor_hardware_config_message(sensor_config);
zh_send_sensor_keep_alive_message_task(sensor_config);
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE) if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{ {
required_message_quantity += zh_send_sensor_config_message(sensor_config); required_message_quantity += zh_send_sensor_config_message(sensor_config);
@ -360,7 +371,7 @@ uint8_t zh_send_sensor_config_message(const sensor_config_t *sensor_config)
data.device_type = ZHDT_SENSOR; data.device_type = ZHDT_SENSOR;
data.payload_type = ZHPT_CONFIG; data.payload_type = ZHPT_CONFIG;
data.payload_data.config_message.sensor_config_message.suggested_display_precision = 1; data.payload_data.config_message.sensor_config_message.suggested_display_precision = 1;
data.payload_data.config_message.sensor_config_message.expire_after = sensor_config->hardware_config.measurement_frequency * 3; data.payload_data.config_message.sensor_config_message.expire_after = sensor_config->hardware_config.measurement_frequency * 1.5; // + 50% just in case.
data.payload_data.config_message.sensor_config_message.enabled_by_default = true; data.payload_data.config_message.sensor_config_message.enabled_by_default = true;
data.payload_data.config_message.sensor_config_message.force_update = true; data.payload_data.config_message.sensor_config_message.force_update = true;
data.payload_data.config_message.sensor_config_message.qos = 2; data.payload_data.config_message.sensor_config_message.qos = 2;
@ -385,7 +396,7 @@ uint8_t zh_send_sensor_config_message(const sensor_config_t *sensor_config)
case HAST_DHT: case HAST_DHT:
case HAST_AHT: case HAST_AHT:
case HAST_SHT: // For future development. case HAST_SHT: // For future development.
case HAST_HTU: // For future development. case HAST_HTU: // For future development.
case HAST_HDC1080: // For future development. case HAST_HDC1080: // For future development.
data.payload_data.config_message.sensor_config_message.unique_id = 2; data.payload_data.config_message.sensor_config_message.unique_id = 2;
data.payload_data.config_message.sensor_config_message.sensor_device_class = HASDC_TEMPERATURE; data.payload_data.config_message.sensor_config_message.sensor_device_class = HASDC_TEMPERATURE;
@ -428,8 +439,6 @@ void zh_send_sensor_status_message_task(void *pvParameter)
float illuminance = 0.0; float illuminance = 0.0;
zh_espnow_data_t data = {0}; zh_espnow_data_t data = {0};
data.device_type = ZHDT_SENSOR; data.device_type = ZHDT_SENSOR;
data.payload_type = ZHPT_STATE;
data.payload_data.status_message.sensor_status_message.sensor_type = sensor_config->hardware_config.sensor_type;
for (;;) for (;;)
{ {
if (sensor_config->hardware_config.power_pin != ZH_NOT_USED && sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_pin_2 == ZH_NOT_USED) if (sensor_config->hardware_config.power_pin != ZH_NOT_USED && sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_pin_2 == ZH_NOT_USED)
@ -448,6 +457,8 @@ void zh_send_sensor_status_message_task(void *pvParameter)
break; break;
} }
} }
uint8_t attempts = 0;
READ_SENSOR:;
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
switch (sensor_config->hardware_config.sensor_type) switch (sensor_config->hardware_config.sensor_type)
{ {
@ -502,11 +513,24 @@ void zh_send_sensor_status_message_task(void *pvParameter)
} }
if (err == ESP_OK) if (err == ESP_OK)
{ {
data.payload_type = ZHPT_STATE;
data.payload_data.status_message.sensor_status_message.sensor_type = sensor_config->hardware_config.sensor_type;
zh_send_message(sensor_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t)); zh_send_message(sensor_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
} }
else else
{ {
zh_send_message(sensor_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t)); // For future development. Will be changed for sensor read error message. if (++attempts < ZH_SENSOR_READ_MAXIMUM_RETRY)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
goto READ_SENSOR;
}
data.payload_type = ZHPT_ERROR;
char *message = (char *)heap_caps_malloc(150, MALLOC_CAP_8BIT);
memset(message, 0, 150);
sprintf(message, "Sensor %s reading error. Error - %s.", zh_get_sensor_type_value_name(sensor_config->hardware_config.sensor_type), esp_err_to_name(err));
strcpy(data.payload_data.status_message.error_message.message, message);
zh_send_message(sensor_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
heap_caps_free(message);
} }
if (gpio_get_level(sensor_config->hardware_config.power_pin) == 1) if (gpio_get_level(sensor_config->hardware_config.power_pin) == 1)
{ {
@ -521,6 +545,26 @@ void zh_send_sensor_status_message_task(void *pvParameter)
vTaskDelete(NULL); vTaskDelete(NULL);
} }
void zh_send_sensor_keep_alive_message_task(void *pvParameter)
{
sensor_config_t *sensor_config = pvParameter;
zh_espnow_data_t data = {0};
data.device_type = ZHDT_SENSOR;
data.payload_type = ZHPT_KEEP_ALIVE;
data.payload_data.keep_alive_message.online_status = ZH_ONLINE;
data.payload_data.keep_alive_message.message_frequency = ZH_SENSOR_KEEP_ALIVE_MESSAGE_FREQUENCY;
for (;;)
{
zh_send_message(sensor_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
if (sensor_config->hardware_config.battery_power == true)
{
return;
}
vTaskDelay(ZH_SENSOR_KEEP_ALIVE_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{ {
sensor_config_t *sensor_config = arg; sensor_config_t *sensor_config = arg;
@ -558,8 +602,19 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE) if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{ {
zh_send_sensor_config_message(sensor_config); zh_send_sensor_config_message(sensor_config);
xTaskCreatePinnedToCore(&zh_send_sensor_status_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, sensor_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&sensor_config->status_message_task, tskNO_AFFINITY); if (sensor_config->is_first_connection == false)
xTaskCreatePinnedToCore(&zh_send_sensor_attributes_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, sensor_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&sensor_config->attributes_message_task, tskNO_AFFINITY); {
xTaskCreatePinnedToCore(&zh_send_sensor_status_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, sensor_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&sensor_config->status_message_task, tskNO_AFFINITY);
xTaskCreatePinnedToCore(&zh_send_sensor_attributes_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, sensor_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&sensor_config->attributes_message_task, tskNO_AFFINITY);
xTaskCreatePinnedToCore(&zh_send_sensor_keep_alive_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, sensor_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&sensor_config->keep_alive_message_task, tskNO_AFFINITY);
sensor_config->is_first_connection = true;
}
else
{
vTaskResume(sensor_config->status_message_task);
vTaskResume(sensor_config->attributes_message_task);
vTaskResume(sensor_config->keep_alive_message_task);
}
} }
} }
} }
@ -570,8 +625,9 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
sensor_config->gateway_is_available = false; sensor_config->gateway_is_available = false;
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE) if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{ {
vTaskDelete(sensor_config->status_message_task); vTaskSuspend(sensor_config->status_message_task);
vTaskDelete(sensor_config->attributes_message_task); vTaskSuspend(sensor_config->attributes_message_task);
vTaskSuspend(sensor_config->keep_alive_message_task);
} }
} }
} }
@ -584,9 +640,32 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
sensor_config->hardware_config.measurement_frequency = data->payload_data.config_message.sensor_hardware_config_message.measurement_frequency; sensor_config->hardware_config.measurement_frequency = data->payload_data.config_message.sensor_hardware_config_message.measurement_frequency;
sensor_config->hardware_config.battery_power = data->payload_data.config_message.sensor_hardware_config_message.battery_power; sensor_config->hardware_config.battery_power = data->payload_data.config_message.sensor_hardware_config_message.battery_power;
zh_save_config(sensor_config); zh_save_config(sensor_config);
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{
vTaskDelete(sensor_config->status_message_task);
vTaskDelete(sensor_config->attributes_message_task);
vTaskDelete(sensor_config->keep_alive_message_task);
}
data->device_type = ZHDT_SENSOR;
data->payload_type = ZHPT_KEEP_ALIVE;
data->payload_data.keep_alive_message.online_status = ZH_OFFLINE;
data->payload_data.keep_alive_message.message_frequency = ZH_SENSOR_KEEP_ALIVE_MESSAGE_FREQUENCY;
zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
vTaskDelay(1000 / portTICK_PERIOD_MS);
esp_restart(); esp_restart();
break; break;
case ZHPT_UPDATE:; case ZHPT_UPDATE:;
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{
vTaskSuspend(sensor_config->status_message_task);
vTaskSuspend(sensor_config->attributes_message_task);
vTaskSuspend(sensor_config->keep_alive_message_task);
}
data->device_type = ZHDT_SENSOR;
data->payload_type = ZHPT_KEEP_ALIVE;
data->payload_data.keep_alive_message.online_status = ZH_OFFLINE;
data->payload_data.keep_alive_message.message_frequency = ZH_SENSOR_KEEP_ALIVE_MESSAGE_FREQUENCY;
zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
const esp_app_desc_t *app_info = get_app_description(); const esp_app_desc_t *app_info = get_app_description();
sensor_config->update_partition = esp_ota_get_next_update_partition(NULL); sensor_config->update_partition = esp_ota_get_next_update_partition(NULL);
strcpy(data->payload_data.ota_message.espnow_ota_data.app_version, app_info->version); strcpy(data->payload_data.ota_message.espnow_ota_data.app_version, app_info->version);
@ -599,7 +678,6 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
#else #else
strcpy(data->payload_data.ota_message.espnow_ota_data.app_name, app_info->project_name); strcpy(data->payload_data.ota_message.espnow_ota_data.app_name, app_info->project_name);
#endif #endif
data->device_type = ZHDT_SENSOR;
data->payload_type = ZHPT_UPDATE; data->payload_type = ZHPT_UPDATE;
zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t)); zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
break; break;
@ -626,6 +704,12 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
break; break;
case ZHPT_UPDATE_ERROR: case ZHPT_UPDATE_ERROR:
esp_ota_end(sensor_config->update_handle); esp_ota_end(sensor_config->update_handle);
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{
vTaskResume(sensor_config->status_message_task);
vTaskResume(sensor_config->attributes_message_task);
vTaskResume(sensor_config->keep_alive_message_task);
}
break; break;
case ZHPT_UPDATE_END: case ZHPT_UPDATE_END:
if (esp_ota_end(sensor_config->update_handle) != ESP_OK) if (esp_ota_end(sensor_config->update_handle) != ESP_OK)
@ -633,6 +717,12 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
data->device_type = ZHDT_SENSOR; data->device_type = ZHDT_SENSOR;
data->payload_type = ZHPT_UPDATE_FAIL; data->payload_type = ZHPT_UPDATE_FAIL;
zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t)); zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{
vTaskResume(sensor_config->status_message_task);
vTaskResume(sensor_config->attributes_message_task);
vTaskResume(sensor_config->keep_alive_message_task);
}
break; break;
} }
esp_ota_set_boot_partition(sensor_config->update_partition); esp_ota_set_boot_partition(sensor_config->update_partition);
@ -643,6 +733,18 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
esp_restart(); esp_restart();
break; break;
case ZHPT_RESTART: case ZHPT_RESTART:
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{
vTaskDelete(sensor_config->status_message_task);
vTaskDelete(sensor_config->attributes_message_task);
vTaskDelete(sensor_config->keep_alive_message_task);
}
data->device_type = ZHDT_SENSOR;
data->payload_type = ZHPT_KEEP_ALIVE;
data->payload_data.keep_alive_message.online_status = ZH_OFFLINE;
data->payload_data.keep_alive_message.message_frequency = ZH_SENSOR_KEEP_ALIVE_MESSAGE_FREQUENCY;
zh_send_message(sensor_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
vTaskDelay(1000 / portTICK_PERIOD_MS);
esp_restart(); esp_restart();
break; break;
default: default:
@ -665,8 +767,9 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
sensor_config->gateway_is_available = false; sensor_config->gateway_is_available = false;
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE) if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{ {
vTaskDelete(sensor_config->status_message_task); vTaskSuspend(sensor_config->status_message_task);
vTaskDelete(sensor_config->attributes_message_task); vTaskSuspend(sensor_config->attributes_message_task);
vTaskSuspend(sensor_config->keep_alive_message_task);
} }
} }
} }
@ -688,8 +791,9 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
sensor_config->gateway_is_available = false; sensor_config->gateway_is_available = false;
if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE) if (sensor_config->hardware_config.sensor_pin_1 != ZH_NOT_USED && sensor_config->hardware_config.sensor_type != HAST_NONE)
{ {
vTaskDelete(sensor_config->status_message_task); vTaskSuspend(sensor_config->status_message_task);
vTaskDelete(sensor_config->attributes_message_task); vTaskSuspend(sensor_config->attributes_message_task);
vTaskSuspend(sensor_config->keep_alive_message_task);
} }
} }
} }

View File

@ -51,10 +51,12 @@
#define I2C_PORT (I2C_NUM_MAX - 1) #define I2C_PORT (I2C_NUM_MAX - 1)
#define DS18B20_POWER_STABILIZATION_PERIOD 500 // Power stabilization period after the sensor is turned on. The value is selected experimentally. #define DS18B20_POWER_STABILIZATION_PERIOD 500 // Power stabilization period after the sensor is turned on (in seconds). The value is selected experimentally.
#define DHT_POWER_STABILIZATION_PERIOD 2000 // Power stabilization period after the sensor is turned on. The value is selected experimentally. #define DHT_POWER_STABILIZATION_PERIOD 2000 // Power stabilization period after the sensor is turned on (in seconds). The value is selected experimentally.
#define ZH_SENSOR_ATTRIBUTES_MESSAGE_FREQUENCY 60 // Frequency of transmission of keep alive messages to the gateway (in seconds). #define ZH_SENSOR_KEEP_ALIVE_MESSAGE_FREQUENCY 10 // Frequency of sending a keep alive message to the gateway (in seconds).
#define ZH_SENSOR_ATTRIBUTES_MESSAGE_FREQUENCY 60 // Frequency of transmission a sensor attributes message to the gateway (in seconds).
#define ZH_SENSOR_READ_MAXIMUM_RETRY 5 // Maximum number of read sensor attempts.
#define ZH_MESSAGE_TASK_PRIORITY 2 // Prioritize the task of sending messages to the gateway. #define ZH_MESSAGE_TASK_PRIORITY 2 // Prioritize the task of sending messages to the gateway.
#define ZH_MESSAGE_STACK_SIZE 2048 // The stack size of the task of sending messages to the gateway. #define ZH_MESSAGE_STACK_SIZE 2048 // The stack size of the task of sending messages to the gateway.
@ -71,10 +73,12 @@ typedef struct // Structure of data exchange between tasks, functions and event
bool battery_power; // Battery powered. @note Battery powering (true) / external powering (false). bool battery_power; // Battery powered. @note Battery powering (true) / external powering (false).
} hardware_config; } hardware_config;
volatile bool gateway_is_available; // Gateway availability status flag. @note Used to control the tasks when the gateway connection is established / lost. Used only when external powered. volatile bool gateway_is_available; // Gateway availability status flag. @note Used to control the tasks when the gateway connection is established / lost. Used only when external powered.
volatile bool is_first_connection; // First connection status flag. @note Used to control the tasks when the gateway connection is established / lost.
uint8_t gateway_mac[6]; // Gateway MAC address. @note Used only when external powered. uint8_t gateway_mac[6]; // Gateway MAC address. @note Used only when external powered.
uint8_t sent_message_quantity; // System counter for the number of sended messages. @note Used only when powered by battery. uint8_t sent_message_quantity; // System counter for the number of sended messages. @note Used only when powered by battery.
TaskHandle_t attributes_message_task; // Unique task handle for zh_send_sensor_attributes_message_task(). @note Used only when external powered. TaskHandle_t attributes_message_task; // Unique task handle for zh_send_sensor_attributes_message_task(). @note Used only when external powered.
TaskHandle_t status_message_task; // Unique task handle for zh_send_sensor_status_message_task(). @note Used only when external powered. TaskHandle_t status_message_task; // Unique task handle for zh_send_sensor_status_message_task(). @note Used only when external powered.
TaskHandle_t keep_alive_message_task; // Unique task handle for zh_send_sensor_keep_alive_message_task(). @note Used only when external powered.
const esp_partition_t *update_partition; // Unique handle for next OTA update partition. @note Used only when external powered. const esp_partition_t *update_partition; // Unique handle for next OTA update partition. @note Used only when external powered.
esp_ota_handle_t update_handle; // Unique handle for OTA functions. @note Used only when external powered. esp_ota_handle_t update_handle; // Unique handle for OTA functions. @note Used only when external powered.
uint16_t ota_message_part_number; // System counter for the number of received OTA messages. @note Used only when external powered. uint16_t ota_message_part_number; // System counter for the number of received OTA messages. @note Used only when external powered.
@ -157,6 +161,13 @@ uint8_t zh_send_sensor_config_message(const sensor_config_t *sensor_config);
*/ */
void zh_send_sensor_status_message_task(void *pvParameter); void zh_send_sensor_status_message_task(void *pvParameter);
/**
* @brief Task for prepare the sensor keep alive message and sending it to the gateway.
*
* @param[in] pvParameter Pointer to the structure of data exchange between tasks, functions and event handlers.
*/
void zh_send_sensor_keep_alive_message_task(void *pvParameter);
/** /**
* @brief Function for ESP-NOW event processing. * @brief Function for ESP-NOW event processing.
* *

View File

@ -1 +1 @@
1.0.2 1.0.5