Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
3ffdfae7b3 | |||
5dd44ec825 | |||
5045741079 | |||
897224744f | |||
80d3c9953c | |||
02ec02edcc | |||
b5def82a15 | |||
708bf211fa | |||
31b7789873 | |||
6e27f40bf1 | |||
577d5478a8 | |||
10640f64b5 | |||
1699554c74 | |||
2f6c37038b |
15
.gitmodules
vendored
15
.gitmodules
vendored
@ -1,18 +1,3 @@
|
||||
[submodule "components/zh_ds18b20"]
|
||||
path = components/zh_ds18b20
|
||||
url = https://github.com/aZholtikov/zh_ds18b20
|
||||
[submodule "components/zh_onewire"]
|
||||
path = components/zh_onewire
|
||||
url = https://github.com/aZholtikov/zh_onewire
|
||||
[submodule "components/zh_dht"]
|
||||
path = components/zh_dht
|
||||
url = https://github.com/aZholtikov/zh_dht
|
||||
[submodule "components/zh_network"]
|
||||
path = components/zh_network
|
||||
url = https://github.com/aZholtikov/zh_network
|
||||
[submodule "components/zh_vector"]
|
||||
path = components/zh_vector
|
||||
url = https://github.com/aZholtikov/zh_vector
|
||||
[submodule "components/zh_config"]
|
||||
path = components/zh_config
|
||||
url = https://github.com/aZholtikov/zh_config
|
||||
|
20
README.md
20
README.md
@ -1,30 +1,26 @@
|
||||
# ESP-NOW switch
|
||||
|
||||
ESP-NOW based switch for ESP32 ESP-IDF and ESP8266 RTOS SDK. Alternate firmware for Tuya/SmartLife/eWeLink WiFi switches.
|
||||
ESP-NOW based switch for ESP32 ESP-IDF and ESP8266 RTOS_SDK. Alternate firmware for Tuya/SmartLife/eWeLink WiFi switches.
|
||||
|
||||
## Tested on
|
||||
|
||||
1. ESP8266 RTOS_SDK v3.4
|
||||
2. ESP32 ESP-IDF v5.2
|
||||
2. ESP32 ESP-IDF v5.4
|
||||
|
||||
## Features
|
||||
|
||||
1. Saves the last state when the power is turned off.
|
||||
2. Automatically adds switch configuration to Home Assistan via MQTT discovery as a switch.
|
||||
3. Update firmware from HTTPS server via ESP-NOW.
|
||||
4. Optional support one external sensor (DS18B20, DHT11, DHT22).
|
||||
5. Direct or mesh work mode.
|
||||
|
||||
## Notes
|
||||
|
||||
1. Work mode must be same with [gateway](https://github.com/aZholtikov/zh_gateway) 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 ESP-NOW Switch Configuration". After first boot all settings will be stored in NVS memory for prevente change during OTA firmware update.
|
||||
4. To restart the switch, send the "restart" command to the root topic of the switch (example - "homeassistant/espnow_switch/24-62-AB-F9-1F-A8").
|
||||
5. To update the switch firmware, send the "update" command to the root topic of the switch (example - "homeassistant/espnow_switch/70-03-9F-44-BE-F7"). The update path should be like as "https://your_server/zh_espnow_switch_esp32.bin" (for ESP32) or "https://your_server/zh_espnow_switch_esp8266.app1.bin + https://your_server/zh_espnow_switch_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 will be displayed in the root switch topic.
|
||||
6. To change initial settings of the switch (except work mode), send the X1,X2,X3,X4,X5,X6,X7,X8,X9,X10 command to the hardware topic of the switch (example - "homeassistant/espnow_switch/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 switch (example - "homeassistant/espnow_switch/70-03-9F-44-BE-F7/config").
|
||||
1. For initial settings use "menuconfig -> ZH ESP-NOW Switch Configuration". After first boot all settings will be stored in NVS memory for prevente change during OTA firmware update.
|
||||
2. To restart the switch, send the "restart" command to the root topic of the switch (example - "homeassistant/espnow_switch/24-62-AB-F9-1F-A8").
|
||||
3. To update the switch firmware, send the "update" command to the root topic of the switch (example - "homeassistant/espnow_switch/70-03-9F-44-BE-F7"). The update path should be like as "https://your_server/zh_espnow_switch_esp32.bin" (for ESP32) or "https://your_server/zh_espnow_switch_esp8266.app1.bin + https://your_server/zh_espnow_switch_esp8266.app2.bin" (for ESP8266). Average update time is up to one minute. The status of the update will be displayed in the root switch topic.
|
||||
4. To change initial settings of the switch, send the X1,X2,X3,X4,X5,X6,X7,X8 command to the hardware topic of the switch (example - "homeassistant/espnow_switch/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 switch (example - "homeassistant/espnow_switch/70-03-9F-44-BE-F7/config").
|
||||
|
||||
MQTT configuration message should filled according to the template "X1,X2,X3,X4,X5,X6,X7,X8,X9,X10". Where:
|
||||
MQTT configuration message should filled according to the template "X1,X2,X3,X4,X5,X6,X7,X8". Where:
|
||||
|
||||
1. X1 - Relay GPIO number. 0 - 48 (according to the module used), 255 if not used.
|
||||
2. X2 - Relay ON level. 1 for high, 0 for low. Only affected when X1 is used.
|
||||
@ -34,8 +30,6 @@ MQTT configuration message should filled according to the template "X1,X2,X3,X4,
|
||||
6. X6 - Internal button trigger level. 1 for high, 0 for low. Only affected when X5 is used.
|
||||
7. X7 - External button GPIO number. 0 - 48 (according to the module used), 255 if not used.
|
||||
8. X8 - External button trigger level. 1 for high, 0 for low. Only affected when X7 is used.
|
||||
9. X9 - Sensor GPIO number. 0 - 48 (according to the module used). 255 if not used.
|
||||
10. X10 - Sensor type. 1 for DS18B20, 2 for DHT11, 3 for DHT22. Only affected when X9 is used.
|
||||
|
||||
## Build and flash
|
||||
|
||||
|
Submodule components/zh_config updated: bc12b2ca4b...73e8a70f4f
Submodule components/zh_dht deleted from 7662593a30
Submodule components/zh_ds18b20 deleted from 88bf443320
Submodule components/zh_espnow updated: 742c807c41...af7fa204e1
Submodule components/zh_network deleted from 783b44fbca
Submodule components/zh_onewire deleted from c2993a5059
Submodule components/zh_vector deleted from 53cdc76873
@ -14,7 +14,7 @@
|
||||
|
||||
Using MQTT:
|
||||
|
||||
"12,1,4,0,13,0,255,0,255,0"
|
||||
"12,1,4,0,13,0,255,0"
|
||||
```
|
||||
|
||||
2. MINI 1CH 16A. Built on Tuya WiFi module WB2S (BK7231T chip). Replacement with ESP-02S (TYWE2S). [Photo](http://git.zh.com.ru/alexey.zholtikov/zh_espnow_switch/src/branch/main/hardware/MINI_1CH_16A).
|
||||
@ -29,11 +29,11 @@
|
||||
Internal button GPIO number 3
|
||||
Internal button trigger level LOW
|
||||
External button GPIO number 14
|
||||
External button trigger level HIGH
|
||||
External button trigger level LOW
|
||||
|
||||
Using MQTT:
|
||||
|
||||
"13,1,4,0,3,0,14,1,255,0"
|
||||
"13,1,4,0,3,0,14,1"
|
||||
```
|
||||
|
||||
3. LIGHT E27 SOCKET. Built on Tuya WiFi module WA2 (WB2S) (BK7231T chip). Replacement with ESP-02S (TYWE2S). [Photo](http://git.zh.com.ru/alexey.zholtikov/zh_espnow_switch/src/branch/main/hardware/LIGHT_E27_SOCKET).
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
Using MQTT:
|
||||
|
||||
"12,1,4,0,13,0,255,0,255,0"
|
||||
"12,1,4,0,13,0,255,0"
|
||||
```
|
||||
|
||||
4. TH 1CH 16A + DS18B20. Built on ITEAD WiFi module PSF-B85 (ESP8285 chip). Replacement not required. [Photo](http://git.zh.com.ru/alexey.zholtikov/zh_espnow_switch/src/branch/main/hardware/TH_1CH_16A).
|
||||
@ -64,10 +64,8 @@
|
||||
Led ON level LOW
|
||||
Internal button GPIO number 0
|
||||
Internal button trigger level LOW
|
||||
Sensor GPIO number 14
|
||||
Sensor type DS18B20
|
||||
|
||||
Using MQTT:
|
||||
|
||||
"12,1,13,0,0,0,255,0,14,1"
|
||||
"12,1,13,0,0,0,255,0"
|
||||
```
|
Binary file not shown.
Before Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
Before Width: | Height: | Size: 3.3 MiB |
@ -9,17 +9,6 @@ menu "ZH ESP-NOW Switch Configuration"
|
||||
default 18 if IDF_TARGET_ESP32C2
|
||||
default 19 if IDF_TARGET_ESP32C3
|
||||
default 30 if IDF_TARGET_ESP32C6
|
||||
|
||||
choice NETWORK_TYPE
|
||||
prompt "Network type"
|
||||
help
|
||||
Network type.
|
||||
default NETWORK_TYPE_DIRECT
|
||||
config NETWORK_TYPE_DIRECT
|
||||
bool "DIRECT"
|
||||
config NETWORK_TYPE_MESH
|
||||
bool "MESH"
|
||||
endchoice
|
||||
|
||||
config RELAY_USING
|
||||
bool "Enable using relay"
|
||||
@ -128,31 +117,4 @@ menu "ZH ESP-NOW Switch Configuration"
|
||||
bool "LOW"
|
||||
endchoice
|
||||
|
||||
config SENSOR_USING
|
||||
depends on RELAY_USING
|
||||
bool "Enable using external sensor"
|
||||
default false
|
||||
help
|
||||
Enable using external sensor.
|
||||
|
||||
config SENSOR_PIN
|
||||
depends on SENSOR_USING
|
||||
int "Sensor GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 2
|
||||
help
|
||||
Sensor GPIO.
|
||||
|
||||
choice SENSOR_TYPE
|
||||
depends on SENSOR_USING
|
||||
prompt "Sensor type"
|
||||
help
|
||||
Sensor type.
|
||||
default SENSOR_TYPE_DS18B20
|
||||
config SENSOR_TYPE_DS18B20
|
||||
bool "DS18B20"
|
||||
config SENSOR_TYPE_DHT
|
||||
bool "DHT"
|
||||
endchoice
|
||||
|
||||
endmenu
|
@ -15,19 +15,18 @@ void app_main(void)
|
||||
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();
|
||||
#ifdef CONFIG_NETWORK_TYPE_DIRECT
|
||||
zh_espnow_init_config_t espnow_init_config = ZH_ESPNOW_INIT_CONFIG_DEFAULT();
|
||||
zh_espnow_init(&espnow_init_config);
|
||||
#else
|
||||
zh_network_init_config_t network_init_config = ZH_NETWORK_INIT_CONFIG_DEFAULT();
|
||||
zh_network_init(&network_init_config);
|
||||
#endif
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_attributes_message_task, "switch_attributes_message_task", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_keep_alive_message_task, "switch_keep_alive_message_task", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_config_message_task, "switch_config_message_task", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_hardware_config_message_task, "switch_hardware_config_message_task", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_status_message_task, "switch_status_message_task", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP8266
|
||||
esp_event_handler_register(ZH_EVENT, ESP_EVENT_ANY_ID, &zh_espnow_event_handler, switch_config);
|
||||
esp_event_handler_register(ZH_ESPNOW, ESP_EVENT_ANY_ID, &zh_espnow_event_handler, switch_config);
|
||||
#else
|
||||
esp_event_handler_instance_register(ZH_EVENT, ESP_EVENT_ANY_ID, &zh_espnow_event_handler, switch_config, NULL);
|
||||
esp_event_handler_instance_register(ZH_ESPNOW, ESP_EVENT_ANY_ID, &zh_espnow_event_handler, switch_config, NULL);
|
||||
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);
|
||||
@ -46,8 +45,8 @@ void zh_load_config(switch_config_t *switch_config)
|
||||
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);
|
||||
SETUP_INITIAL_SETTINGS:
|
||||
#ifdef CONFIG_RELAY_USING
|
||||
switch_config->hardware_config.relay_pin = CONFIG_RELAY_PIN;
|
||||
#else
|
||||
@ -87,37 +86,31 @@ void zh_load_config(switch_config_t *switch_config)
|
||||
switch_config->hardware_config.ext_button_on_level = ZH_HIGH;
|
||||
#else
|
||||
switch_config->hardware_config.ext_button_on_level = ZH_LOW;
|
||||
#endif
|
||||
#ifdef CONFIG_SENSOR_TYPE_DS18B20
|
||||
switch_config->hardware_config.sensor_pin = CONFIG_SENSOR_PIN;
|
||||
switch_config->hardware_config.sensor_type = HAST_DS18B20;
|
||||
#elif CONFIG_SENSOR_TYPE_DHT
|
||||
switch_config->hardware_config.sensor_pin = CONFIG_SENSOR_PIN;
|
||||
switch_config->hardware_config.sensor_type = HAST_DHT;
|
||||
#else
|
||||
switch_config->hardware_config.sensor_pin = ZH_NOT_USED;
|
||||
switch_config->hardware_config.sensor_type = HAST_NONE;
|
||||
#endif
|
||||
zh_save_config(switch_config);
|
||||
return;
|
||||
}
|
||||
nvs_get_u8(nvs_handle, "relay_pin", &switch_config->hardware_config.relay_pin);
|
||||
nvs_get_u8(nvs_handle, "relay_lvl", (uint8_t *)&switch_config->hardware_config.relay_on_level);
|
||||
nvs_get_u8(nvs_handle, "led_pin", &switch_config->hardware_config.led_pin);
|
||||
nvs_get_u8(nvs_handle, "led_lvl", (uint8_t *)&switch_config->hardware_config.led_on_level);
|
||||
nvs_get_u8(nvs_handle, "int_btn_pin", &switch_config->hardware_config.int_button_pin);
|
||||
nvs_get_u8(nvs_handle, "int_btn_lvl", (uint8_t *)&switch_config->hardware_config.int_button_on_level);
|
||||
nvs_get_u8(nvs_handle, "ext_btn_pin", &switch_config->hardware_config.ext_button_pin);
|
||||
nvs_get_u8(nvs_handle, "ext_btn_lvl", (uint8_t *)&switch_config->hardware_config.ext_button_on_level);
|
||||
nvs_get_u8(nvs_handle, "sensor_pin", &switch_config->hardware_config.sensor_pin);
|
||||
nvs_get_u8(nvs_handle, "sensor_type", (uint8_t *)&switch_config->hardware_config.sensor_type);
|
||||
esp_err_t err = ESP_OK;
|
||||
err += nvs_get_u8(nvs_handle, "relay_pin", &switch_config->hardware_config.relay_pin);
|
||||
err += nvs_get_u8(nvs_handle, "relay_lvl", (uint8_t *)&switch_config->hardware_config.relay_on_level);
|
||||
err += nvs_get_u8(nvs_handle, "led_pin", &switch_config->hardware_config.led_pin);
|
||||
err += nvs_get_u8(nvs_handle, "led_lvl", (uint8_t *)&switch_config->hardware_config.led_on_level);
|
||||
err += nvs_get_u8(nvs_handle, "int_btn_pin", &switch_config->hardware_config.int_button_pin);
|
||||
err += nvs_get_u8(nvs_handle, "int_btn_lvl", (uint8_t *)&switch_config->hardware_config.int_button_on_level);
|
||||
err += nvs_get_u8(nvs_handle, "ext_btn_pin", &switch_config->hardware_config.ext_button_pin);
|
||||
err += nvs_get_u8(nvs_handle, "ext_btn_lvl", (uint8_t *)&switch_config->hardware_config.ext_button_on_level);
|
||||
nvs_close(nvs_handle);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
goto SETUP_INITIAL_SETTINGS;
|
||||
}
|
||||
}
|
||||
|
||||
void zh_save_config(const switch_config_t *switch_config)
|
||||
{
|
||||
nvs_handle_t nvs_handle = 0;
|
||||
nvs_open("config", NVS_READWRITE, &nvs_handle);
|
||||
nvs_set_u8(nvs_handle, "present", 0xFE);
|
||||
nvs_set_u8(nvs_handle, "relay_pin", switch_config->hardware_config.relay_pin);
|
||||
nvs_set_u8(nvs_handle, "relay_lvl", switch_config->hardware_config.relay_on_level);
|
||||
nvs_set_u8(nvs_handle, "led_pin", switch_config->hardware_config.led_pin);
|
||||
@ -126,8 +119,6 @@ void zh_save_config(const switch_config_t *switch_config)
|
||||
nvs_set_u8(nvs_handle, "int_btn_lvl", switch_config->hardware_config.int_button_on_level);
|
||||
nvs_set_u8(nvs_handle, "ext_btn_pin", switch_config->hardware_config.ext_button_pin);
|
||||
nvs_set_u8(nvs_handle, "ext_btn_lvl", switch_config->hardware_config.ext_button_on_level);
|
||||
nvs_set_u8(nvs_handle, "sensor_pin", switch_config->hardware_config.sensor_pin);
|
||||
nvs_set_u8(nvs_handle, "sensor_type", switch_config->hardware_config.sensor_type);
|
||||
nvs_close(nvs_handle);
|
||||
}
|
||||
|
||||
@ -139,7 +130,6 @@ void zh_load_status(switch_config_t *switch_config)
|
||||
uint8_t status_is_present = 0;
|
||||
if (nvs_get_u8(nvs_handle, "present", &status_is_present) == ESP_ERR_NVS_NOT_FOUND)
|
||||
{
|
||||
nvs_set_u8(nvs_handle, "present", 0xFE);
|
||||
nvs_close(nvs_handle);
|
||||
zh_save_status(switch_config);
|
||||
return;
|
||||
@ -152,6 +142,7 @@ void zh_save_status(const switch_config_t *switch_config)
|
||||
{
|
||||
nvs_handle_t nvs_handle = 0;
|
||||
nvs_open("status", NVS_READWRITE, &nvs_handle);
|
||||
nvs_set_u8(nvs_handle, "present", 0xFE);
|
||||
nvs_set_u8(nvs_handle, "relay_state", switch_config->status.status);
|
||||
nvs_close(nvs_handle);
|
||||
}
|
||||
@ -172,7 +163,6 @@ void zh_gpio_init(switch_config_t *switch_config)
|
||||
switch_config->hardware_config.led_pin = ZH_NOT_USED;
|
||||
switch_config->hardware_config.int_button_pin = ZH_NOT_USED;
|
||||
switch_config->hardware_config.ext_button_pin = ZH_NOT_USED;
|
||||
switch_config->hardware_config.sensor_pin = ZH_NOT_USED;
|
||||
return;
|
||||
}
|
||||
if (switch_config->hardware_config.led_pin != ZH_NOT_USED)
|
||||
@ -214,7 +204,7 @@ void zh_gpio_init(switch_config_t *switch_config)
|
||||
if (switch_config->hardware_config.int_button_pin != ZH_NOT_USED || switch_config->hardware_config.ext_button_pin != ZH_NOT_USED)
|
||||
{
|
||||
switch_config->button_pushing_semaphore = xSemaphoreCreateBinary();
|
||||
xTaskCreatePinnedToCore(&zh_gpio_processing_task, "NULL", ZH_GPIO_STACK_SIZE, switch_config, ZH_GPIO_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_gpio_processing_task, "gpio_processing_task", ZH_GPIO_STACK_SIZE, switch_config, ZH_GPIO_TASK_PRIORITY, NULL, tskNO_AFFINITY);
|
||||
gpio_install_isr_service(0);
|
||||
if (switch_config->hardware_config.int_button_pin != ZH_NOT_USED)
|
||||
{
|
||||
@ -225,30 +215,6 @@ void zh_gpio_init(switch_config_t *switch_config)
|
||||
gpio_isr_handler_add(switch_config->hardware_config.ext_button_pin, zh_gpio_isr_handler, switch_config);
|
||||
}
|
||||
}
|
||||
if (switch_config->hardware_config.sensor_pin != ZH_NOT_USED)
|
||||
{
|
||||
switch (switch_config->hardware_config.sensor_type)
|
||||
{
|
||||
case HAST_DS18B20:
|
||||
if (zh_onewire_init(switch_config->hardware_config.sensor_pin) != ESP_OK)
|
||||
{
|
||||
switch_config->hardware_config.sensor_pin = ZH_NOT_USED;
|
||||
}
|
||||
break;
|
||||
case HAST_DHT:;
|
||||
zh_dht_init_config_t dht_init_config = ZH_DHT_INIT_CONFIG_DEFAULT();
|
||||
dht_init_config.sensor_pin = switch_config->hardware_config.sensor_pin;
|
||||
if (zh_dht_init(&dht_init_config) != ESP_OK)
|
||||
{
|
||||
switch_config->hardware_config.sensor_pin = ZH_NOT_USED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch_config->hardware_config.sensor_type = HAST_NONE;
|
||||
switch_config->hardware_config.sensor_pin = ZH_NOT_USED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,7 +244,7 @@ void zh_gpio_set_level(switch_config_t *switch_config)
|
||||
}
|
||||
}
|
||||
|
||||
void zh_gpio_isr_handler(void *arg)
|
||||
void IRAM_ATTR zh_gpio_isr_handler(void *arg)
|
||||
{
|
||||
switch_config_t *switch_config = arg;
|
||||
if (switch_config->gpio_processing == false)
|
||||
@ -297,10 +263,7 @@ void zh_gpio_processing_task(void *pvParameter)
|
||||
switch_config->status.status = (switch_config->status.status == HAONOFT_ON) ? HAONOFT_OFF : HAONOFT_ON;
|
||||
zh_gpio_set_level(switch_config);
|
||||
zh_save_status(switch_config);
|
||||
if (switch_config->gateway_is_available == true)
|
||||
{
|
||||
zh_send_switch_status_message(switch_config);
|
||||
}
|
||||
zh_send_switch_status_message(switch_config);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS); // To prevent button contact rattling. Value is selected experimentally.
|
||||
switch_config->gpio_processing = false;
|
||||
}
|
||||
@ -325,14 +288,15 @@ void zh_send_switch_attributes_message_task(void *pvParameter)
|
||||
data.payload_data.attributes_message.heap_size = esp_get_free_heap_size();
|
||||
data.payload_data.attributes_message.min_heap_size = esp_get_minimum_free_heap_size();
|
||||
data.payload_data.attributes_message.uptime = esp_timer_get_time() / 1000000;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SWITCH_ATTRIBUTES_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void zh_send_switch_config_message(const switch_config_t *switch_config)
|
||||
void zh_send_switch_config_message_task(void *pvParameter)
|
||||
{
|
||||
switch_config_t *switch_config = pvParameter;
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SWITCH;
|
||||
data.payload_type = ZHPT_CONFIG;
|
||||
@ -344,11 +308,17 @@ void zh_send_switch_config_message(const switch_config_t *switch_config)
|
||||
data.payload_data.config_message.switch_config_message.optimistic = false;
|
||||
data.payload_data.config_message.switch_config_message.qos = 2;
|
||||
data.payload_data.config_message.switch_config_message.retain = true;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
for (;;)
|
||||
{
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SWITCH_CONFIG_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void zh_send_switch_hardware_config_message(const switch_config_t *switch_config)
|
||||
void zh_send_switch_hardware_config_message_task(void *pvParameter)
|
||||
{
|
||||
switch_config_t *switch_config = pvParameter;
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SWITCH;
|
||||
data.payload_type = ZHPT_HARDWARE;
|
||||
@ -360,9 +330,12 @@ void zh_send_switch_hardware_config_message(const switch_config_t *switch_config
|
||||
data.payload_data.config_message.switch_hardware_config_message.int_button_on_level = switch_config->hardware_config.int_button_on_level;
|
||||
data.payload_data.config_message.switch_hardware_config_message.ext_button_pin = switch_config->hardware_config.ext_button_pin;
|
||||
data.payload_data.config_message.switch_hardware_config_message.ext_button_on_level = switch_config->hardware_config.ext_button_on_level;
|
||||
data.payload_data.config_message.switch_hardware_config_message.sensor_pin = switch_config->hardware_config.sensor_pin;
|
||||
data.payload_data.config_message.switch_hardware_config_message.sensor_type = switch_config->hardware_config.sensor_type;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
for (;;)
|
||||
{
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SWITCH_HARDWARE_CONFIG_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void zh_send_switch_keep_alive_message_task(void *pvParameter)
|
||||
@ -375,147 +348,34 @@ void zh_send_switch_keep_alive_message_task(void *pvParameter)
|
||||
data.payload_data.keep_alive_message.message_frequency = ZH_SWITCH_KEEP_ALIVE_MESSAGE_FREQUENCY;
|
||||
for (;;)
|
||||
{
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SWITCH_KEEP_ALIVE_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void zh_send_switch_status_message_task(void *pvParameter)
|
||||
{
|
||||
switch_config_t *switch_config = pvParameter;
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SWITCH;
|
||||
data.payload_type = ZHPT_STATE;
|
||||
for (;;)
|
||||
{
|
||||
data.payload_data.status_message.switch_status_message.status = switch_config->status.status;
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SWITCH_STATUS_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void zh_send_switch_status_message(const switch_config_t *switch_config)
|
||||
{
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SWITCH;
|
||||
data.payload_type = ZHPT_STATE;
|
||||
data.payload_data.status_message.switch_status_message.status = switch_config->status.status;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
}
|
||||
|
||||
void zh_send_sensor_config_message(const switch_config_t *switch_config)
|
||||
{
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SENSOR;
|
||||
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.expire_after = ZH_SENSOR_STATUS_MESSAGE_FREQUENCY * 3;
|
||||
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.qos = 2;
|
||||
data.payload_data.config_message.sensor_config_message.retain = true;
|
||||
char *unit_of_measurement = NULL;
|
||||
switch (switch_config->hardware_config.sensor_type)
|
||||
{
|
||||
case HAST_DS18B20:
|
||||
data.payload_data.config_message.sensor_config_message.unique_id = 2;
|
||||
data.payload_data.config_message.sensor_config_message.sensor_device_class = HASDC_TEMPERATURE;
|
||||
unit_of_measurement = "°C";
|
||||
strcpy(data.payload_data.config_message.sensor_config_message.unit_of_measurement, unit_of_measurement);
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
break;
|
||||
case HAST_DHT:
|
||||
data.payload_data.config_message.sensor_config_message.unique_id = 2;
|
||||
data.payload_data.config_message.sensor_config_message.sensor_device_class = HASDC_TEMPERATURE;
|
||||
unit_of_measurement = "°C";
|
||||
strcpy(data.payload_data.config_message.sensor_config_message.unit_of_measurement, unit_of_measurement);
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
data.payload_data.config_message.sensor_config_message.unique_id = 3;
|
||||
data.payload_data.config_message.sensor_config_message.sensor_device_class = HASDC_HUMIDITY;
|
||||
unit_of_measurement = "%";
|
||||
strcpy(data.payload_data.config_message.sensor_config_message.unit_of_measurement, unit_of_measurement);
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void zh_send_sensor_attributes_message_task(void *pvParameter)
|
||||
{
|
||||
switch_config_t *switch_config = pvParameter;
|
||||
const esp_app_desc_t *app_info = get_app_description();
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SENSOR;
|
||||
data.payload_type = ZHPT_ATTRIBUTES;
|
||||
data.payload_data.attributes_message.chip_type = ZH_CHIP_TYPE;
|
||||
data.payload_data.attributes_message.sensor_type = switch_config->hardware_config.sensor_type;
|
||||
strcpy(data.payload_data.attributes_message.flash_size, CONFIG_ESPTOOLPY_FLASHSIZE);
|
||||
data.payload_data.attributes_message.cpu_frequency = ZH_CPU_FREQUENCY;
|
||||
data.payload_data.attributes_message.reset_reason = (uint8_t)esp_reset_reason();
|
||||
strcpy(data.payload_data.attributes_message.app_name, app_info->project_name);
|
||||
strcpy(data.payload_data.attributes_message.app_version, app_info->version);
|
||||
for (;;)
|
||||
{
|
||||
data.payload_data.attributes_message.heap_size = esp_get_free_heap_size();
|
||||
data.payload_data.attributes_message.min_heap_size = esp_get_minimum_free_heap_size();
|
||||
data.payload_data.attributes_message.uptime = esp_timer_get_time() / 1000000;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SENSOR_ATTRIBUTES_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void zh_send_sensor_status_message_task(void *pvParameter)
|
||||
{
|
||||
switch_config_t *switch_config = pvParameter;
|
||||
float humidity = 0.0;
|
||||
float temperature = 0.0;
|
||||
zh_espnow_data_t data = {0};
|
||||
data.device_type = ZHDT_SENSOR;
|
||||
data.payload_type = ZHPT_STATE;
|
||||
data.payload_data.status_message.sensor_status_message.sensor_type = switch_config->hardware_config.sensor_type;
|
||||
for (;;)
|
||||
{
|
||||
switch (switch_config->hardware_config.sensor_type)
|
||||
{
|
||||
case HAST_DS18B20:
|
||||
ZH_DS18B20_READ:
|
||||
switch (zh_ds18b20_read(NULL, &temperature))
|
||||
{
|
||||
case ESP_OK:
|
||||
data.payload_data.status_message.sensor_status_message.temperature = temperature;
|
||||
break;
|
||||
case ESP_FAIL:
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||
goto ZH_DS18B20_READ;
|
||||
break;
|
||||
case ESP_ERR_INVALID_CRC:
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
goto ZH_DS18B20_READ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HAST_DHT:
|
||||
ZH_DHT_READ:
|
||||
switch (zh_dht_read(&humidity, &temperature))
|
||||
{
|
||||
case ESP_OK:
|
||||
data.payload_data.status_message.sensor_status_message.humidity = humidity;
|
||||
data.payload_data.status_message.sensor_status_message.temperature = temperature;
|
||||
break;
|
||||
case ESP_ERR_INVALID_RESPONSE:
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||
goto ZH_DHT_READ;
|
||||
break;
|
||||
case ESP_ERR_TIMEOUT:
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||
goto ZH_DHT_READ;
|
||||
break;
|
||||
case ESP_ERR_INVALID_CRC:
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
goto ZH_DHT_READ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(ZH_SENSOR_STATUS_MESSAGE_FREQUENCY * 1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)&data, sizeof(zh_espnow_data_t));
|
||||
}
|
||||
|
||||
void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
@ -523,21 +383,12 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
switch_config_t *switch_config = arg;
|
||||
switch (event_id)
|
||||
{
|
||||
#ifdef CONFIG_NETWORK_TYPE_DIRECT
|
||||
case ZH_ESPNOW_ON_RECV_EVENT:;
|
||||
zh_espnow_event_on_recv_t *recv_data = event_data;
|
||||
if (recv_data->data_len != sizeof(zh_espnow_data_t))
|
||||
{
|
||||
goto ZH_ESPNOW_EVENT_HANDLER_EXIT;
|
||||
}
|
||||
#else
|
||||
case ZH_NETWORK_ON_RECV_EVENT:;
|
||||
zh_network_event_on_recv_t *recv_data = event_data;
|
||||
if (recv_data->data_len != sizeof(zh_espnow_data_t))
|
||||
{
|
||||
goto ZH_NETWORK_EVENT_HANDLER_EXIT;
|
||||
}
|
||||
#endif
|
||||
zh_espnow_data_t *data = (zh_espnow_data_t *)recv_data->data;
|
||||
switch (data->device_type)
|
||||
{
|
||||
@ -545,45 +396,7 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
switch (data->payload_type)
|
||||
{
|
||||
case ZHPT_KEEP_ALIVE:
|
||||
if (data->payload_data.keep_alive_message.online_status == ZH_ONLINE)
|
||||
{
|
||||
if (switch_config->gateway_is_available == false)
|
||||
{
|
||||
switch_config->gateway_is_available = true;
|
||||
memcpy(switch_config->gateway_mac, recv_data->mac_addr, 6);
|
||||
zh_send_switch_hardware_config_message(switch_config);
|
||||
if (switch_config->hardware_config.relay_pin != ZH_NOT_USED)
|
||||
{
|
||||
zh_send_switch_config_message(switch_config);
|
||||
zh_send_switch_status_message(switch_config);
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_attributes_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&switch_config->switch_attributes_message_task, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_send_switch_keep_alive_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&switch_config->switch_keep_alive_message_task, tskNO_AFFINITY);
|
||||
if (switch_config->hardware_config.sensor_pin != ZH_NOT_USED && switch_config->hardware_config.sensor_type != HAST_NONE)
|
||||
{
|
||||
zh_send_sensor_config_message(switch_config);
|
||||
xTaskCreatePinnedToCore(&zh_send_sensor_status_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&switch_config->sensor_status_message_task, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&zh_send_sensor_attributes_message_task, "NULL", ZH_MESSAGE_STACK_SIZE, switch_config, ZH_MESSAGE_TASK_PRIORITY, (TaskHandle_t *)&switch_config->sensor_attributes_message_task, tskNO_AFFINITY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (switch_config->gateway_is_available == true)
|
||||
{
|
||||
switch_config->gateway_is_available = false;
|
||||
if (switch_config->hardware_config.relay_pin != ZH_NOT_USED)
|
||||
{
|
||||
vTaskDelete(switch_config->switch_attributes_message_task);
|
||||
vTaskDelete(switch_config->switch_keep_alive_message_task);
|
||||
if (switch_config->hardware_config.sensor_pin != ZH_NOT_USED && switch_config->hardware_config.sensor_type != HAST_NONE)
|
||||
{
|
||||
vTaskDelete(switch_config->sensor_attributes_message_task);
|
||||
vTaskDelete(switch_config->sensor_status_message_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(switch_config->gateway_mac, recv_data->mac_addr, 6);
|
||||
break;
|
||||
case ZHPT_SET:
|
||||
switch_config->status.status = data->payload_data.status_message.switch_status_message.status;
|
||||
@ -600,8 +413,6 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
switch_config->hardware_config.int_button_on_level = data->payload_data.config_message.switch_hardware_config_message.int_button_on_level;
|
||||
switch_config->hardware_config.ext_button_pin = data->payload_data.config_message.switch_hardware_config_message.ext_button_pin;
|
||||
switch_config->hardware_config.ext_button_on_level = data->payload_data.config_message.switch_hardware_config_message.ext_button_on_level;
|
||||
switch_config->hardware_config.sensor_pin = data->payload_data.config_message.switch_hardware_config_message.sensor_pin;
|
||||
switch_config->hardware_config.sensor_type = data->payload_data.config_message.switch_hardware_config_message.sensor_type;
|
||||
zh_save_config(switch_config);
|
||||
esp_restart();
|
||||
break;
|
||||
@ -618,9 +429,8 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
#else
|
||||
strcpy(data->payload_data.ota_message.espnow_ota_data.app_name, app_info->project_name);
|
||||
#endif
|
||||
data->device_type = ZHDT_SWITCH;
|
||||
data->payload_type = ZHPT_UPDATE;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
break;
|
||||
case ZHPT_UPDATE_BEGIN:
|
||||
#ifdef CONFIG_IDF_TARGET_ESP8266
|
||||
@ -631,7 +441,7 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
switch_config->ota_message_part_number = 1;
|
||||
data->device_type = ZHDT_SWITCH;
|
||||
data->payload_type = ZHPT_UPDATE_PROGRESS;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
break;
|
||||
case ZHPT_UPDATE_PROGRESS:
|
||||
if (switch_config->ota_message_part_number == data->payload_data.ota_message.espnow_ota_message.part)
|
||||
@ -641,7 +451,7 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
}
|
||||
data->device_type = ZHDT_SWITCH;
|
||||
data->payload_type = ZHPT_UPDATE_PROGRESS;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
break;
|
||||
case ZHPT_UPDATE_ERROR:
|
||||
esp_ota_end(switch_config->update_handle);
|
||||
@ -651,13 +461,13 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
{
|
||||
data->device_type = ZHDT_SWITCH;
|
||||
data->payload_type = ZHPT_UPDATE_FAIL;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
break;
|
||||
}
|
||||
esp_ota_set_boot_partition(switch_config->update_partition);
|
||||
data->device_type = ZHDT_SWITCH;
|
||||
data->payload_type = ZHPT_UPDATE_SUCCESS;
|
||||
zh_send_message(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
zh_espnow_send(switch_config->gateway_mac, (uint8_t *)data, sizeof(zh_espnow_data_t));
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
break;
|
||||
@ -671,49 +481,11 @@ void zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t eve
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_NETWORK_TYPE_DIRECT
|
||||
ZH_ESPNOW_EVENT_HANDLER_EXIT:
|
||||
heap_caps_free(recv_data->data);
|
||||
break;
|
||||
case ZH_ESPNOW_ON_SEND_EVENT:;
|
||||
zh_espnow_event_on_send_t *send_data = event_data;
|
||||
if (send_data->status == ZH_ESPNOW_SEND_FAIL && switch_config->gateway_is_available == true)
|
||||
{
|
||||
switch_config->gateway_is_available = false;
|
||||
if (switch_config->hardware_config.relay_pin != ZH_NOT_USED)
|
||||
{
|
||||
vTaskDelete(switch_config->switch_attributes_message_task);
|
||||
vTaskDelete(switch_config->switch_keep_alive_message_task);
|
||||
if (switch_config->hardware_config.sensor_pin != ZH_NOT_USED && switch_config->hardware_config.sensor_type != HAST_NONE)
|
||||
{
|
||||
vTaskDelete(switch_config->sensor_attributes_message_task);
|
||||
vTaskDelete(switch_config->sensor_status_message_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
case ZH_ESPNOW_ON_SEND_EVENT:
|
||||
break;
|
||||
#else
|
||||
ZH_NETWORK_EVENT_HANDLER_EXIT:
|
||||
heap_caps_free(recv_data->data);
|
||||
break;
|
||||
case ZH_NETWORK_ON_SEND_EVENT:;
|
||||
zh_network_event_on_send_t *send_data = event_data;
|
||||
if (send_data->status == ZH_NETWORK_SEND_FAIL && switch_config->gateway_is_available == true)
|
||||
{
|
||||
switch_config->gateway_is_available = false;
|
||||
if (switch_config->hardware_config.relay_pin != ZH_NOT_USED)
|
||||
{
|
||||
vTaskDelete(switch_config->switch_attributes_message_task);
|
||||
vTaskDelete(switch_config->switch_keep_alive_message_task);
|
||||
if (switch_config->hardware_config.sensor_pin != ZH_NOT_USED && switch_config->hardware_config.sensor_type != HAST_NONE)
|
||||
{
|
||||
vTaskDelete(switch_config->sensor_attributes_message_task);
|
||||
vTaskDelete(switch_config->sensor_status_message_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -8,19 +8,8 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "zh_ds18b20.h"
|
||||
#include "zh_dht.h"
|
||||
#include "zh_config.h"
|
||||
|
||||
#ifdef CONFIG_NETWORK_TYPE_DIRECT
|
||||
#include "zh_espnow.h"
|
||||
#define zh_send_message(a, b, c) zh_espnow_send(a, b, c)
|
||||
#define ZH_EVENT ZH_ESPNOW
|
||||
#else
|
||||
#include "zh_network.h"
|
||||
#define zh_send_message(a, b, c) zh_network_send(a, b, c)
|
||||
#define ZH_EVENT ZH_NETWORK
|
||||
#endif
|
||||
#include "zh_config.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP8266
|
||||
#define ZH_CHIP_TYPE HACHT_ESP8266
|
||||
@ -46,46 +35,40 @@
|
||||
#define get_app_description() esp_app_get_description()
|
||||
#endif
|
||||
|
||||
#define ZH_SWITCH_KEEP_ALIVE_MESSAGE_FREQUENCY 10 // Frequency of sending a switch keep alive message to the gateway (in seconds).
|
||||
#define ZH_SWITCH_ATTRIBUTES_MESSAGE_FREQUENCY 60 // Frequency of sending a switch attributes message to the gateway (in seconds).
|
||||
#define ZH_SENSOR_STATUS_MESSAGE_FREQUENCY 300 // // Frequency of sending a sensor status message to the gateway (in seconds).
|
||||
#define ZH_SENSOR_ATTRIBUTES_MESSAGE_FREQUENCY 60 // Frequency of sending a sensor attributes message to the gateway (in seconds).
|
||||
#define ZH_SWITCH_KEEP_ALIVE_MESSAGE_FREQUENCY 10 // Frequency of sending a switch keep alive message to the gateway (in seconds).
|
||||
#define ZH_SWITCH_ATTRIBUTES_MESSAGE_FREQUENCY 60 // Frequency of sending a switch attributes message to the gateway (in seconds).
|
||||
#define ZH_SWITCH_HARDWARE_CONFIG_MESSAGE_FREQUENCY 300 // Frequency of sending a switch hardware config message to the gateway (in seconds).
|
||||
#define ZH_SWITCH_CONFIG_MESSAGE_FREQUENCY 300 // Frequency of sending a switch config message to the gateway (in seconds).
|
||||
#define ZH_SWITCH_STATUS_MESSAGE_FREQUENCY 300 // Frequency of sending a switch status message to the gateway (in seconds).
|
||||
|
||||
#define ZH_GPIO_TASK_PRIORITY 3 // Prioritize the task of GPIO processing.
|
||||
#define ZH_GPIO_TASK_PRIORITY 10 // Prioritize the task of GPIO processing.
|
||||
#define ZH_GPIO_STACK_SIZE 2048 // The stack size of the task of GPIO processing.
|
||||
#define ZH_MESSAGE_TASK_PRIORITY 2 // Prioritize the task of sending messages to the gateway.
|
||||
#define ZH_MESSAGE_TASK_PRIORITY 5 // 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.
|
||||
|
||||
typedef struct // Structure of data exchange between tasks, functions and event handlers.
|
||||
{
|
||||
struct // Storage structure of switch hardware configuration data.
|
||||
{
|
||||
uint8_t relay_pin; // Relay GPIO number.
|
||||
bool relay_on_level; // Relay ON level. @note HIGH (true) / LOW (false).
|
||||
uint8_t led_pin; // Led GPIO number (if present).
|
||||
bool led_on_level; // Led ON level (if present). @note HIGH (true) / LOW (false).
|
||||
uint8_t int_button_pin; // Internal button GPIO number (if present).
|
||||
bool int_button_on_level; // Internal button trigger level (if present). @note HIGH (true) / LOW (false).
|
||||
uint8_t ext_button_pin; // External button GPIO number (if present).
|
||||
bool ext_button_on_level; // External button trigger level (if present). @note HIGH (true) / LOW (false).
|
||||
uint8_t sensor_pin; // Sensor GPIO number (if present).
|
||||
ha_sensor_type_t sensor_type; // Sensor types (if present). @note Used to identify the sensor type by ESP-NOW gateway and send the appropriate sensor status messages to MQTT.
|
||||
uint8_t relay_pin; // Relay GPIO number.
|
||||
bool relay_on_level; // Relay ON level. @note HIGH (true) / LOW (false).
|
||||
uint8_t led_pin; // Led GPIO number (if present).
|
||||
bool led_on_level; // Led ON level (if present). @note HIGH (true) / LOW (false).
|
||||
uint8_t int_button_pin; // Internal button GPIO number (if present).
|
||||
bool int_button_on_level; // Internal button trigger level (if present). @note HIGH (true) / LOW (false).
|
||||
uint8_t ext_button_pin; // External button GPIO number (if present).
|
||||
bool ext_button_on_level; // External button trigger level (if present). @note HIGH (true) / LOW (false).
|
||||
} hardware_config;
|
||||
struct // Storage structure of switch status data.
|
||||
{
|
||||
ha_on_off_type_t status; // Status of the zh_espnow_switch. @note Example - ON / OFF. @attention Must be same with set on switch_config_message structure.
|
||||
ha_on_off_type_t status; // Status of the zh_espnow_switch. @note Example - ON / OFF. @attention Must be same with set on switch_config_message structure (zh_config).
|
||||
} status;
|
||||
volatile bool gpio_processing; // GPIO processing flag. @note Used to prevent a repeated interrupt from triggering during GPIO processing.
|
||||
volatile bool gateway_is_available; // Gateway availability status flag. @note Used to control the tasks when the gateway connection is established / lost.
|
||||
uint8_t gateway_mac[6]; // Gateway MAC address.
|
||||
TaskHandle_t switch_attributes_message_task; // Unique task handle for zh_send_switsh_attributes_message_task().
|
||||
TaskHandle_t switch_keep_alive_message_task; // Unique task handle for zh_send_switch_keep_alive_message_task().
|
||||
TaskHandle_t sensor_attributes_message_task; // Unique task handle for zh_send_sensor_attributes_message_task().
|
||||
TaskHandle_t sensor_status_message_task; // Unique task handle for zh_send_sensor_status_message_task().
|
||||
SemaphoreHandle_t button_pushing_semaphore; // Unique semaphore handle for GPIO processing tasks.
|
||||
const esp_partition_t *update_partition; // Next update partition.
|
||||
esp_ota_handle_t update_handle; // Unique OTA handle.
|
||||
uint16_t ota_message_part_number; // The sequence number of the firmware upgrade part. @note Used to verify that all parts have been received.
|
||||
volatile bool gpio_processing; // GPIO processing flag. @note Used to prevent a repeated interrupt from triggering during GPIO processing.
|
||||
uint8_t gateway_mac[6]; // Gateway MAC address.
|
||||
SemaphoreHandle_t button_pushing_semaphore; // Unique semaphore handle for GPIO processing tasks.
|
||||
const esp_partition_t *update_partition; // Next update partition.
|
||||
esp_ota_handle_t update_handle; // Unique OTA handle.
|
||||
uint16_t ota_message_part_number; // The sequence number of the firmware upgrade part. @note Used to verify that all parts have been received.
|
||||
} switch_config_t;
|
||||
|
||||
/**
|
||||
@ -152,26 +135,33 @@ void zh_gpio_processing_task(void *pvParameter);
|
||||
void zh_send_switch_attributes_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Function for prepare the switch configuration message and sending it to the gateway.
|
||||
* @brief Task for prepare the switch configuration message and sending it to the gateway.
|
||||
*
|
||||
* @param[in] switch_config Pointer to the structure of data exchange between tasks, functions and event handlers.
|
||||
* @param[in] pvParameter Pointer to the structure of data exchange between tasks, functions and event handlers.
|
||||
*/
|
||||
void zh_send_switch_config_message(const switch_config_t *switch_config);
|
||||
void zh_send_switch_config_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Function for prepare the sensor hardware configuration message and sending it to the gateway.
|
||||
* @brief Task for prepare the switch hardware configuration message and sending it to the gateway.
|
||||
*
|
||||
* @param[in] switch_config Pointer to the structure of data exchange between tasks, functions and event handlers.
|
||||
* @param[in] pvParameter Pointer to the structure of data exchange between tasks, functions and event handlers.
|
||||
*/
|
||||
void zh_send_switch_hardware_config_message(const switch_config_t *switch_config);
|
||||
void zh_send_switch_hardware_config_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Task for prepare the sensor keep alive message and sending it to the gateway.
|
||||
* @brief Task for prepare the switch 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_switch_keep_alive_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Task for prepare the switch status 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_switch_status_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Function for prepare the switch status message and sending it to the gateway.
|
||||
*
|
||||
@ -179,27 +169,6 @@ void zh_send_switch_keep_alive_message_task(void *pvParameter);
|
||||
*/
|
||||
void zh_send_switch_status_message(const switch_config_t *switch_config);
|
||||
|
||||
/**
|
||||
* @brief Function for prepare the sensor configuration message and sending it to the gateway.
|
||||
*
|
||||
* @param[in] switch_config Pointer to the structure of data exchange between tasks, functions and event handlers.
|
||||
*/
|
||||
void zh_send_sensor_config_message(const switch_config_t *switch_config);
|
||||
|
||||
/**
|
||||
* @brief Task for prepare the sensor attributes message and sending it to the gateway.
|
||||
*
|
||||
* @param[in] pvParameter Pointer to structure of data exchange between tasks, functions and event handlers.
|
||||
*/
|
||||
void zh_send_sensor_attributes_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Task for prepare the sensor status 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_status_message_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Function for ESP-NOW event processing.
|
||||
*
|
||||
|
7
partitions_esp32c2.csv
Normal file
7
partitions_esp32c2.csv
Normal file
@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, , 900K,
|
||||
ota_1, app, ota_1, , 900K,
|
|
7
partitions_esp32c3.csv
Normal file
7
partitions_esp32c3.csv
Normal file
@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, , 1500K,
|
||||
ota_1, app, ota_1, , 1500K,
|
|
7
partitions_esp32c6.csv
Normal file
7
partitions_esp32c6.csv
Normal file
@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, , 1500K,
|
||||
ota_1, app, ota_1, , 1500K,
|
|
7
partitions_esp32s2.csv
Normal file
7
partitions_esp32s2.csv
Normal file
@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, , 1500K,
|
||||
ota_1, app, ota_1, , 1500K,
|
|
7
partitions_esp32s3.csv
Normal file
7
partitions_esp32s3.csv
Normal file
@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, , 1500K,
|
||||
ota_1, app, ota_1, , 1500K,
|
|
18
sdkconfig.defaults.esp32c2
Normal file
18
sdkconfig.defaults.esp32c2
Normal file
@ -0,0 +1,18 @@
|
||||
CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=0
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_esp32c2.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_esp32c2.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=0
|
18
sdkconfig.defaults.esp32c3
Normal file
18
sdkconfig.defaults.esp32c3
Normal file
@ -0,0 +1,18 @@
|
||||
CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=0
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_esp32c3.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_esp32c3.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=0
|
18
sdkconfig.defaults.esp32c6
Normal file
18
sdkconfig.defaults.esp32c6
Normal file
@ -0,0 +1,18 @@
|
||||
CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=0
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_esp32c6.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_esp32c6.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=0
|
18
sdkconfig.defaults.esp32s2
Normal file
18
sdkconfig.defaults.esp32s2
Normal file
@ -0,0 +1,18 @@
|
||||
CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=0
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_esp32s2.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_esp32s2.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=0
|
18
sdkconfig.defaults.esp32s3
Normal file
18
sdkconfig.defaults.esp32s3
Normal file
@ -0,0 +1,18 @@
|
||||
CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=0
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_esp32s3.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_esp32s3.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=0
|
@ -1 +1 @@
|
||||
1.0.2
|
||||
2.1.0
|
Reference in New Issue
Block a user