Update the ibeacon code (#3859)

This commit is contained in:
Frank Riley 2022-10-12 16:59:07 -07:00 committed by GitHub
parent 71387be72e
commit 5ec1588110
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 17 deletions

View file

@ -1,7 +1,7 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_TYPE, CONF_UUID from esphome.const import CONF_ID, CONF_TYPE, CONF_UUID, CONF_TX_POWER
from esphome.core import CORE from esphome.core import CORE, TimePeriod
from esphome.components.esp32 import add_idf_sdkconfig_option from esphome.components.esp32 import add_idf_sdkconfig_option
DEPENDENCIES = ["esp32"] DEPENDENCIES = ["esp32"]
@ -12,16 +12,47 @@ ESP32BLEBeacon = esp32_ble_beacon_ns.class_("ESP32BLEBeacon", cg.Component)
CONF_MAJOR = "major" CONF_MAJOR = "major"
CONF_MINOR = "minor" CONF_MINOR = "minor"
CONF_MIN_INTERVAL = "min_interval"
CONF_MAX_INTERVAL = "max_interval"
CONF_MEASURED_POWER = "measured_power"
CONFIG_SCHEMA = cv.Schema(
def validate_config(config):
if config[CONF_MIN_INTERVAL] > config.get(CONF_MAX_INTERVAL):
raise cv.Invalid("min_interval must be <= max_interval")
return config
CONFIG_SCHEMA = cv.All(
cv.Schema(
{ {
cv.GenerateID(): cv.declare_id(ESP32BLEBeacon), cv.GenerateID(): cv.declare_id(ESP32BLEBeacon),
cv.Required(CONF_TYPE): cv.one_of("IBEACON", upper=True), cv.Required(CONF_TYPE): cv.one_of("IBEACON", upper=True),
cv.Required(CONF_UUID): cv.uuid, cv.Required(CONF_UUID): cv.uuid,
cv.Optional(CONF_MAJOR, default=10167): cv.uint16_t, cv.Optional(CONF_MAJOR, default=10167): cv.uint16_t,
cv.Optional(CONF_MINOR, default=61958): cv.uint16_t, cv.Optional(CONF_MINOR, default=61958): cv.uint16_t,
cv.Optional(CONF_MIN_INTERVAL, default="100ms"): cv.All(
cv.positive_time_period_milliseconds,
cv.Range(
min=TimePeriod(milliseconds=20), max=TimePeriod(milliseconds=10240)
),
),
cv.Optional(CONF_MAX_INTERVAL, default="100ms"): cv.All(
cv.positive_time_period_milliseconds,
cv.Range(
min=TimePeriod(milliseconds=20), max=TimePeriod(milliseconds=10240)
),
),
cv.Optional(CONF_MEASURED_POWER, default=-59): cv.int_range(
min=-128, max=0
),
cv.Optional(CONF_TX_POWER, default="3dBm"): cv.All(
cv.decibel, cv.one_of(-12, -9, -6, -3, 0, 3, 6, 9, int=True)
),
} }
).extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA),
validate_config,
)
async def to_code(config): async def to_code(config):
@ -31,6 +62,10 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
cg.add(var.set_major(config[CONF_MAJOR])) cg.add(var.set_major(config[CONF_MAJOR]))
cg.add(var.set_minor(config[CONF_MINOR])) cg.add(var.set_minor(config[CONF_MINOR]))
cg.add(var.set_min_interval(config[CONF_MIN_INTERVAL]))
cg.add(var.set_max_interval(config[CONF_MAX_INTERVAL]))
cg.add(var.set_measured_power(config[CONF_MEASURED_POWER]))
cg.add(var.set_tx_power(config[CONF_TX_POWER]))
if CORE.using_esp_idf: if CORE.using_esp_idf:
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True) add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)

View file

