mirror of
https://github.com/esphome/esphome.git
synced 2024-11-23 15:38:11 +01:00
commit
feee075122
8 changed files with 99 additions and 34 deletions
|
@ -323,6 +323,18 @@ def validate_multi_click_timing(value):
|
||||||
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_click_timing(value):
|
||||||
|
for v in value:
|
||||||
|
min_length = v.get(CONF_MIN_LENGTH)
|
||||||
|
max_length = v.get(CONF_MAX_LENGTH)
|
||||||
|
if max_length < min_length:
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"Max length ({max_length}) must be larger than min length ({min_length})."
|
||||||
|
)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(BinarySensor),
|
cv.GenerateID(): cv.declare_id(BinarySensor),
|
||||||
|
@ -342,7 +354,8 @@ BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).ex
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ReleaseTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ReleaseTrigger),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_ON_CLICK): automation.validate_automation(
|
cv.Optional(CONF_ON_CLICK): cv.All(
|
||||||
|
automation.validate_automation(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ClickTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ClickTrigger),
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
|
@ -353,7 +366,10 @@ BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).ex
|
||||||
): cv.positive_time_period_milliseconds,
|
): cv.positive_time_period_milliseconds,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_ON_DOUBLE_CLICK): automation.validate_automation(
|
validate_click_timing,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ON_DOUBLE_CLICK): cv.All(
|
||||||
|
automation.validate_automation(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DoubleClickTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DoubleClickTrigger),
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
|
@ -364,6 +380,8 @@ BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).ex
|
||||||
): cv.positive_time_period_milliseconds,
|
): cv.positive_time_period_milliseconds,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
validate_click_timing,
|
||||||
|
),
|
||||||
cv.Optional(CONF_ON_MULTI_CLICK): automation.validate_automation(
|
cv.Optional(CONF_ON_MULTI_CLICK): automation.validate_automation(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MultiClickTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MultiClickTrigger),
|
||||||
|
|
|
@ -275,6 +275,10 @@ esp_err_t BluetoothConnection::notify_characteristic(uint16_t handle, bool enabl
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp32_ble_tracker::AdvertisementParserType BluetoothConnection::get_advertisement_parser_type() {
|
||||||
|
return this->proxy_->get_advertisement_parser_type();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace bluetooth_proxy
|
} // namespace bluetooth_proxy
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ class BluetoothConnection : public esp32_ble_client::BLEClientBase {
|
||||||
bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||||
esp_ble_gattc_cb_param_t *param) override;
|
esp_ble_gattc_cb_param_t *param) override;
|
||||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
||||||
|
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
|
||||||
|
|
||||||
esp_err_t read_characteristic(uint16_t handle);
|
esp_err_t read_characteristic(uint16_t handle);
|
||||||
esp_err_t write_characteristic(uint16_t handle, const std::string &data, bool response);
|
esp_err_t write_characteristic(uint16_t handle, const std::string &data, bool response);
|
||||||
|
|
|
@ -198,6 +198,12 @@ void BluetoothProxy::loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp32_ble_tracker::AdvertisementParserType BluetoothProxy::get_advertisement_parser_type() {
|
||||||
|
if (this->raw_advertisements_)
|
||||||
|
return esp32_ble_tracker::AdvertisementParserType::RAW_ADVERTISEMENTS;
|
||||||
|
return esp32_ble_tracker::AdvertisementParserType::PARSED_ADVERTISEMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) {
|
BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) {
|
||||||
for (auto *connection : this->connections_) {
|
for (auto *connection : this->connections_) {
|
||||||
if (connection->get_address() == address)
|
if (connection->get_address() == address)
|
||||||
|
@ -435,6 +441,7 @@ void BluetoothProxy::subscribe_api_connection(api::APIConnection *api_connection
|
||||||
}
|
}
|
||||||
this->api_connection_ = api_connection;
|
this->api_connection_ = api_connection;
|
||||||
this->raw_advertisements_ = flags & BluetoothProxySubscriptionFlag::SUBSCRIPTION_RAW_ADVERTISEMENTS;
|
this->raw_advertisements_ = flags & BluetoothProxySubscriptionFlag::SUBSCRIPTION_RAW_ADVERTISEMENTS;
|
||||||
|
this->parent_->recalculate_advertisement_parser_types();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connection) {
|
void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connection) {
|
||||||
|
@ -444,6 +451,7 @@ void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connecti
|
||||||
}
|
}
|
||||||
this->api_connection_ = nullptr;
|
this->api_connection_ = nullptr;
|
||||||
this->raw_advertisements_ = false;
|
this->raw_advertisements_ = false;
|
||||||
|
this->parent_->recalculate_advertisement_parser_types();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::send_device_connection(uint64_t address, bool connected, uint16_t mtu, esp_err_t error) {
|
void BluetoothProxy::send_device_connection(uint64_t address, bool connected, uint16_t mtu, esp_err_t error) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
||||||
bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) override;
|
bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
|
||||||
|
|
||||||
void register_connection(BluetoothConnection *connection) {
|
void register_connection(BluetoothConnection *connection) {
|
||||||
this->connections_.push_back(connection);
|
this->connections_.push_back(connection);
|
||||||
|
|
|
@ -107,16 +107,16 @@ void ESP32BLETracker::loop() {
|
||||||
ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up.");
|
ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bulk_parsed = false;
|
if (this->raw_advertisements_) {
|
||||||
|
|
||||||
for (auto *listener : this->listeners_) {
|
for (auto *listener : this->listeners_) {
|
||||||
bulk_parsed |= listener->parse_devices(this->scan_result_buffer_, this->scan_result_index_);
|
listener->parse_devices(this->scan_result_buffer_, this->scan_result_index_);
|
||||||
}
|
}
|
||||||
for (auto *client : this->clients_) {
|
for (auto *client : this->clients_) {
|
||||||
bulk_parsed |= client->parse_devices(this->scan_result_buffer_, this->scan_result_index_);
|
client->parse_devices(this->scan_result_buffer_, this->scan_result_index_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bulk_parsed) {
|
if (this->parse_advertisements_) {
|
||||||
for (size_t i = 0; i < index; i++) {
|
for (size_t i = 0; i < index; i++) {
|
||||||
ESPBTDevice device;
|
ESPBTDevice device;
|
||||||
device.parse_scan_rst(this->scan_result_buffer_[i]);
|
device.parse_scan_rst(this->scan_result_buffer_[i]);
|
||||||
|
@ -284,6 +284,32 @@ void ESP32BLETracker::end_of_scan_() {
|
||||||
void ESP32BLETracker::register_client(ESPBTClient *client) {
|
void ESP32BLETracker::register_client(ESPBTClient *client) {
|
||||||
client->app_id = ++this->app_id_;
|
client->app_id = ++this->app_id_;
|
||||||
this->clients_.push_back(client);
|
this->clients_.push_back(client);
|
||||||
|
this->recalculate_advertisement_parser_types();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32BLETracker::register_listener(ESPBTDeviceListener *listener) {
|
||||||
|
listener->set_parent(this);
|
||||||
|
this->listeners_.push_back(listener);
|
||||||
|
this->recalculate_advertisement_parser_types();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32BLETracker::recalculate_advertisement_parser_types() {
|
||||||
|
this->raw_advertisements_ = false;
|
||||||
|
this->parse_advertisements_ = false;
|
||||||
|
for (auto *listener : this->listeners_) {
|
||||||
|
if (listener->get_advertisement_parser_type() == AdvertisementParserType::PARSED_ADVERTISEMENTS) {
|
||||||
|
this->parse_advertisements_ = true;
|
||||||
|
} else {
|
||||||
|
this->raw_advertisements_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto *client : this->clients_) {
|
||||||
|
if (client->get_advertisement_parser_type() == AdvertisementParserType::PARSED_ADVERTISEMENTS) {
|
||||||
|
this->parse_advertisements_ = true;
|
||||||
|
} else {
|
||||||
|
this->raw_advertisements_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP32BLETracker::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
void ESP32BLETracker::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
||||||
|
|
|
@ -27,6 +27,11 @@ using namespace esp32_ble;
|
||||||
|
|
||||||
using adv_data_t = std::vector<uint8_t>;
|
using adv_data_t = std::vector<uint8_t>;
|
||||||
|
|
||||||
|
enum AdvertisementParserType {
|
||||||
|
PARSED_ADVERTISEMENTS,
|
||||||
|
RAW_ADVERTISEMENTS,
|
||||||
|
};
|
||||||
|
|
||||||
struct ServiceData {
|
struct ServiceData {
|
||||||
ESPBTUUID uuid;
|
ESPBTUUID uuid;
|
||||||
adv_data_t data;
|
adv_data_t data;
|
||||||
|
@ -116,6 +121,9 @@ class ESPBTDeviceListener {
|
||||||
virtual bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) {
|
virtual bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
virtual AdvertisementParserType get_advertisement_parser_type() {
|
||||||
|
return AdvertisementParserType::PARSED_ADVERTISEMENTS;
|
||||||
|
};
|
||||||
void set_parent(ESP32BLETracker *parent) { parent_ = parent; }
|
void set_parent(ESP32BLETracker *parent) { parent_ = parent; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -184,12 +192,9 @@ class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEv
|
||||||
|
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
void register_listener(ESPBTDeviceListener *listener) {
|
void register_listener(ESPBTDeviceListener *listener);
|
||||||
listener->set_parent(this);
|
|
||||||
this->listeners_.push_back(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_client(ESPBTClient *client);
|
void register_client(ESPBTClient *client);
|
||||||
|
void recalculate_advertisement_parser_types();
|
||||||
|
|
||||||
void print_bt_device_info(const ESPBTDevice &device);
|
void print_bt_device_info(const ESPBTDevice &device);
|
||||||
|
|
||||||
|
@ -231,6 +236,8 @@ class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEv
|
||||||
bool scan_continuous_;
|
bool scan_continuous_;
|
||||||
bool scan_active_;
|
bool scan_active_;
|
||||||
bool scanner_idle_;
|
bool scanner_idle_;
|
||||||
|
bool raw_advertisements_{false};
|
||||||
|
bool parse_advertisements_{false};
|
||||||
SemaphoreHandle_t scan_result_lock_;
|
SemaphoreHandle_t scan_result_lock_;
|
||||||
SemaphoreHandle_t scan_end_lock_;
|
SemaphoreHandle_t scan_end_lock_;
|
||||||
size_t scan_result_index_{0};
|
size_t scan_result_index_{0};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2023.6.4"
|
__version__ = "2023.6.5"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||||
|
|
Loading…
Reference in a new issue