feat(zigbee): Add vibration sensor endpoint (#10944)
This commit is contained in:
parent
83abca1604
commit
7f8c77f9ee
7 changed files with 320 additions and 0 deletions
|
|
@ -293,6 +293,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS
|
||||||
libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp
|
libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp
|
||||||
libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
|
libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
|
||||||
libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp
|
libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp
|
||||||
|
libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ARDUINO_LIBRARY_BLE_SRCS
|
set(ARDUINO_LIBRARY_BLE_SRCS
|
||||||
|
|
|
||||||
58
libraries/Zigbee/examples/Zigbee_Vibration_Sensor/README.md
Normal file
58
libraries/Zigbee/examples/Zigbee_Vibration_Sensor/README.md
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Arduino-ESP32 Zigbee Vibration Sensor Example
|
||||||
|
|
||||||
|
This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) vibration sensor (IAS Zone),
|
||||||
|
that can be used for example as a security device which is sensing a vibrations.
|
||||||
|
|
||||||
|
# Supported Targets
|
||||||
|
|
||||||
|
Currently, this example supports the following targets.
|
||||||
|
|
||||||
|
| Supported Targets | ESP32-C6 | ESP32-H2 |
|
||||||
|
| ----------------- | -------- | -------- |
|
||||||
|
|
||||||
|
## Hardware Required
|
||||||
|
|
||||||
|
* A USB cable for power supply and programming
|
||||||
|
|
||||||
|
### Configure the Project
|
||||||
|
|
||||||
|
Set the Button GPIO by changing the `button` variable. By default, it's the pin `BOOT_PIN` (BOOT button on ESP32-C6 and ESP32-H2).
|
||||||
|
Set the Sensor GPIO by changing the `sensor_pin` variable.
|
||||||
|
|
||||||
|
#### Using Arduino IDE
|
||||||
|
|
||||||
|
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
|
||||||
|
|
||||||
|
* Before Compile/Verify, select the correct board: `Tools -> Board`.
|
||||||
|
* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)`
|
||||||
|
* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs`
|
||||||
|
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
|
||||||
|
* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board.
|
||||||
|
|
||||||
|
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source***
|
||||||
|
|
||||||
|
* **LED not blinking:** Check the wiring connection and the IO selection.
|
||||||
|
* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed.
|
||||||
|
* **COM port not detected:** Check the USB cable and the USB to Serial driver installation.
|
||||||
|
|
||||||
|
If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute).
|
||||||
|
|
||||||
|
## Contribute
|
||||||
|
|
||||||
|
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
|
||||||
|
|
||||||
|
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
|
||||||
|
|
||||||
|
Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
* Official ESP32 Forum: [Link](https://esp32.com)
|
||||||
|
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
|
||||||
|
* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf)
|
||||||
|
* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf)
|
||||||
|
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This example demonstrates Zigbee vibration sensor (IAS Zone).
|
||||||
|
*
|
||||||
|
* The example demonstrates how to use Zigbee library to create a end device vibration sensor.
|
||||||
|
* The vibration sensor is a Zigbee end device, which is reporting data to the Zigbee network.
|
||||||
|
*
|
||||||
|
* Proper Zigbee mode must be selected in Tools->Zigbee mode
|
||||||
|
* and also the correct partition scheme must be selected in Tools->Partition Scheme.
|
||||||
|
*
|
||||||
|
* Please check the README.md for instructions and more detailed description.
|
||||||
|
*
|
||||||
|
* Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZIGBEE_MODE_ED
|
||||||
|
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Zigbee.h"
|
||||||
|
|
||||||
|
/* Zigbee vibration sensor configuration */
|
||||||
|
#define VIBRATION_SENSOR_ENDPOINT_NUMBER 10
|
||||||
|
uint8_t button = BOOT_PIN;
|
||||||
|
uint8_t sensor_pin = 4;
|
||||||
|
|
||||||
|
ZigbeeVibrationSensor zbVibrationSensor = ZigbeeVibrationSensor(VIBRATION_SENSOR_ENDPOINT_NUMBER);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
// Init button + sensor
|
||||||
|
pinMode(button, INPUT_PULLUP);
|
||||||
|
pinMode(sensor_pin, INPUT);
|
||||||
|
|
||||||
|
// Optional: set Zigbee device name and model
|
||||||
|
zbVibrationSensor.setManufacturerAndModel("Espressif", "ZigbeeVibrationSensor");
|
||||||
|
|
||||||
|
// Add endpoint to Zigbee Core
|
||||||
|
Zigbee.addEndpoint(&zbVibrationSensor);
|
||||||
|
|
||||||
|
Serial.println("Starting Zigbee...");
|
||||||
|
// When all EPs are registered, start Zigbee in End Device mode
|
||||||
|
if (!Zigbee.begin()) {
|
||||||
|
Serial.println("Zigbee failed to start!");
|
||||||
|
Serial.println("Rebooting...");
|
||||||
|
ESP.restart();
|
||||||
|
} else {
|
||||||
|
Serial.println("Zigbee started successfully!");
|
||||||
|
}
|
||||||
|
Serial.println("Connecting to network");
|
||||||
|
while (!Zigbee.connected()) {
|
||||||
|
Serial.print(".");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Checking pin for contact change
|
||||||
|
static bool sensed = false;
|
||||||
|
if (digitalRead(sensor_pin) == HIGH && !sensed) {
|
||||||
|
// Update contact sensor value
|
||||||
|
zbVibrationSensor.setVibration(true);
|
||||||
|
sensed = true;
|
||||||
|
//if sensed, wait 2 seconds before next sensing
|
||||||
|
delay(2000);
|
||||||
|
} else if (digitalRead(sensor_pin) == LOW && sensed) {
|
||||||
|
zbVibrationSensor.setVibration(false);
|
||||||
|
sensed = false;
|
||||||
|
//if not sensed, wait 0,5 seconds before next sensing
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checking button for factory reset
|
||||||
|
if (digitalRead(button) == LOW) { // Push button pressed
|
||||||
|
// Key debounce handling
|
||||||
|
delay(100);
|
||||||
|
int startTime = millis();
|
||||||
|
while (digitalRead(button) == LOW) {
|
||||||
|
delay(50);
|
||||||
|
if ((millis() - startTime) > 3000) {
|
||||||
|
// If key pressed for more than 3secs, factory reset Zigbee and reboot
|
||||||
|
Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
|
||||||
|
delay(1000);
|
||||||
|
Zigbee.factoryReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed",
|
||||||
|
"requires": [
|
||||||
|
"CONFIG_SOC_IEEE802154_SUPPORTED=y"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -21,3 +21,4 @@
|
||||||
#include "ep/ZigbeeContactSwitch.h"
|
#include "ep/ZigbeeContactSwitch.h"
|
||||||
#include "ep/ZigbeeDoorWindowHandle.h"
|
#include "ep/ZigbeeDoorWindowHandle.h"
|
||||||
#include "ep/ZigbeeWindowCovering.h"
|
#include "ep/ZigbeeWindowCovering.h"
|
||||||
|
#include "ep/ZigbeeVibrationSensor.h"
|
||||||
|
|
|
||||||
86
libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
Normal file
86
libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include "ZigbeeVibrationSensor.h"
|
||||||
|
#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
|
||||||
|
|
||||||
|
esp_zb_cluster_list_t *zigbee_vibration_sensor_clusters_create(zigbee_vibration_sensor_cfg_t *vibration_sensor) {
|
||||||
|
esp_zb_basic_cluster_cfg_t *basic_cfg = vibration_sensor ? &(vibration_sensor->basic_cfg) : NULL;
|
||||||
|
esp_zb_identify_cluster_cfg_t *identify_cfg = vibration_sensor ? &(vibration_sensor->identify_cfg) : NULL;
|
||||||
|
esp_zb_ias_zone_cluster_cfg_t *ias_zone_cfg = vibration_sensor ? &(vibration_sensor->ias_zone_cfg) : NULL;
|
||||||
|
esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
|
||||||
|
esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
|
esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
|
esp_zb_cluster_list_add_ias_zone_cluster(cluster_list, esp_zb_ias_zone_cluster_create(ias_zone_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
|
return cluster_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeVibrationSensor::ZigbeeVibrationSensor(uint8_t endpoint) : ZigbeeEP(endpoint) {
|
||||||
|
_device_id = ESP_ZB_HA_IAS_ZONE_ID;
|
||||||
|
_zone_status = 0;
|
||||||
|
_zone_id = 0xff;
|
||||||
|
_ias_cie_endpoint = 1;
|
||||||
|
|
||||||
|
//Create custom vibration sensor configuration
|
||||||
|
zigbee_vibration_sensor_cfg_t vibration_sensor_cfg = ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG();
|
||||||
|
_cluster_list = zigbee_vibration_sensor_clusters_create(&vibration_sensor_cfg);
|
||||||
|
|
||||||
|
_ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_IAS_ZONE_ID, .app_device_version = 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeVibrationSensor::setIASClientEndpoint(uint8_t ep_number) {
|
||||||
|
_ias_cie_endpoint = ep_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeVibrationSensor::setVibration(bool sensed) {
|
||||||
|
log_v("Setting Vibration sensor to %s", sensed ? "sensed" : "not sensed");
|
||||||
|
uint8_t vibration = (uint8_t)sensed;
|
||||||
|
esp_zb_lock_acquire(portMAX_DELAY);
|
||||||
|
esp_zb_zcl_set_attribute_val(
|
||||||
|
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &vibration, false
|
||||||
|
);
|
||||||
|
esp_zb_lock_release();
|
||||||
|
_zone_status = vibration;
|
||||||
|
report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeVibrationSensor::report() {
|
||||||
|
/* Send IAS Zone status changed notification command */
|
||||||
|
|
||||||
|
esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd;
|
||||||
|
status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
|
||||||
|
status_change_notif_cmd.zcl_basic_cmd.src_endpoint = _endpoint;
|
||||||
|
status_change_notif_cmd.zcl_basic_cmd.dst_endpoint = _ias_cie_endpoint; //default is 1
|
||||||
|
memcpy(status_change_notif_cmd.zcl_basic_cmd.dst_addr_u.addr_long, _ias_cie_addr, sizeof(esp_zb_ieee_addr_t));
|
||||||
|
|
||||||
|
status_change_notif_cmd.zone_status = _zone_status;
|
||||||
|
status_change_notif_cmd.extend_status = 0;
|
||||||
|
status_change_notif_cmd.zone_id = _zone_id;
|
||||||
|
status_change_notif_cmd.delay = 0;
|
||||||
|
|
||||||
|
esp_zb_lock_acquire(portMAX_DELAY);
|
||||||
|
esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd);
|
||||||
|
esp_zb_lock_release();
|
||||||
|
log_v("IAS Zone status changed notification sent");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {
|
||||||
|
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) {
|
||||||
|
log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code);
|
||||||
|
if (message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) {
|
||||||
|
log_v("IAS Zone Enroll Response: success");
|
||||||
|
esp_zb_lock_acquire(portMAX_DELAY);
|
||||||
|
memcpy(
|
||||||
|
_ias_cie_addr,
|
||||||
|
(*(esp_zb_ieee_addr_t *)
|
||||||
|
esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID)
|
||||||
|
->data_p),
|
||||||
|
sizeof(esp_zb_ieee_addr_t)
|
||||||
|
);
|
||||||
|
esp_zb_lock_release();
|
||||||
|
_zone_id = message->zone_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
|
||||||
64
libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h
Normal file
64
libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* Class of Zigbee contact switch (IAS Zone) endpoint inherited from common EP class */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
|
||||||
|
|
||||||
|
#include "ZigbeeEP.h"
|
||||||
|
#include "ha/esp_zigbee_ha_standard.h"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#define ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.basic_cfg = \
|
||||||
|
{ \
|
||||||
|
.zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \
|
||||||
|
.power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \
|
||||||
|
}, \
|
||||||
|
.identify_cfg = \
|
||||||
|
{ \
|
||||||
|
.identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \
|
||||||
|
}, \
|
||||||
|
.ias_zone_cfg = \
|
||||||
|
{ \
|
||||||
|
.zone_state = ESP_ZB_ZCL_IAS_ZONE_ZONESTATE_NOT_ENROLLED, \
|
||||||
|
.zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT, \
|
||||||
|
.zone_status = 0, \
|
||||||
|
.ias_cie_addr = ESP_ZB_ZCL_ZONE_IAS_CIE_ADDR_DEFAULT, \
|
||||||
|
.zone_id = 0xff, \
|
||||||
|
.zone_ctx = {0, 0, 0, 0}, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
typedef struct zigbee_vibration_sensor_cfg_s {
|
||||||
|
esp_zb_basic_cluster_cfg_t basic_cfg;
|
||||||
|
esp_zb_identify_cluster_cfg_t identify_cfg;
|
||||||
|
esp_zb_ias_zone_cluster_cfg_t ias_zone_cfg;
|
||||||
|
} zigbee_vibration_sensor_cfg_t;
|
||||||
|
|
||||||
|
class ZigbeeVibrationSensor : public ZigbeeEP {
|
||||||
|
public:
|
||||||
|
ZigbeeVibrationSensor(uint8_t endpoint);
|
||||||
|
~ZigbeeVibrationSensor() {}
|
||||||
|
|
||||||
|
// Set the IAS Client endpoint number (default is 1)
|
||||||
|
void setIASClientEndpoint(uint8_t ep_number);
|
||||||
|
|
||||||
|
// Set the vibration sensor value (true = sensed, false = not sensed)
|
||||||
|
void setVibration(bool sensed);
|
||||||
|
|
||||||
|
// Report the vibration sensor value, done automatically after setting the sensed value
|
||||||
|
void report();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override;
|
||||||
|
uint8_t _zone_status;
|
||||||
|
uint8_t _zone_id;
|
||||||
|
esp_zb_ieee_addr_t _ias_cie_addr;
|
||||||
|
uint8_t _ias_cie_endpoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
|
||||||
Loading…
Reference in a new issue