@ -36,11 +36,24 @@ static esp_ble_adv_params_t ble_adv_params = {
#define ENDIAN_CHANGE_U16(x) ((((x) &0xFF00) >> 8) + (((x) &0xFF) << 8)) #define ENDIAN_CHANGE_U16(x) ((((x) &0xFF00) >> 8) + (((x) &0xFF) << 8))
static const esp_ble_ibeacon_head_t IBEACON_COMMON_HEAD = { static const esp_ble_ibeacon_head_t IBEACON_COMMON_HEAD = {
.flags = {0x02, 0x01, 0x06}, .length = 0x1A, .type = 0xFF, .company_id = 0x004C, .beacon_type = 0x1502}; .flags = {0x02, 0x01, 0x06}, .length = 0x1A, .type = 0xFF, .company_id = {0x4C, 0x00}, .beacon_type = {0x02, 0x15}};
void ESP32BLEBeacon::dump_config() { void ESP32BLEBeacon::dump_config() {
ESP_LOGCONFIG(TAG, "ESP32 BLE Beacon:"); ESP_LOGCONFIG(TAG, "ESP32 BLE Beacon:");
ESP_LOGCONFIG(TAG, " Major: %u, Minor: %u", this->major_, this->minor_); char uuid[37];
char *bpos = uuid;
for (int8_t ii = 0; ii < 16; ++ii) {
bpos += sprintf(bpos, "%02X", this->uuid_[ii]);
if (ii == 3 || ii == 5 || ii == 7 || ii == 9) {
bpos += sprintf(bpos, "-");
}
}
uuid[36] = '\0';
ESP_LOGCONFIG(TAG,
" UUID: %s, Major: %u, Minor: %u, Min Interval: %ums, Max Interval: %ums, Measured Power: %d"
", TX Power: %ddBm",
uuid, this->major_, this->minor_, this->min_interval_, this->max_interval_, this->measured_power_,
this->tx_power_);
} }
void ESP32BLEBeacon::setup() { void ESP32BLEBeacon::setup() {
@ -67,6 +80,9 @@ void ESP32BLEBeacon::ble_core_task(void *params) {
} }
void ESP32BLEBeacon::ble_setup() { void ESP32BLEBeacon::ble_setup() {
ble_adv_params.adv_int_min = static_cast<uint16_t>(global_esp32_ble_beacon->min_interval_ / 0.625f);
ble_adv_params.adv_int_max = static_cast<uint16_t>(global_esp32_ble_beacon->max_interval_ / 0.625f);
// Initialize non-volatile storage for the bluetooth controller // Initialize non-volatile storage for the bluetooth controller
esp_err_t err = nvs_flash_init(); esp_err_t err = nvs_flash_init();
if (err != ESP_OK) { if (err != ESP_OK) {
@ -118,6 +134,12 @@ void ESP32BLEBeacon::ble_setup() {
ESP_LOGE(TAG, "esp_bluedroid_enable failed: %d", err); ESP_LOGE(TAG, "esp_bluedroid_enable failed: %d", err);
return; return;
} }
err = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV,
static_cast<esp_power_level_t>((global_esp32_ble_beacon->tx_power_ + 12) / 3));
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_tx_power_set failed: %s", esp_err_to_name(err));
return;
}
err = esp_ble_gap_register_callback(ESP32BLEBeacon::gap_event_handler); err = esp_ble_gap_register_callback(ESP32BLEBeacon::gap_event_handler);
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gap_register_callback failed: %d", err); ESP_LOGE(TAG, "esp_ble_gap_register_callback failed: %d", err);
@ -130,7 +152,7 @@ void ESP32BLEBeacon::ble_setup() {
sizeof(ibeacon_adv_data.ibeacon_vendor.proximity_uuid)); sizeof(ibeacon_adv_data.ibeacon_vendor.proximity_uuid));
ibeacon_adv_data.ibeacon_vendor.minor = ENDIAN_CHANGE_U16(global_esp32_ble_beacon->minor_); ibeacon_adv_data.ibeacon_vendor.minor = ENDIAN_CHANGE_U16(global_esp32_ble_beacon->minor_);
ibeacon_adv_data.ibeacon_vendor.major = ENDIAN_CHANGE_U16(global_esp32_ble_beacon->major_); ibeacon_adv_data.ibeacon_vendor.major = ENDIAN_CHANGE_U16(global_esp32_ble_beacon->major_);
ibeacon_adv_data.ibeacon_vendor.measured_power = 0xC5; ibeacon_adv_data.ibeacon_vendor.measured_power = static_cast<uint8_t>(global_esp32_ble_beacon->measured_power_);
esp_ble_gap_config_adv_data_raw((uint8_t *) &ibeacon_adv_data, sizeof(ibeacon_adv_data)); esp_ble_gap_config_adv_data_raw((uint8_t *) &ibeacon_adv_data, sizeof(ibeacon_adv_data));
} }
@ -153,7 +175,7 @@ void ESP32BLEBeacon::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap
break; break;
} }
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: { case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: {
err = param->adv_start_cmpl.status; err = param->adv_stop_cmpl.status;
if (err != ESP_BT_STATUS_SUCCESS) { if (err != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(TAG, "BLE adv stop failed: %s", esp_err_to_name(err)); ESP_LOGE(TAG, "BLE adv stop failed: %s", esp_err_to_name(err));
} else { } else {

View file

@ -5,6 +5,7 @@
#ifdef USE_ESP32 #ifdef USE_ESP32
#include <esp_gap_ble_api.h> #include <esp_gap_ble_api.h>
#include <esp_bt.h>
namespace esphome { namespace esphome {
namespace esp32_ble_beacon { namespace esp32_ble_beacon {
@ -14,8 +15,8 @@ typedef struct {
uint8_t flags[3]; uint8_t flags[3];
uint8_t length; uint8_t length;
uint8_t type; uint8_t type;
uint16_t company_id; uint8_t company_id[2];
uint16_t beacon_type; uint8_t beacon_type[2];
} __attribute__((packed)) esp_ble_ibeacon_head_t; } __attribute__((packed)) esp_ble_ibeacon_head_t;
// NOLINTNEXTLINE(modernize-use-using) // NOLINTNEXTLINE(modernize-use-using)
@ -42,6 +43,10 @@ class ESP32BLEBeacon : public Component {
void set_major(uint16_t major) { this->major_ = major; } void set_major(uint16_t major) { this->major_ = major; }
void set_minor(uint16_t minor) { this->minor_ = minor; } void set_minor(uint16_t minor) { this->minor_ = minor; }
void set_min_interval(uint16_t val) { this->min_interval_ = val; }
void set_max_interval(uint16_t val) { this->max_interval_ = val; }
void set_measured_power(int8_t val) { this->measured_power_ = val; }
void set_tx_power(int8_t val) { this->tx_power_ = val; }
protected: protected:
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
@ -51,6 +56,10 @@ class ESP32BLEBeacon : public Component {
std::array<uint8_t, 16> uuid_; std::array<uint8_t, 16> uuid_;
uint16_t major_{}; uint16_t major_{};
uint16_t minor_{}; uint16_t minor_{};
uint16_t min_interval_{};
uint16_t max_interval_{};
int8_t measured_power_{};
int8_t tx_power_{};
}; };
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)