# esp_component_template esp_component_template ```c #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "esp_event.h" #include "zh_nrf24_gateway.h" // #include "zh_nrf24_config.h" static const char *TAG = "MAIN"; #define GW_CHANNEL 120 #define GW_ADDRESS 0xDDEEFF static const zh_nrf_gateway_config_t s_gw_config = { .spi_host = SPI2_HOST, .pin_sck = 18, .pin_miso = 19, .pin_mosi = 23, .pin_csn = 17, .pin_ce = 16, .pin_irq = 4, .channel = GW_CHANNEL, .address = GW_ADDRESS, .spi_clock_hz = 0, }; static void dump_bindings(const char *reason) { zh_nrf_gateway_binding_t tmp[ZH_NRF_GATEWAY_MAX_BINDINGS]; size_t got = zh_nrf_gateway_bindings_get(tmp, ZH_NRF_GATEWAY_MAX_BINDINGS); ESP_LOGI(TAG, "=== Bindings (%s): %u total ===", reason, (unsigned)got); for (size_t i = 0; i < got; i++) { ESP_LOGI(TAG, " [%u] id=%u type=%u (%s)", (unsigned)i, tmp[i].id, tmp[i].type, zh_get_nrf24_sensor_type_name((zh_nrf24_sensor_type_t)tmp[i].type)); } } static void gateway_event_handler(void *arg, esp_event_base_t base, int32_t id, void *event_data) { if (base != ZH_NRF_GATEWAY_EVENTS) return; switch (id) { case ZH_NRF_GATEWAY_EVENT_SENSOR_DATA: { const zh_nrf24_sensor_transmitted_data_t *d = event_data; const char *name = zh_get_nrf24_sensor_type_name((zh_nrf24_sensor_type_t)d->type); ESP_LOGI(TAG, "<<< sensor id=%d type=%s battery=%.2fV", d->id, name, d->battery / 100.0); switch (d->type) { case ZH_NRF24_SENSOR_TOUCH_SWITCH: ESP_LOGI(TAG, " button event"); break; case ZH_NRF24_SENSOR_WATER_LEAKAGE: ESP_LOGI(TAG, " status=%s", d->value_1 == ZH_NRF24_SENSOR_STATUS_ALARM ? "ALARM" : "DRY"); break; case ZH_NRF24_SENSOR_OPEN_CLOSE: ESP_LOGI(TAG, " state=%s", d->value_1 == ZH_NRF24_SENSOR_STATUS_OPEN ? "OPEN" : "CLOSE"); break; case ZH_NRF24_SENSOR_PLANT_HUMIDITY: ESP_LOGI(TAG, " humidity=%d%%", d->value_1); break; case ZH_NRF24_SENSOR_BMP280: ESP_LOGI(TAG, " T=%d C, P=%d", d->value_1, d->value_2); break; case ZH_NRF24_SENSOR_BME280: ESP_LOGI(TAG, " H=%d%% T=%d C P=%d mmHg", d->value_1, d->value_2, d->value_3); break; case ZH_NRF24_SENSOR_BME680: ESP_LOGI(TAG, " H=%d%% T=%d C P=%d Q=%d", d->value_1, d->value_2, d->value_3, d->value_4); break; default: break; } break; } default: break; } } /* Пример: удаление одной привязки (из MQTT, кнопки, HTTP и т.п.) */ static void demo_manual_delete(void) { uint8_t id = 5; uint8_t type = ZH_NRF24_SENSOR_BME280; if (zh_nrf_gateway_binding_exists(id, type)) { ESP_LOGI(TAG, "Binding {id=%u, type=%u} exists, deleting", id, type); esp_err_t err = zh_nrf_gateway_binding_delete(id, type); ESP_LOGI(TAG, "delete → %s", esp_err_to_name(err)); } else { ESP_LOGW(TAG, "Binding {id=%u, type=%u} not found, nothing to do", id, type); } } void app_main(void) { ESP_LOGI(TAG, "Starting nRF24L01+ gateway"); ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_event_handler_instance_register( ZH_NRF_GATEWAY_EVENTS, ESP_EVENT_ANY_ID, &gateway_event_handler, NULL, NULL)); ESP_ERROR_CHECK(zh_nrf_gateway_init(&s_gw_config)); dump_bindings("after init"); ESP_ERROR_CHECK(zh_nrf_gateway_start()); ESP_LOGI(TAG, "Gateway running: channel=%d, address=0x%06X", GW_CHANNEL, GW_ADDRESS); /* Здесь можно, например, ждать команд по MQTT/HTTP и вызывать: * * zh_nrf_gateway_binding_delete(id, type) — точное удаление * zh_nrf_gateway_bindings_delete_by_id(id) — всё с этим id * zh_nrf_gateway_bindings_delete_by_type(type) — всё этого типа * zh_nrf_gateway_binding_clear_all() — полный сброс * zh_nrf_gateway_binding_exists(id, type) — проверка * zh_nrf_gateway_bindings_get(...) / _count() — чтение * * После удаления id сразу доступен для следующего pairing-запроса * того же типа. */ } ```