mirror of
https://github.com/esphome/esphome.git
synced 2024-11-14 11:08:10 +01:00
Update the ibeacon code (#3859)
This commit is contained in:
parent
71387be72e
commit
5ec1588110
3 changed files with 83 additions and 17 deletions
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue