Merge branch 'master' into release/v3.3.x
This commit is contained in:
commit
4c51968acf
10 changed files with 166 additions and 15 deletions
|
|
@ -432,6 +432,11 @@ void PPPClass::end(void) {
|
|||
_pin_cts = -1;
|
||||
perimanClearPinBus(pin);
|
||||
}
|
||||
if (_pin_rst != -1) {
|
||||
pin = _pin_rst;
|
||||
_pin_rst = -1;
|
||||
perimanClearPinBus(pin);
|
||||
}
|
||||
|
||||
_mode = ESP_MODEM_MODE_COMMAND;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,18 +32,49 @@
|
|||
|
||||
#include "Zigbee.h"
|
||||
|
||||
#define USE_GLOBAL_ON_RESPONSE_CALLBACK 1 // Set to 0 to use local callback specified directly for the endpoint.
|
||||
|
||||
/* Zigbee temperature + humidity sensor configuration */
|
||||
#define TEMP_SENSOR_ENDPOINT_NUMBER 10
|
||||
|
||||
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
|
||||
#define TIME_TO_SLEEP 55 /* Sleep for 55s will + 5s delay for establishing connection => data reported every 1 minute */
|
||||
#define REPORT_TIMEOUT 1000 /* Timeout for response from coordinator in ms */
|
||||
|
||||
uint8_t button = BOOT_PIN;
|
||||
|
||||
ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
|
||||
|
||||
uint8_t dataToSend = 2; // Temperature and humidity values are reported in same endpoint, so 2 values are reported
|
||||
bool resend = false;
|
||||
|
||||
/************************ Callbacks *****************************/
|
||||
#if USE_GLOBAL_ON_RESPONSE_CALLBACK
|
||||
void onGlobalResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster) {
|
||||
Serial.printf("Global response command: %d, status: %s, endpoint: %d, cluster: 0x%04x\r\n", command, esp_zb_zcl_status_to_name(status), endpoint, cluster);
|
||||
if ((command == ZB_CMD_REPORT_ATTRIBUTE) && (endpoint == TEMP_SENSOR_ENDPOINT_NUMBER)) {
|
||||
switch (status) {
|
||||
case ESP_ZB_ZCL_STATUS_SUCCESS: dataToSend--; break;
|
||||
case ESP_ZB_ZCL_STATUS_FAIL: resend = true; break;
|
||||
default: break; // add more statuses like ESP_ZB_ZCL_STATUS_INVALID_VALUE, ESP_ZB_ZCL_STATUS_TIMEOUT etc.
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void onResponse(zb_cmd_type_t command, esp_zb_zcl_status_t status) {
|
||||
Serial.printf("Response command: %d, status: %s\r\n", command, esp_zb_zcl_status_to_name(status));
|
||||
if (command == ZB_CMD_REPORT_ATTRIBUTE) {
|
||||
switch (status) {
|
||||
case ESP_ZB_ZCL_STATUS_SUCCESS: dataToSend--; break;
|
||||
case ESP_ZB_ZCL_STATUS_FAIL: resend = true; break;
|
||||
default: break; // add more statuses like ESP_ZB_ZCL_STATUS_INVALID_VALUE, ESP_ZB_ZCL_STATUS_TIMEOUT etc.
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************ Temp sensor *****************************/
|
||||
void meausureAndSleep() {
|
||||
static void meausureAndSleep(void *arg) {
|
||||
// Measure temperature sensor value
|
||||
float temperature = temperatureRead();
|
||||
|
||||
|
|
@ -55,13 +86,35 @@ void meausureAndSleep() {
|
|||
zbTempSensor.setHumidity(humidity);
|
||||
|
||||
// Report temperature and humidity values
|
||||
zbTempSensor.report();
|
||||
zbTempSensor.report(); // reports temperature and humidity values (if humidity sensor is not added, only temperature is reported)
|
||||
Serial.printf("Reported temperature: %.2f°C, Humidity: %.2f%%\r\n", temperature, humidity);
|
||||
|
||||
// Add small delay to allow the data to be sent before going to sleep
|
||||
delay(100);
|
||||
unsigned long startTime = millis();
|
||||
const unsigned long timeout = REPORT_TIMEOUT;
|
||||
|
||||
// Put device to deep sleep
|
||||
Serial.printf("Waiting for data report to be confirmed \r\n");
|
||||
// Wait until data was successfully sent
|
||||
int tries = 0;
|
||||
const int maxTries = 3;
|
||||
while (dataToSend != 0 && tries < maxTries) {
|
||||
if (resend) {
|
||||
Serial.println("Resending data on failure!");
|
||||
resend = false;
|
||||
dataToSend = 2;
|
||||
zbTempSensor.report(); // report again
|
||||
}
|
||||
if (millis() - startTime >= timeout) {
|
||||
Serial.println("\nReport timeout! Report Again");
|
||||
dataToSend = 2;
|
||||
zbTempSensor.report(); // report again
|
||||
startTime = millis();
|
||||
tries++;
|
||||
}
|
||||
Serial.printf(".");
|
||||
delay(50); // 50ms delay to avoid busy-waiting
|
||||
}
|
||||
|
||||
// Put device to deep sleep after data was sent successfully or timeout
|
||||
Serial.println("Going to sleep now");
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
|
@ -92,6 +145,16 @@ void setup() {
|
|||
// Add humidity cluster to the temperature sensor device with min, max and tolerance values
|
||||
zbTempSensor.addHumiditySensor(0, 100, 1);
|
||||
|
||||
// Set callback for default response to handle status of reported data, there are 2 options.
|
||||
|
||||
#if USE_GLOBAL_ON_RESPONSE_CALLBACK
|
||||
// Global callback for all endpoints with more params to determine the endpoint and cluster in the callback function.
|
||||
Zigbee.onGlobalDefaultResponse(onGlobalResponse);
|
||||
#else
|
||||
// Callback specified for endpoint
|
||||
zbTempSensor.onDefaultResponse(onResponse);
|
||||
#endif
|
||||
|
||||
// Add endpoint to Zigbee Core
|
||||
Zigbee.addEndpoint(&zbTempSensor);
|
||||
|
||||
|
|
@ -117,8 +180,8 @@ void setup() {
|
|||
Serial.println();
|
||||
Serial.println("Successfully connected to Zigbee network");
|
||||
|
||||
// Delay approx 1s (may be adjusted) to allow establishing proper connection with coordinator, needed for sleepy devices
|
||||
delay(1000);
|
||||
// Start Temperature sensor reading task
|
||||
xTaskCreate(meausureAndSleep, "temp_sensor_update", 2048, NULL, 10, NULL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
|
@ -141,7 +204,5 @@ void loop() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function to measure temperature and put the device to sleep
|
||||
meausureAndSleep();
|
||||
delay(100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ zb_power_source_t KEYWORD1
|
|||
ZigbeeWindowCoveringType KEYWORD1
|
||||
ZigbeeFanMode KEYWORD1
|
||||
ZigbeeFanModeSequence KEYWORD1
|
||||
zb_cmd_type_t KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
|
|
@ -96,6 +97,7 @@ getTime KEYWORD2
|
|||
getTimezone KEYWORD2
|
||||
addOTAClient KEYWORD2
|
||||
clearBoundDevices KEYWORD2
|
||||
onDefaultResponse KEYWORD2
|
||||
|
||||
# ZigbeeLight + ZigbeeColorDimmableLight
|
||||
onLightChange KEYWORD2
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Common types and functions
|
||||
#include "ZigbeeTypes.h"
|
||||
|
||||
// Core
|
||||
#include "ZigbeeCore.h"
|
||||
#include "ZigbeeEP.h"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ ZigbeeCore::ZigbeeCore() {
|
|||
_scan_duration = 3; // default scan duration
|
||||
_rx_on_when_idle = true;
|
||||
_debug = false;
|
||||
_global_default_response_cb = nullptr; // Initialize global callback to nullptr
|
||||
if (!lock) {
|
||||
lock = xSemaphoreCreateBinary();
|
||||
if (lock == NULL) {
|
||||
|
|
@ -237,7 +238,9 @@ void ZigbeeCore::closeNetwork() {
|
|||
}
|
||||
|
||||
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) {
|
||||
ESP_ERROR_CHECK(esp_zb_bdb_start_top_level_commissioning(mode_mask));
|
||||
if (esp_zb_bdb_start_top_level_commissioning(mode_mask) != ESP_OK) {
|
||||
log_e("Failed to start Zigbee commissioning");
|
||||
}
|
||||
}
|
||||
|
||||
void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
|
||||
|
|
@ -792,6 +795,12 @@ const char *ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceI
|
|||
}
|
||||
}
|
||||
|
||||
void ZigbeeCore::callDefaultResponseCallback(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster) {
|
||||
if (_global_default_response_cb) {
|
||||
_global_default_response_cb(resp_to_cmd, status, endpoint, cluster);
|
||||
}
|
||||
}
|
||||
|
||||
ZigbeeCore Zigbee = ZigbeeCore();
|
||||
|
||||
#endif // CONFIG_ZB_ENABLED
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "aps/esp_zigbee_aps.h"
|
||||
#include <esp32-hal-log.h>
|
||||
#include <list>
|
||||
#include "ZigbeeTypes.h"
|
||||
#include "ZigbeeEP.h"
|
||||
class ZigbeeEP;
|
||||
|
||||
|
|
@ -103,6 +104,9 @@ private:
|
|||
SemaphoreHandle_t lock;
|
||||
bool _debug;
|
||||
|
||||
// Global default response callback
|
||||
void (*_global_default_response_cb)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster);
|
||||
|
||||
bool zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs);
|
||||
static void scanCompleteCallback(esp_zb_zdp_status_t zdo_status, uint8_t count, esp_zb_network_descriptor_t *nwk_descriptor);
|
||||
const char *getDeviceTypeString(esp_zb_ha_standard_devices_t deviceId);
|
||||
|
|
@ -176,6 +180,14 @@ public:
|
|||
return _debug;
|
||||
}
|
||||
|
||||
// Set global default response callback
|
||||
void onGlobalDefaultResponse(void (*callback)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster)) {
|
||||
_global_default_response_cb = callback;
|
||||
}
|
||||
|
||||
// Call global default response callback (for internal use)
|
||||
void callDefaultResponseCallback(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status, uint8_t endpoint, uint16_t cluster);
|
||||
|
||||
// Friend function declaration to allow access to private members
|
||||
friend void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct);
|
||||
friend bool zb_apsde_data_indication_handler(esp_zb_apsde_data_ind_t ind);
|
||||
|
|
|
|||
|
|
@ -608,7 +608,17 @@ void ZigbeeEP::removeBoundDevice(zb_device_params_t *device) {
|
|||
log_w("No matching device found for removal");
|
||||
}
|
||||
|
||||
const char *ZigbeeEP::esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status) {
|
||||
void ZigbeeEP::zbDefaultResponse(const esp_zb_zcl_cmd_default_resp_message_t *message) {
|
||||
log_v("Default response received for endpoint %d", _endpoint);
|
||||
log_v("Status code: %s", esp_zb_zcl_status_to_name(message->status_code));
|
||||
log_v("Response to command: %d", message->resp_to_cmd);
|
||||
if (_on_default_response) {
|
||||
_on_default_response((zb_cmd_type_t)message->resp_to_cmd, message->status_code);
|
||||
}
|
||||
}
|
||||
|
||||
// Global function implementation
|
||||
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status) {
|
||||
switch (status) {
|
||||
case ESP_ZB_ZCL_STATUS_SUCCESS: return "Success";
|
||||
case ESP_ZB_ZCL_STATUS_FAIL: return "Fail";
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ typedef enum {
|
|||
ZB_POWER_SOURCE_BATTERY = 0x03,
|
||||
} zb_power_source_t;
|
||||
|
||||
// Global function for converting ZCL status to name
|
||||
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
|
||||
|
||||
/* Zigbee End Device Class */
|
||||
class ZigbeeEP {
|
||||
public:
|
||||
|
|
@ -138,6 +141,7 @@ public:
|
|||
virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented
|
||||
virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {};
|
||||
virtual void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {};
|
||||
virtual void zbDefaultResponse(const esp_zb_zcl_cmd_default_resp_message_t *message); //already implemented
|
||||
|
||||
virtual void addBoundDevice(zb_device_params_t *device) {
|
||||
_bound_devices.push_back(device);
|
||||
|
|
@ -156,17 +160,21 @@ public:
|
|||
_on_identify = callback;
|
||||
}
|
||||
|
||||
void onDefaultResponse(void (*callback)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status)) {
|
||||
_on_default_response = callback;
|
||||
}
|
||||
|
||||
// Convert ZCL status to name
|
||||
|
||||
private:
|
||||
char *_read_manufacturer;
|
||||
char *_read_model;
|
||||
void (*_on_identify)(uint16_t time);
|
||||
void (*_on_default_response)(zb_cmd_type_t resp_to_cmd, esp_zb_zcl_status_t status);
|
||||
time_t _read_time;
|
||||
int32_t _read_timezone;
|
||||
|
||||
protected:
|
||||
// Convert ZCL status to name
|
||||
const char *esp_zb_zcl_status_to_name(esp_zb_zcl_status_t status);
|
||||
|
||||
uint8_t _endpoint;
|
||||
esp_zb_ha_standard_devices_t _device_id;
|
||||
esp_zb_endpoint_config_t _ep_config;
|
||||
|
|
@ -179,6 +187,7 @@ protected:
|
|||
zb_power_source_t _power_source;
|
||||
uint8_t _time_status;
|
||||
|
||||
// Friend class declaration to allow access to protected members
|
||||
friend class ZigbeeCore;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -398,6 +398,16 @@ static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_m
|
|||
"Received default response: from address(0x%x), src_endpoint(%d) to dst_endpoint(%d), cluster(0x%x) with status 0x%x",
|
||||
message->info.src_address.u.short_addr, message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code
|
||||
);
|
||||
|
||||
// Call global callback if set
|
||||
Zigbee.callDefaultResponseCallback((zb_cmd_type_t)message->resp_to_cmd, message->status_code, message->info.dst_endpoint, message->info.cluster);
|
||||
|
||||
// List through all Zigbee EPs and call the callback function, with the message
|
||||
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
|
||||
if (message->info.dst_endpoint == (*it)->getEndpoint()) {
|
||||
(*it)->zbDefaultResponse(message); //method zbDefaultResponse is implemented in the common EP class
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
30
libraries/Zigbee/src/ZigbeeTypes.h
Normal file
30
libraries/Zigbee/src/ZigbeeTypes.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "esp_zigbee_core.h"
|
||||
|
||||
// Foundation Command Types
|
||||
typedef enum {
|
||||
ZB_CMD_READ_ATTRIBUTE = 0x00U, /*!< Read attributes command */
|
||||
ZB_CMD_READ_ATTRIBUTE_RESPONSE = 0x01U, /*!< Read attributes response command */
|
||||
ZB_CMD_WRITE_ATTRIBUTE = 0x02U, /*!< Write attributes foundation command */
|
||||
ZB_CMD_WRITE_ATTRIBUTE_UNDIVIDED = 0x03U, /*!< Write attributes undivided command */
|
||||
ZB_CMD_WRITE_ATTRIBUTE_RESPONSE = 0x04U, /*!< Write attributes response command */
|
||||
ZB_CMD_WRITE_ATTRIBUTE_NO_RESPONSE = 0x05U, /*!< Write attributes no response command */
|
||||
ZB_CMD_CONFIGURE_REPORTING = 0x06U, /*!< Configure reporting command */
|
||||
ZB_CMD_CONFIGURE_REPORTING_RESPONSE = 0x07U, /*!< Configure reporting response command */
|
||||
ZB_CMD_READ_REPORTING_CONFIG = 0x08U, /*!< Read reporting config command */
|
||||
ZB_CMD_READ_REPORTING_CONFIG_RESPONSE = 0x09U, /*!< Read reporting config response command */
|
||||
ZB_CMD_REPORT_ATTRIBUTE = 0x0aU, /*!< Report attribute command */
|
||||
ZB_CMD_DEFAULT_RESPONSE = 0x0bU, /*!< Default response command */
|
||||
ZB_CMD_DISCOVER_ATTRIBUTES = 0x0cU, /*!< Discover attributes command */
|
||||
ZB_CMD_DISCOVER_ATTRIBUTES_RESPONSE = 0x0dU, /*!< Discover attributes response command */
|
||||
ZB_CMD_READ_ATTRIBUTE_STRUCTURED = 0x0eU, /*!< Read attributes structured */
|
||||
ZB_CMD_WRITE_ATTRIBUTE_STRUCTURED = 0x0fU, /*!< Write attributes structured */
|
||||
ZB_CMD_WRITE_ATTRIBUTE_STRUCTURED_RESPONSE = 0x10U, /*!< Write attributes structured response */
|
||||
ZB_CMD_DISCOVER_COMMANDS_RECEIVED = 0x11U, /*!< Discover Commands Received command */
|
||||
ZB_CMD_DISCOVER_COMMANDS_RECEIVED_RESPONSE = 0x12U, /*!< Discover Commands Received response command */
|
||||
ZB_CMD_DISCOVER_COMMANDS_GENERATED = 0x13U, /*!< Discover Commands Generated command */
|
||||
ZB_CMD_DISCOVER_COMMANDS_GENERATED_RESPONSE = 0x14U, /*!< Discover Commands Generated response command */
|
||||
ZB_CMD_DISCOVER_ATTRIBUTES_EXTENDED = 0x15U, /*!< Discover attributes extended command */
|
||||
ZB_CMD_DISCOVER_ATTRIBUTES_EXTENDED_RESPONSE = 0x16U, /*!< Discover attributes extended response command */
|
||||
} zb_cmd_type_t;
|
||||
Loading…
Reference in a new issue