mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Update the ibeacon code (#3859)
This commit is contained in:
		| @@ -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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user