mirror of
https://github.com/esphome/esphome.git
synced 2025-11-01 23:51:47 +00:00
Compare commits
23 Commits
jesserockz
...
2022.11.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7209dd8bae | ||
|
|
ab736c89bb | ||
|
|
6911639617 | ||
|
|
b9720d0715 | ||
|
|
47b3267ed4 | ||
|
|
e16ba2adb5 | ||
|
|
0a19b1e32c | ||
|
|
bae9a950c0 | ||
|
|
72b2943332 | ||
|
|
4ec0ef7548 | ||
|
|
25bc6761f6 | ||
|
|
81b6562c25 | ||
|
|
ae74189fc2 | ||
|
|
9e516efe10 | ||
|
|
366e29439e | ||
|
|
1c9c700d7f | ||
|
|
b2e6b9d31f | ||
|
|
7623f63846 | ||
|
|
2bfaf9dce3 | ||
|
|
5c2c1560bb | ||
|
|
f7096ab78e | ||
|
|
98f8feb625 | ||
|
|
9944ca414e |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -177,7 +177,7 @@ jobs:
|
||||
|
||||
- name: Run yamllint
|
||||
if: matrix.id == 'yamllint'
|
||||
uses: frenck/action-yamllint@v1.3.1
|
||||
uses: frenck/action-yamllint@v1.3.0
|
||||
|
||||
- name: Suggested changes
|
||||
run: script/ci-suggest-changes
|
||||
|
||||
@@ -11,7 +11,7 @@ repos:
|
||||
- --quiet
|
||||
files: ^((esphome|script|tests)/.+)?[^/]+\.py$
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
rev: 5.0.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
@@ -27,7 +27,7 @@ repos:
|
||||
- --branch=release
|
||||
- --branch=beta
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.2.2
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
|
||||
@@ -6,11 +6,17 @@
|
||||
ARG BASEIMGTYPE=docker
|
||||
|
||||
# https://github.com/hassio-addons/addon-debian-base/releases
|
||||
FROM ghcr.io/hassio-addons/debian-base:6.1.3 AS base-hassio
|
||||
FROM ghcr.io/hassio-addons/debian-base/amd64:5.3.0 AS base-hassio-amd64
|
||||
FROM ghcr.io/hassio-addons/debian-base/aarch64:5.3.0 AS base-hassio-arm64
|
||||
FROM ghcr.io/hassio-addons/debian-base/armv7:5.3.0 AS base-hassio-armv7
|
||||
# https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye
|
||||
FROM debian:bullseye-20221024-slim AS base-docker
|
||||
FROM debian:bullseye-20220328-slim AS base-docker-amd64
|
||||
FROM debian:bullseye-20220328-slim AS base-docker-arm64
|
||||
FROM debian:bullseye-20220328-slim AS base-docker-armv7
|
||||
|
||||
FROM base-${BASEIMGTYPE} AS base
|
||||
# Use TARGETARCH/TARGETVARIANT defined by docker
|
||||
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
|
||||
FROM base-${BASEIMGTYPE}-${TARGETARCH}${TARGETVARIANT} AS base
|
||||
|
||||
RUN \
|
||||
apt-get update \
|
||||
@@ -23,8 +29,8 @@ RUN \
|
||||
python3-cryptography=3.3.2-1 \
|
||||
iputils-ping=3:20210202-1 \
|
||||
git=1:2.30.2-1 \
|
||||
curl=7.74.0-1.3+deb11u3 \
|
||||
openssh-client=1:8.4p1-5+deb11u1 \
|
||||
curl=7.74.0-1.3+deb11u1 \
|
||||
openssh-client=1:8.4p1-5 \
|
||||
&& rm -rf \
|
||||
/tmp/* \
|
||||
/var/{cache,log}/* \
|
||||
|
||||
0
docker/ha-addon-rootfs/etc/cont-init.d/30-dirs.sh
Executable file → Normal file
0
docker/ha-addon-rootfs/etc/cont-init.d/30-dirs.sh
Executable file → Normal file
@@ -3,13 +3,7 @@
|
||||
# Community Hass.io Add-ons: ESPHome
|
||||
# Take down the S6 supervision tree when ESPHome fails
|
||||
# ==============================================================================
|
||||
if -n { s6-test $# -ne 0 }
|
||||
if -n { s6-test ${1} -eq 256 }
|
||||
|
||||
declare APP_EXIT_CODE=${1}
|
||||
|
||||
if [[ "${APP_EXIT_CODE}" -ne 0 ]] && [[ "${APP_EXIT_CODE}" -ne 256 ]]; then
|
||||
bashio::log.warning "Halt add-on with exit code ${APP_EXIT_CODE}"
|
||||
echo "${APP_EXIT_CODE}" > /run/s6-linux-init-container-results/exitcode
|
||||
exec /run/s6/basedir/bin/halt
|
||||
fi
|
||||
|
||||
bashio::log.info "Service restart after closing"
|
||||
s6-svscanctl -t /var/run/s6/services
|
||||
|
||||
@@ -22,14 +22,6 @@ if bashio::config.has_value 'relative_url'; then
|
||||
export ESPHOME_DASHBOARD_RELATIVE_URL=$(bashio::config 'relative_url')
|
||||
fi
|
||||
|
||||
if bashio::config.has_value 'default_compile_process_limit'; then
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=$(bashio::config 'default_compile_process_limit')
|
||||
else
|
||||
if grep -q 'Raspberry Pi 3' /proc/cpuinfo; then
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=1;
|
||||
fi
|
||||
fi
|
||||
|
||||
pio_cache_base=/data/cache/platformio
|
||||
# we can't set core_dir, because the settings file is stored in `core_dir/appstate.json`
|
||||
# setting `core_dir` would therefore prevent pio from accessing
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
# Community Hass.io Add-ons: ESPHome
|
||||
# Take down the S6 supervision tree when NGINX fails
|
||||
# ==============================================================================
|
||||
if -n { s6-test $# -ne 0 }
|
||||
if -n { s6-test ${1} -eq 256 }
|
||||
|
||||
declare APP_EXIT_CODE=${1}
|
||||
|
||||
if [[ "${APP_EXIT_CODE}" -ne 0 ]] && [[ "${APP_EXIT_CODE}" -ne 256 ]]; then
|
||||
bashio::log.warning "Halt add-on with exit code ${APP_EXIT_CODE}"
|
||||
echo "${APP_EXIT_CODE}" > /run/s6-linux-init-container-results/exitcode
|
||||
exec /run/s6/basedir/bin/halt
|
||||
fi
|
||||
|
||||
bashio::log.info "Service restart after closing"
|
||||
s6-svscanctl -t /var/run/s6/services
|
||||
|
||||
@@ -254,7 +254,8 @@ def upload_using_esptool(config, port):
|
||||
if os.environ.get("ESPHOME_USE_SUBPROCESS") is None:
|
||||
import esptool
|
||||
|
||||
return run_external_command(esptool.main, *cmd) # pylint: disable=no-member
|
||||
# pylint: disable=protected-access
|
||||
return run_external_command(esptool._main, *cmd)
|
||||
|
||||
return run_external_process(*cmd)
|
||||
|
||||
@@ -297,8 +298,6 @@ def upload_program(config, args, host):
|
||||
ota_conf = config[CONF_OTA]
|
||||
remote_port = ota_conf[CONF_PORT]
|
||||
password = ota_conf.get(CONF_PASSWORD, "")
|
||||
if getattr(args, "file", None) is not None:
|
||||
return espota2.run_ota(host, remote_port, password, args.file)
|
||||
return espota2.run_ota(host, remote_port, password, CORE.firmware_bin)
|
||||
|
||||
|
||||
@@ -688,10 +687,6 @@ def parse_args(argv):
|
||||
"--device",
|
||||
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
|
||||
)
|
||||
parser_upload.add_argument(
|
||||
"--file",
|
||||
help="Manually specify the binary file to upload.",
|
||||
)
|
||||
|
||||
parser_logs = subparsers.add_parser(
|
||||
"logs",
|
||||
|
||||
@@ -117,11 +117,10 @@ void ADCSensor::dump_config() {
|
||||
}
|
||||
#endif // USE_ESP32
|
||||
#ifdef USE_RP2040
|
||||
if (this->is_temperature_) {
|
||||
if (this->is_temperature_)
|
||||
ESP_LOGCONFIG(TAG, " Pin: Temperature");
|
||||
} else {
|
||||
else
|
||||
LOG_PIN(" Pin: ", pin_);
|
||||
}
|
||||
#endif
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "esphome/components/display/display_buffer.h"
|
||||
#include "esphome/components/light/addressable_light.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace addressable_light {
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace ade7953 {
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/voltage_sampler/voltage_sampler.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace ads1115 {
|
||||
|
||||
|
||||
@@ -122,9 +122,8 @@ void AHT10Component::update() {
|
||||
this->temperature_sensor_->publish_state(temperature);
|
||||
}
|
||||
if (this->humidity_sensor_ != nullptr) {
|
||||
if (std::isnan(humidity)) {
|
||||
if (std::isnan(humidity))
|
||||
ESP_LOGW(TAG, "Invalid humidity! Sensor reported 0%% Hum");
|
||||
}
|
||||
this->humidity_sensor_->publish_state(humidity);
|
||||
}
|
||||
this->status_clear_warning();
|
||||
|
||||
@@ -104,9 +104,8 @@ void Am43::update() {
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
|
||||
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
|
||||
}
|
||||
}
|
||||
this->current_sensor_++;
|
||||
}
|
||||
|
||||
@@ -56,9 +56,8 @@ void Am43Component::control(const CoverCall &call) {
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
|
||||
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] Error writing stop command to device, error = %d", this->get_name().c_str(), status);
|
||||
}
|
||||
}
|
||||
if (call.get_position().has_value()) {
|
||||
auto pos = *call.get_position();
|
||||
@@ -69,9 +68,8 @@ void Am43Component::control(const CoverCall &call) {
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
|
||||
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] Error writing set_position command to device, error = %d", this->get_name().c_str(), status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,21 +126,18 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
auto status = esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(),
|
||||
this->char_handle_, packet->length, packet->data,
|
||||
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] Error writing set_position to device, error = %d", this->get_name().c_str(), status);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(TAG, "[%s] AM43 pin rejected!", this->get_name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (this->decoder_->has_set_position_response() && !this->decoder_->set_position_ok_) {
|
||||
if (this->decoder_->has_set_position_response() && !this->decoder_->set_position_ok_)
|
||||
ESP_LOGW(TAG, "[%s] Got nack after sending set_position. Bad pin?", this->get_name().c_str());
|
||||
}
|
||||
|
||||
if (this->decoder_->has_set_state_response() && !this->decoder_->set_state_ok_) {
|
||||
if (this->decoder_->has_set_state_response() && !this->decoder_->set_state_ok_)
|
||||
ESP_LOGW(TAG, "[%s] Got nack after sending set_state. Bad pin?", this->get_name().c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -37,18 +37,16 @@ void Anova::control(const ClimateCall &call) {
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
|
||||
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
|
||||
}
|
||||
}
|
||||
if (call.get_target_temperature().has_value()) {
|
||||
auto *pkt = this->codec_->get_set_target_temp_request(*call.get_target_temperature());
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
|
||||
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,9 +143,8 @@ void Anova::update() {
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
|
||||
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
|
||||
}
|
||||
this->current_request_++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -915,7 +915,6 @@ message ListEntitiesNumberResponse {
|
||||
EntityCategory entity_category = 10;
|
||||
string unit_of_measurement = 11;
|
||||
NumberMode mode = 12;
|
||||
string device_class = 13;
|
||||
}
|
||||
message NumberStateResponse {
|
||||
option (id) = 50;
|
||||
@@ -1141,8 +1140,6 @@ message BluetoothLEAdvertisementResponse {
|
||||
repeated string service_uuids = 4;
|
||||
repeated BluetoothServiceData service_data = 5;
|
||||
repeated BluetoothServiceData manufacturer_data = 6;
|
||||
|
||||
uint32 address_type = 7;
|
||||
}
|
||||
|
||||
enum BluetoothDeviceRequestType {
|
||||
@@ -1150,8 +1147,6 @@ enum BluetoothDeviceRequestType {
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_DISCONNECT = 1;
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR = 2;
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR = 3;
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE = 4;
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5;
|
||||
}
|
||||
|
||||
message BluetoothDeviceRequest {
|
||||
@@ -1161,8 +1156,6 @@ message BluetoothDeviceRequest {
|
||||
|
||||
uint64 address = 1;
|
||||
BluetoothDeviceRequestType request_type = 2;
|
||||
bool has_address_type = 3;
|
||||
uint32 address_type = 4;
|
||||
}
|
||||
|
||||
message BluetoothDeviceConnectionResponse {
|
||||
|
||||
@@ -616,7 +616,6 @@ bool APIConnection::send_number_info(number::Number *number) {
|
||||
msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category());
|
||||
msg.unit_of_measurement = number->traits.get_unit_of_measurement();
|
||||
msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
|
||||
msg.device_class = number->traits.get_device_class();
|
||||
|
||||
msg.min_value = number->traits.get_min_value();
|
||||
msg.max_value = number->traits.get_max_value();
|
||||
@@ -950,7 +949,7 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
||||
resp.webserver_port = USE_WEBSERVER_PORT;
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
resp.bluetooth_proxy_version = bluetooth_proxy::global_bluetooth_proxy->has_active() ? 3 : 1;
|
||||
resp.bluetooth_proxy_version = bluetooth_proxy::global_bluetooth_proxy->has_active() ? 2 : 1;
|
||||
#endif
|
||||
return resp;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace api {
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
namespace esphome {
|
||||
namespace api {
|
||||
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::EntityCategory>(enums::EntityCategory value) {
|
||||
switch (value) {
|
||||
case enums::ENTITY_CATEGORY_NONE:
|
||||
@@ -19,8 +18,6 @@ template<> const char *proto_enum_to_string<enums::EntityCategory>(enums::Entity
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::LegacyCoverState>(enums::LegacyCoverState value) {
|
||||
switch (value) {
|
||||
case enums::LEGACY_COVER_STATE_OPEN:
|
||||
@@ -31,8 +28,6 @@ template<> const char *proto_enum_to_string<enums::LegacyCoverState>(enums::Lega
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::CoverOperation>(enums::CoverOperation value) {
|
||||
switch (value) {
|
||||
case enums::COVER_OPERATION_IDLE:
|
||||
@@ -45,8 +40,6 @@ template<> const char *proto_enum_to_string<enums::CoverOperation>(enums::CoverO
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::LegacyCoverCommand>(enums::LegacyCoverCommand value) {
|
||||
switch (value) {
|
||||
case enums::LEGACY_COVER_COMMAND_OPEN:
|
||||
@@ -59,8 +52,6 @@ template<> const char *proto_enum_to_string<enums::LegacyCoverCommand>(enums::Le
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::FanSpeed>(enums::FanSpeed value) {
|
||||
switch (value) {
|
||||
case enums::FAN_SPEED_LOW:
|
||||
@@ -73,8 +64,6 @@ template<> const char *proto_enum_to_string<enums::FanSpeed>(enums::FanSpeed val
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::FanDirection>(enums::FanDirection value) {
|
||||
switch (value) {
|
||||
case enums::FAN_DIRECTION_FORWARD:
|
||||
@@ -85,8 +74,6 @@ template<> const char *proto_enum_to_string<enums::FanDirection>(enums::FanDirec
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ColorMode>(enums::ColorMode value) {
|
||||
switch (value) {
|
||||
case enums::COLOR_MODE_UNKNOWN:
|
||||
@@ -113,8 +100,6 @@ template<> const char *proto_enum_to_string<enums::ColorMode>(enums::ColorMode v
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::SensorStateClass>(enums::SensorStateClass value) {
|
||||
switch (value) {
|
||||
case enums::STATE_CLASS_NONE:
|
||||
@@ -129,8 +114,6 @@ template<> const char *proto_enum_to_string<enums::SensorStateClass>(enums::Sens
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::SensorLastResetType>(enums::SensorLastResetType value) {
|
||||
switch (value) {
|
||||
case enums::LAST_RESET_NONE:
|
||||
@@ -143,8 +126,6 @@ template<> const char *proto_enum_to_string<enums::SensorLastResetType>(enums::S
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::LogLevel>(enums::LogLevel value) {
|
||||
switch (value) {
|
||||
case enums::LOG_LEVEL_NONE:
|
||||
@@ -167,8 +148,6 @@ template<> const char *proto_enum_to_string<enums::LogLevel>(enums::LogLevel val
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ServiceArgType>(enums::ServiceArgType value) {
|
||||
switch (value) {
|
||||
case enums::SERVICE_ARG_TYPE_BOOL:
|
||||
@@ -191,8 +170,6 @@ template<> const char *proto_enum_to_string<enums::ServiceArgType>(enums::Servic
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ClimateMode>(enums::ClimateMode value) {
|
||||
switch (value) {
|
||||
case enums::CLIMATE_MODE_OFF:
|
||||
@@ -213,8 +190,6 @@ template<> const char *proto_enum_to_string<enums::ClimateMode>(enums::ClimateMo
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ClimateFanMode>(enums::ClimateFanMode value) {
|
||||
switch (value) {
|
||||
case enums::CLIMATE_FAN_ON:
|
||||
@@ -239,8 +214,6 @@ template<> const char *proto_enum_to_string<enums::ClimateFanMode>(enums::Climat
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ClimateSwingMode>(enums::ClimateSwingMode value) {
|
||||
switch (value) {
|
||||
case enums::CLIMATE_SWING_OFF:
|
||||
@@ -255,8 +228,6 @@ template<> const char *proto_enum_to_string<enums::ClimateSwingMode>(enums::Clim
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ClimateAction>(enums::ClimateAction value) {
|
||||
switch (value) {
|
||||
case enums::CLIMATE_ACTION_OFF:
|
||||
@@ -275,8 +246,6 @@ template<> const char *proto_enum_to_string<enums::ClimateAction>(enums::Climate
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::ClimatePreset>(enums::ClimatePreset value) {
|
||||
switch (value) {
|
||||
case enums::CLIMATE_PRESET_NONE:
|
||||
@@ -299,8 +268,6 @@ template<> const char *proto_enum_to_string<enums::ClimatePreset>(enums::Climate
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::NumberMode>(enums::NumberMode value) {
|
||||
switch (value) {
|
||||
case enums::NUMBER_MODE_AUTO:
|
||||
@@ -313,8 +280,6 @@ template<> const char *proto_enum_to_string<enums::NumberMode>(enums::NumberMode
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::LockState>(enums::LockState value) {
|
||||
switch (value) {
|
||||
case enums::LOCK_STATE_NONE:
|
||||
@@ -333,8 +298,6 @@ template<> const char *proto_enum_to_string<enums::LockState>(enums::LockState v
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::LockCommand>(enums::LockCommand value) {
|
||||
switch (value) {
|
||||
case enums::LOCK_UNLOCK:
|
||||
@@ -347,8 +310,6 @@ template<> const char *proto_enum_to_string<enums::LockCommand>(enums::LockComma
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::MediaPlayerState>(enums::MediaPlayerState value) {
|
||||
switch (value) {
|
||||
case enums::MEDIA_PLAYER_STATE_NONE:
|
||||
@@ -363,8 +324,6 @@ template<> const char *proto_enum_to_string<enums::MediaPlayerState>(enums::Medi
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::MediaPlayerCommand>(enums::MediaPlayerCommand value) {
|
||||
switch (value) {
|
||||
case enums::MEDIA_PLAYER_COMMAND_PLAY:
|
||||
@@ -381,8 +340,6 @@ template<> const char *proto_enum_to_string<enums::MediaPlayerCommand>(enums::Me
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<>
|
||||
const char *proto_enum_to_string<enums::BluetoothDeviceRequestType>(enums::BluetoothDeviceRequestType value) {
|
||||
switch (value) {
|
||||
@@ -394,15 +351,10 @@ const char *proto_enum_to_string<enums::BluetoothDeviceRequestType>(enums::Bluet
|
||||
return "BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR";
|
||||
case enums::BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR:
|
||||
return "BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR";
|
||||
case enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE:
|
||||
return "BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE";
|
||||
case enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE:
|
||||
return "BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 2: {
|
||||
@@ -3990,10 +3942,6 @@ bool ListEntitiesNumberResponse::decode_length(uint32_t field_id, ProtoLengthDel
|
||||
this->unit_of_measurement = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 13: {
|
||||
this->device_class = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -4033,7 +3981,6 @@ void ListEntitiesNumberResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_enum<enums::EntityCategory>(10, this->entity_category);
|
||||
buffer.encode_string(11, this->unit_of_measurement);
|
||||
buffer.encode_enum<enums::NumberMode>(12, this->mode);
|
||||
buffer.encode_string(13, this->device_class);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesNumberResponse::dump_to(std::string &out) const {
|
||||
@@ -4090,10 +4037,6 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const {
|
||||
out.append(" mode: ");
|
||||
out.append(proto_enum_to_string<enums::NumberMode>(this->mode));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" device_class: ");
|
||||
out.append("'").append(this->device_class).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
@@ -5041,10 +4984,6 @@ bool BluetoothLEAdvertisementResponse::decode_varint(uint32_t field_id, ProtoVar
|
||||
this->rssi = value.as_sint32();
|
||||
return true;
|
||||
}
|
||||
case 7: {
|
||||
this->address_type = value.as_uint32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -5084,7 +5023,6 @@ void BluetoothLEAdvertisementResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
for (auto &it : this->manufacturer_data) {
|
||||
buffer.encode_message<BluetoothServiceData>(6, it, true);
|
||||
}
|
||||
buffer.encode_uint32(7, this->address_type);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void BluetoothLEAdvertisementResponse::dump_to(std::string &out) const {
|
||||
@@ -5121,11 +5059,6 @@ void BluetoothLEAdvertisementResponse::dump_to(std::string &out) const {
|
||||
it.dump_to(out);
|
||||
out.append("\n");
|
||||
}
|
||||
|
||||
out.append(" address_type: ");
|
||||
sprintf(buffer, "%u", this->address_type);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
@@ -5139,14 +5072,6 @@ bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value)
|
||||
this->request_type = value.as_enum<enums::BluetoothDeviceRequestType>();
|
||||
return true;
|
||||
}
|
||||
case 3: {
|
||||
this->has_address_type = value.as_bool();
|
||||
return true;
|
||||
}
|
||||
case 4: {
|
||||
this->address_type = value.as_uint32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -5154,8 +5079,6 @@ bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value)
|
||||
void BluetoothDeviceRequest::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_enum<enums::BluetoothDeviceRequestType>(2, this->request_type);
|
||||
buffer.encode_bool(3, this->has_address_type);
|
||||
buffer.encode_uint32(4, this->address_type);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void BluetoothDeviceRequest::dump_to(std::string &out) const {
|
||||
@@ -5169,15 +5092,6 @@ void BluetoothDeviceRequest::dump_to(std::string &out) const {
|
||||
out.append(" request_type: ");
|
||||
out.append(proto_enum_to_string<enums::BluetoothDeviceRequestType>(this->request_type));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" has_address_type: ");
|
||||
out.append(YESNO(this->has_address_type));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" address_type: ");
|
||||
sprintf(buffer, "%u", this->address_type);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -160,8 +160,6 @@ enum BluetoothDeviceRequestType : uint32_t {
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_DISCONNECT = 1,
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR = 2,
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR = 3,
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE = 4,
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5,
|
||||
};
|
||||
|
||||
} // namespace enums
|
||||
@@ -1006,7 +1004,6 @@ class ListEntitiesNumberResponse : public ProtoMessage {
|
||||
enums::EntityCategory entity_category{};
|
||||
std::string unit_of_measurement{};
|
||||
enums::NumberMode mode{};
|
||||
std::string device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
@@ -1259,7 +1256,6 @@ class BluetoothLEAdvertisementResponse : public ProtoMessage {
|
||||
std::vector<std::string> service_uuids{};
|
||||
std::vector<BluetoothServiceData> service_data{};
|
||||
std::vector<BluetoothServiceData> manufacturer_data{};
|
||||
uint32_t address_type{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
@@ -1273,8 +1269,6 @@ class BluetoothDeviceRequest : public ProtoMessage {
|
||||
public:
|
||||
uint64_t address{0};
|
||||
enums::BluetoothDeviceRequestType request_type{};
|
||||
bool has_address_type{false};
|
||||
uint32_t address_type{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "user_services.h"
|
||||
#include "api_noise_context.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace api {
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "api_pb2.h"
|
||||
#include "api_server.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace api {
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||
#define HAS_PROTO_MESSAGE_DUMP
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
namespace esphome {
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "bedjet_child.h"
|
||||
#include "bedjet_codec.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_TIME
|
||||
#include "esphome/components/time/real_time_clock.h"
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/binary_sensor/filter.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
namespace binary_sensor {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
namespace binary_sensor {
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace binary_sensor_map {
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ CONF_BLE_CLIENT_ID = "ble_client_id"
|
||||
|
||||
BLE_CLIENT_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_BLE_CLIENT_ID): cv.use_id(BLEClient),
|
||||
cv.Required(CONF_BLE_CLIENT_ID): cv.use_id(BLEClient),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -78,7 +78,7 @@ async def register_ble_node(var, config):
|
||||
|
||||
BLE_WRITE_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
|
||||
cv.Required(CONF_ID): cv.use_id(BLEClient),
|
||||
cv.Required(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Required(CONF_CHARACTERISTIC_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Required(CONF_VALUE): cv.templatable(cv.ensure_list(cv.hex_uint8_t)),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/components/ble_client/ble_client.h"
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <esp_bt_defs.h>
|
||||
#include <esp_gap_ble_api.h>
|
||||
#include <esp_gatt_common_api.h>
|
||||
#include <esp_gattc_api.h>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <esp_gap_ble_api.h>
|
||||
#include <esp_gattc_api.h>
|
||||
#include <esp_bt_defs.h>
|
||||
#include <esp_gatt_common_api.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace ble_client {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#include <esp_gattc_api.h>
|
||||
|
||||
|
||||
@@ -34,39 +34,12 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
||||
this->set_address(0);
|
||||
api::global_api_server->send_bluetooth_connections_free(this->proxy_->get_bluetooth_connections_free(),
|
||||
this->proxy_->get_bluetooth_connections_limit());
|
||||
} else if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) {
|
||||
api::global_api_server->send_bluetooth_device_connection(this->address_, true, this->mtu_);
|
||||
api::global_api_server->send_bluetooth_connections_free(this->proxy_->get_bluetooth_connections_free(),
|
||||
this->proxy_->get_bluetooth_connections_limit());
|
||||
}
|
||||
this->seen_mtu_or_services_ = false;
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_CFG_MTU_EVT: {
|
||||
if (param->cfg_mtu.conn_id != this->conn_id_)
|
||||
break;
|
||||
if (!this->seen_mtu_or_services_) {
|
||||
// We don't know if we will get the MTU or the services first, so
|
||||
// only send the device connection true if we have already received
|
||||
// the services.
|
||||
this->seen_mtu_or_services_ = true;
|
||||
break;
|
||||
}
|
||||
api::global_api_server->send_bluetooth_device_connection(this->address_, true, this->mtu_);
|
||||
api::global_api_server->send_bluetooth_connections_free(this->proxy_->get_bluetooth_connections_free(),
|
||||
this->proxy_->get_bluetooth_connections_limit());
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
if (param->search_cmpl.conn_id != this->conn_id_)
|
||||
break;
|
||||
if (!this->seen_mtu_or_services_) {
|
||||
// We don't know if we will get the MTU or the services first, so
|
||||
// only send the device connection true if we have already received
|
||||
// the mtu.
|
||||
this->seen_mtu_or_services_ = true;
|
||||
break;
|
||||
}
|
||||
api::global_api_server->send_bluetooth_device_connection(this->address_, true, this->mtu_);
|
||||
api::global_api_server->send_bluetooth_connections_free(this->proxy_->get_bluetooth_connections_free(),
|
||||
this->proxy_->get_bluetooth_connections_limit());
|
||||
@@ -109,6 +82,8 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_UNREG_FOR_NOTIFY_EVT: {
|
||||
if (this->get_characteristic(param->unreg_for_notify.handle) == nullptr) // No conn_id in this event
|
||||
break;
|
||||
if (param->unreg_for_notify.status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Error unregistering notifications for handle 0x%2X, status=%d",
|
||||
this->connection_index_, this->address_str_.c_str(), param->unreg_for_notify.handle,
|
||||
@@ -124,6 +99,8 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
|
||||
if (this->get_characteristic(param->reg_for_notify.handle) == nullptr) // No conn_id in this event
|
||||
break;
|
||||
if (param->reg_for_notify.status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Error registering notifications for handle 0x%2X, status=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), param->reg_for_notify.handle, param->reg_for_notify.status);
|
||||
@@ -164,11 +141,18 @@ esp_err_t BluetoothConnection::read_characteristic(uint16_t handle) {
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_NOT_CONNECTED;
|
||||
}
|
||||
auto *characteristic = this->get_characteristic(handle);
|
||||
if (characteristic == nullptr) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Cannot read GATT characteristic, not found.", this->connection_index_,
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "[%d] [%s] Reading GATT characteristic handle %d", this->connection_index_, this->address_str_.c_str(),
|
||||
handle);
|
||||
ESP_LOGV(TAG, "[%d] [%s] Reading GATT characteristic %s", this->connection_index_, this->address_str_.c_str(),
|
||||
characteristic->uuid.to_string().c_str());
|
||||
|
||||
esp_err_t err = esp_ble_gattc_read_char(this->gattc_if_, this->conn_id_, handle, ESP_GATT_AUTH_REQ_NONE);
|
||||
esp_err_t err =
|
||||
esp_ble_gattc_read_char(this->gattc_if_, this->conn_id_, characteristic->handle, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (err != ERR_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_read_char error, err=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), err);
|
||||
@@ -183,12 +167,18 @@ esp_err_t BluetoothConnection::write_characteristic(uint16_t handle, const std::
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_NOT_CONNECTED;
|
||||
}
|
||||
ESP_LOGV(TAG, "[%d] [%s] Writing GATT characteristic handle %d", this->connection_index_, this->address_str_.c_str(),
|
||||
handle);
|
||||
auto *characteristic = this->get_characteristic(handle);
|
||||
if (characteristic == nullptr) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Cannot write GATT characteristic, not found.", this->connection_index_,
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
esp_err_t err =
|
||||
esp_ble_gattc_write_char(this->gattc_if_, this->conn_id_, handle, data.size(), (uint8_t *) data.data(),
|
||||
response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
ESP_LOGV(TAG, "[%d] [%s] Writing GATT characteristic %s", this->connection_index_, this->address_str_.c_str(),
|
||||
characteristic->uuid.to_string().c_str());
|
||||
|
||||
auto err = characteristic->write_value((uint8_t *) data.data(), data.size(),
|
||||
response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP);
|
||||
if (err != ERR_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_write_char error, err=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), err);
|
||||
@@ -203,10 +193,18 @@ esp_err_t BluetoothConnection::read_descriptor(uint16_t handle) {
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_NOT_CONNECTED;
|
||||
}
|
||||
ESP_LOGV(TAG, "[%d] [%s] Reading GATT descriptor handle %d", this->connection_index_, this->address_str_.c_str(),
|
||||
handle);
|
||||
auto *descriptor = this->get_descriptor(handle);
|
||||
if (descriptor == nullptr) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Cannot read GATT descriptor, not found.", this->connection_index_,
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_ble_gattc_read_char_descr(this->gattc_if_, this->conn_id_, handle, ESP_GATT_AUTH_REQ_NONE);
|
||||
ESP_LOGV(TAG, "[%d] [%s] Reading GATT descriptor %s", this->connection_index_, this->address_str_.c_str(),
|
||||
descriptor->uuid.to_string().c_str());
|
||||
|
||||
esp_err_t err =
|
||||
esp_ble_gattc_read_char_descr(this->gattc_if_, this->conn_id_, descriptor->handle, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (err != ERR_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_read_char_descr error, err=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), err);
|
||||
@@ -215,18 +213,25 @@ esp_err_t BluetoothConnection::read_descriptor(uint16_t handle) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t BluetoothConnection::write_descriptor(uint16_t handle, const std::string &data, bool response) {
|
||||
esp_err_t BluetoothConnection::write_descriptor(uint16_t handle, const std::string &data) {
|
||||
if (!this->connected()) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Cannot write GATT descriptor, not connected.", this->connection_index_,
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_NOT_CONNECTED;
|
||||
}
|
||||
ESP_LOGV(TAG, "[%d] [%s] Writing GATT descriptor handle %d", this->connection_index_, this->address_str_.c_str(),
|
||||
handle);
|
||||
auto *descriptor = this->get_descriptor(handle);
|
||||
if (descriptor == nullptr) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Cannot write GATT descriptor, not found.", this->connection_index_,
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_ble_gattc_write_char_descr(
|
||||
this->gattc_if_, this->conn_id_, handle, data.size(), (uint8_t *) data.data(),
|
||||
response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
ESP_LOGV(TAG, "[%d] [%s] Writing GATT descriptor %s", this->connection_index_, this->address_str_.c_str(),
|
||||
descriptor->uuid.to_string().c_str());
|
||||
|
||||
auto err =
|
||||
esp_ble_gattc_write_char_descr(this->gattc_if_, this->conn_id_, descriptor->handle, data.size(),
|
||||
(uint8_t *) data.data(), ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (err != ERR_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_write_char_descr error, err=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), err);
|
||||
@@ -241,20 +246,26 @@ esp_err_t BluetoothConnection::notify_characteristic(uint16_t handle, bool enabl
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_NOT_CONNECTED;
|
||||
}
|
||||
auto *characteristic = this->get_characteristic(handle);
|
||||
if (characteristic == nullptr) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Cannot notify GATT characteristic, not found.", this->connection_index_,
|
||||
this->address_str_.c_str());
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
ESP_LOGV(TAG, "[%d] [%s] Registering for GATT characteristic notifications handle %d", this->connection_index_,
|
||||
this->address_str_.c_str(), handle);
|
||||
esp_err_t err = esp_ble_gattc_register_for_notify(this->gattc_if_, this->remote_bda_, handle);
|
||||
ESP_LOGV(TAG, "[%d] [%s] Registering for GATT characteristic notifications %s", this->connection_index_,
|
||||
this->address_str_.c_str(), characteristic->uuid.to_string().c_str());
|
||||
esp_err_t err = esp_ble_gattc_register_for_notify(this->gattc_if_, this->remote_bda_, characteristic->handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_register_for_notify failed, err=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), err);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGV(TAG, "[%d] [%s] Unregistering for GATT characteristic notifications handle %d", this->connection_index_,
|
||||
this->address_str_.c_str(), handle);
|
||||
esp_err_t err = esp_ble_gattc_unregister_for_notify(this->gattc_if_, this->remote_bda_, handle);
|
||||
ESP_LOGV(TAG, "[%d] [%s] Unregistering for GATT characteristic notifications %s", this->connection_index_,
|
||||
this->address_str_.c_str(), characteristic->uuid.to_string().c_str());
|
||||
esp_err_t err = esp_ble_gattc_unregister_for_notify(this->gattc_if_, this->remote_bda_, characteristic->handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_unregister_for_notify failed, err=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), err);
|
||||
|
||||
@@ -17,15 +17,14 @@ class BluetoothConnection : public esp32_ble_client::BLEClientBase {
|
||||
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 read_descriptor(uint16_t handle);
|
||||
esp_err_t write_descriptor(uint16_t handle, const std::string &data, bool response);
|
||||
esp_err_t write_descriptor(uint16_t handle, const std::string &data);
|
||||
|
||||
esp_err_t notify_characteristic(uint16_t handle, bool enable);
|
||||
|
||||
protected:
|
||||
friend class BluetoothProxy;
|
||||
bool seen_mtu_or_services_{false};
|
||||
|
||||
int16_t send_service_{-2};
|
||||
int16_t send_service_{-1};
|
||||
BluetoothProxy *proxy_;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,19 +10,6 @@ namespace esphome {
|
||||
namespace bluetooth_proxy {
|
||||
|
||||
static const char *const TAG = "bluetooth_proxy";
|
||||
static const int DONE_SENDING_SERVICES = -2;
|
||||
|
||||
std::vector<uint64_t> get_128bit_uuid_vec(esp_bt_uuid_t uuid_source) {
|
||||
esp_bt_uuid_t uuid = espbt::ESPBTUUID::from_uuid(uuid_source).as_128bit().get_uuid();
|
||||
return std::vector<uint64_t>{((uint64_t) uuid.uuid.uuid128[15] << 56) | ((uint64_t) uuid.uuid.uuid128[14] << 48) |
|
||||
((uint64_t) uuid.uuid.uuid128[13] << 40) | ((uint64_t) uuid.uuid.uuid128[12] << 32) |
|
||||
((uint64_t) uuid.uuid.uuid128[11] << 24) | ((uint64_t) uuid.uuid.uuid128[10] << 16) |
|
||||
((uint64_t) uuid.uuid.uuid128[9] << 8) | ((uint64_t) uuid.uuid.uuid128[8]),
|
||||
((uint64_t) uuid.uuid.uuid128[7] << 56) | ((uint64_t) uuid.uuid.uuid128[6] << 48) |
|
||||
((uint64_t) uuid.uuid.uuid128[5] << 40) | ((uint64_t) uuid.uuid.uuid128[4] << 32) |
|
||||
((uint64_t) uuid.uuid.uuid128[3] << 24) | ((uint64_t) uuid.uuid.uuid128[2] << 16) |
|
||||
((uint64_t) uuid.uuid.uuid128[1] << 8) | ((uint64_t) uuid.uuid.uuid128[0])};
|
||||
}
|
||||
|
||||
BluetoothProxy::BluetoothProxy() { global_bluetooth_proxy = this; }
|
||||
|
||||
@@ -39,7 +26,6 @@ bool BluetoothProxy::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
|
||||
void BluetoothProxy::send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device) {
|
||||
api::BluetoothLEAdvertisementResponse resp;
|
||||
resp.address = device.address_uint64();
|
||||
resp.address_type = device.get_address_type();
|
||||
if (!device.get_name().empty())
|
||||
resp.name = device.get_name();
|
||||
resp.rssi = device.get_rssi();
|
||||
@@ -66,20 +52,6 @@ void BluetoothProxy::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Active: %s", YESNO(this->active_));
|
||||
}
|
||||
|
||||
int BluetoothProxy::get_bluetooth_connections_free() {
|
||||
int free = 0;
|
||||
for (auto *connection : this->connections_) {
|
||||
if (connection->address_ == 0) {
|
||||
free++;
|
||||
ESP_LOGV(TAG, "[%d] Free connection", connection->get_connection_index());
|
||||
} else {
|
||||
ESP_LOGV(TAG, "[%d] Used connection by [%s]", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
}
|
||||
}
|
||||
return free;
|
||||
}
|
||||
|
||||
void BluetoothProxy::loop() {
|
||||
if (!api::global_api_server->is_connected()) {
|
||||
for (auto *connection : this->connections_) {
|
||||
@@ -90,87 +62,32 @@ void BluetoothProxy::loop() {
|
||||
return;
|
||||
}
|
||||
for (auto *connection : this->connections_) {
|
||||
if (connection->send_service_ == connection->service_count_) {
|
||||
connection->send_service_ = DONE_SENDING_SERVICES;
|
||||
if (connection->send_service_ == connection->services_.size()) {
|
||||
connection->send_service_ = -1;
|
||||
api::global_api_server->send_bluetooth_gatt_services_done(connection->get_address());
|
||||
if (connection->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE ||
|
||||
connection->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
|
||||
connection->release_services();
|
||||
}
|
||||
} else if (connection->send_service_ >= 0) {
|
||||
esp_gattc_service_elem_t service_result;
|
||||
uint16_t service_count = 1;
|
||||
esp_gatt_status_t service_status =
|
||||
esp_ble_gattc_get_service(connection->get_gattc_if(), connection->get_conn_id(), nullptr, &service_result,
|
||||
&service_count, connection->send_service_);
|
||||
connection->send_service_++;
|
||||
if (service_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service error at offset=%d, status=%d",
|
||||
connection->get_connection_index(), connection->address_str().c_str(), connection->send_service_ - 1,
|
||||
service_status);
|
||||
continue;
|
||||
}
|
||||
if (service_count == 0) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service missing, service_count=%d",
|
||||
connection->get_connection_index(), connection->address_str().c_str(), service_count);
|
||||
continue;
|
||||
}
|
||||
auto &service = connection->services_[connection->send_service_];
|
||||
api::BluetoothGATTGetServicesResponse resp;
|
||||
resp.address = connection->get_address();
|
||||
api::BluetoothGATTService service_resp;
|
||||
service_resp.uuid = get_128bit_uuid_vec(service_result.uuid);
|
||||
service_resp.handle = service_result.start_handle;
|
||||
uint16_t char_offset = 0;
|
||||
esp_gattc_char_elem_t char_result;
|
||||
while (true) { // characteristics
|
||||
uint16_t char_count = 1;
|
||||
esp_gatt_status_t char_status = esp_ble_gattc_get_all_char(
|
||||
connection->get_gattc_if(), connection->get_conn_id(), service_result.start_handle,
|
||||
service_result.end_handle, &char_result, &char_count, char_offset);
|
||||
if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (char_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", connection->get_connection_index(),
|
||||
connection->address_str().c_str(), char_status);
|
||||
break;
|
||||
}
|
||||
if (char_count == 0) {
|
||||
break;
|
||||
}
|
||||
service_resp.uuid = {service->uuid.get_128bit_high(), service->uuid.get_128bit_low()};
|
||||
service_resp.handle = service->start_handle;
|
||||
for (auto &characteristic : service->characteristics) {
|
||||
api::BluetoothGATTCharacteristic characteristic_resp;
|
||||
characteristic_resp.uuid = get_128bit_uuid_vec(char_result.uuid);
|
||||
characteristic_resp.handle = char_result.char_handle;
|
||||
characteristic_resp.properties = char_result.properties;
|
||||
char_offset++;
|
||||
uint16_t desc_offset = 0;
|
||||
esp_gattc_descr_elem_t desc_result;
|
||||
while (true) { // descriptors
|
||||
uint16_t desc_count = 1;
|
||||
esp_gatt_status_t desc_status =
|
||||
esp_ble_gattc_get_all_descr(connection->get_gattc_if(), connection->get_conn_id(),
|
||||
char_result.char_handle, &desc_result, &desc_count, desc_offset);
|
||||
if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (desc_status != ESP_GATT_OK) {
|
||||
ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", connection->get_connection_index(),
|
||||
connection->address_str().c_str(), desc_status);
|
||||
break;
|
||||
}
|
||||
if (desc_count == 0) {
|
||||
break;
|
||||
}
|
||||
characteristic_resp.uuid = {characteristic->uuid.get_128bit_high(), characteristic->uuid.get_128bit_low()};
|
||||
characteristic_resp.handle = characteristic->handle;
|
||||
characteristic_resp.properties = characteristic->properties;
|
||||
for (auto &descriptor : characteristic->descriptors) {
|
||||
api::BluetoothGATTDescriptor descriptor_resp;
|
||||
descriptor_resp.uuid = get_128bit_uuid_vec(desc_result.uuid);
|
||||
descriptor_resp.handle = desc_result.handle;
|
||||
descriptor_resp.uuid = {descriptor->uuid.get_128bit_high(), descriptor->uuid.get_128bit_low()};
|
||||
descriptor_resp.handle = descriptor->handle;
|
||||
characteristic_resp.descriptors.push_back(std::move(descriptor_resp));
|
||||
desc_offset++;
|
||||
}
|
||||
service_resp.characteristics.push_back(std::move(characteristic_resp));
|
||||
}
|
||||
resp.services.push_back(std::move(service_resp));
|
||||
api::global_api_server->send_bluetooth_gatt_services(resp);
|
||||
connection->send_service_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,13 +103,7 @@ BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool rese
|
||||
|
||||
for (auto *connection : this->connections_) {
|
||||
if (connection->get_address() == 0) {
|
||||
connection->send_service_ = DONE_SENDING_SERVICES;
|
||||
connection->set_address(address);
|
||||
// All connections must start at INIT
|
||||
// We only set the state if we allocate the connection
|
||||
// to avoid a race where multiple connection attempts
|
||||
// are made.
|
||||
connection->set_state(espbt::ClientState::INIT);
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
@@ -202,8 +113,6 @@ BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool rese
|
||||
|
||||
void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest &msg) {
|
||||
switch (msg.request_type) {
|
||||
case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE:
|
||||
case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE:
|
||||
case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT: {
|
||||
auto *connection = this->get_connection_(msg.address, true);
|
||||
if (connection == nullptr) {
|
||||
@@ -211,63 +120,9 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
|
||||
api::global_api_server->send_bluetooth_device_connection(msg.address, false);
|
||||
return;
|
||||
}
|
||||
if (connection->state() == espbt::ClientState::CONNECTED ||
|
||||
connection->state() == espbt::ClientState::ESTABLISHED) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection already established", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
api::global_api_server->send_bluetooth_device_connection(msg.address, true);
|
||||
api::global_api_server->send_bluetooth_connections_free(this->get_bluetooth_connections_free(),
|
||||
this->get_bluetooth_connections_limit());
|
||||
return;
|
||||
} else if (connection->state() == espbt::ClientState::SEARCHING) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, already searching for device",
|
||||
connection->get_connection_index(), connection->address_str().c_str());
|
||||
return;
|
||||
} else if (connection->state() == espbt::ClientState::DISCOVERED) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, device already discovered",
|
||||
connection->get_connection_index(), connection->address_str().c_str());
|
||||
return;
|
||||
} else if (connection->state() == espbt::ClientState::READY_TO_CONNECT) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, waiting in line to connect",
|
||||
connection->get_connection_index(), connection->address_str().c_str());
|
||||
return;
|
||||
} else if (connection->state() == espbt::ClientState::CONNECTING) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, already connecting", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
return;
|
||||
} else if (connection->state() == espbt::ClientState::DISCONNECTING) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, device is disconnecting",
|
||||
connection->get_connection_index(), connection->address_str().c_str());
|
||||
return;
|
||||
} else if (connection->state() != espbt::ClientState::INIT) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection already in progress", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
return;
|
||||
}
|
||||
if (msg.request_type == api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE) {
|
||||
connection->set_connection_type(espbt::ConnectionType::V3_WITH_CACHE);
|
||||
ESP_LOGI(TAG, "[%d] [%s] Connecting v3 with cache", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
} else if (msg.request_type == api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE) {
|
||||
connection->set_connection_type(espbt::ConnectionType::V3_WITHOUT_CACHE);
|
||||
ESP_LOGI(TAG, "[%d] [%s] Connecting v3 without cache", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
} else {
|
||||
connection->set_connection_type(espbt::ConnectionType::V1);
|
||||
ESP_LOGI(TAG, "[%d] [%s] Connecting v1", connection->get_connection_index(), connection->address_str().c_str());
|
||||
}
|
||||
if (msg.has_address_type) {
|
||||
connection->remote_bda_[0] = (msg.address >> 40) & 0xFF;
|
||||
connection->remote_bda_[1] = (msg.address >> 32) & 0xFF;
|
||||
connection->remote_bda_[2] = (msg.address >> 24) & 0xFF;
|
||||
connection->remote_bda_[3] = (msg.address >> 16) & 0xFF;
|
||||
connection->remote_bda_[4] = (msg.address >> 8) & 0xFF;
|
||||
connection->remote_bda_[5] = (msg.address >> 0) & 0xFF;
|
||||
connection->set_remote_addr_type(static_cast<esp_ble_addr_type_t>(msg.address_type));
|
||||
connection->set_state(espbt::ClientState::DISCOVERED);
|
||||
} else {
|
||||
connection->set_state(espbt::ClientState::SEARCHING);
|
||||
}
|
||||
ESP_LOGV(TAG, "[%d] [%s] Searching to connect", connection->get_connection_index(),
|
||||
connection->address_str().c_str());
|
||||
connection->set_state(espbt::ClientState::SEARCHING);
|
||||
api::global_api_server->send_bluetooth_connections_free(this->get_bluetooth_connections_free(),
|
||||
this->get_bluetooth_connections_limit());
|
||||
break;
|
||||
@@ -346,7 +201,7 @@ void BluetoothProxy::bluetooth_gatt_write_descriptor(const api::BluetoothGATTWri
|
||||
return;
|
||||
}
|
||||
|
||||
auto err = connection->write_descriptor(msg.handle, msg.data, true);
|
||||
auto err = connection->write_descriptor(msg.handle, msg.data);
|
||||
if (err != ESP_OK) {
|
||||
api::global_api_server->send_bluetooth_gatt_error(msg.address, msg.handle, err);
|
||||
}
|
||||
@@ -359,13 +214,12 @@ void BluetoothProxy::bluetooth_gatt_send_services(const api::BluetoothGATTGetSer
|
||||
api::global_api_server->send_bluetooth_gatt_error(msg.address, 0, ESP_GATT_NOT_CONNECTED);
|
||||
return;
|
||||
}
|
||||
if (!connection->service_count_) {
|
||||
if (connection->services_.empty()) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] No GATT services found", connection->connection_index_, connection->address_str().c_str());
|
||||
api::global_api_server->send_bluetooth_gatt_services_done(msg.address);
|
||||
return;
|
||||
}
|
||||
if (connection->send_service_ ==
|
||||
DONE_SENDING_SERVICES) // Only start sending services if we're not already sending them
|
||||
if (connection->send_service_ == -1) // Don't start sending services again if we're already sending them
|
||||
connection->send_service_ = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/api/api_pb2.h"
|
||||
#include "esphome/components/esp32_ble_client/ble_client_base.h"
|
||||
@@ -41,7 +40,15 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
||||
void bluetooth_gatt_send_services(const api::BluetoothGATTGetServicesRequest &msg);
|
||||
void bluetooth_gatt_notify(const api::BluetoothGATTNotifyRequest &msg);
|
||||
|
||||
int get_bluetooth_connections_free();
|
||||
int get_bluetooth_connections_free() {
|
||||
int free = 0;
|
||||
for (auto *connection : this->connections_) {
|
||||
if (connection->address_ == 0) {
|
||||
free++;
|
||||
}
|
||||
}
|
||||
return free;
|
||||
}
|
||||
int get_bluetooth_connections_limit() { return this->connections_.size(); }
|
||||
|
||||
void set_active(bool active) { this->active_ = active; }
|
||||
@@ -52,6 +59,7 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
||||
|
||||
BluetoothConnection *get_connection_(uint64_t address, bool reserve);
|
||||
|
||||
int16_t send_service_{-1};
|
||||
bool active_;
|
||||
|
||||
std::vector<BluetoothConnection *> connections_{};
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/optional.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace canbus {
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace cap1188 {
|
||||
|
||||
|
||||
@@ -540,15 +540,12 @@ void Climate::dump_traits_(const char *tag) {
|
||||
ESP_LOGCONFIG(tag, " - Min: %.1f", traits.get_visual_min_temperature());
|
||||
ESP_LOGCONFIG(tag, " - Max: %.1f", traits.get_visual_max_temperature());
|
||||
ESP_LOGCONFIG(tag, " - Step: %.1f", traits.get_visual_temperature_step());
|
||||
if (traits.get_supports_current_temperature()) {
|
||||
if (traits.get_supports_current_temperature())
|
||||
ESP_LOGCONFIG(tag, " [x] Supports current temperature");
|
||||
}
|
||||
if (traits.get_supports_two_point_target_temperature()) {
|
||||
if (traits.get_supports_two_point_target_temperature())
|
||||
ESP_LOGCONFIG(tag, " [x] Supports two-point target temperature");
|
||||
}
|
||||
if (traits.get_supports_action()) {
|
||||
if (traits.get_supports_action())
|
||||
ESP_LOGCONFIG(tag, " [x] Supports action");
|
||||
}
|
||||
if (!traits.get_supported_modes().empty()) {
|
||||
ESP_LOGCONFIG(tag, " [x] Supported modes:");
|
||||
for (ClimateMode m : traits.get_supported_modes())
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/climate/climate.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#include "esphome/components/cover/cover.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/light/light_output.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom {
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/application.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace custom_component {
|
||||
|
||||
|
||||
@@ -29,9 +29,8 @@ void DAC7678Output::setup() {
|
||||
ESP_LOGE(TAG, "Reset failed");
|
||||
this->mark_failed();
|
||||
return;
|
||||
} else {
|
||||
} else
|
||||
ESP_LOGV(TAG, "Reset succeeded");
|
||||
}
|
||||
|
||||
delayMicroseconds(1000);
|
||||
|
||||
@@ -41,18 +40,16 @@ void DAC7678Output::setup() {
|
||||
ESP_LOGE(TAG, "Set internal reference failed");
|
||||
this->mark_failed();
|
||||
return;
|
||||
} else {
|
||||
} else
|
||||
ESP_LOGV(TAG, "Internal reference enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DAC7678Output::dump_config() {
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "Setting up DAC7678 failed!");
|
||||
} else {
|
||||
} else
|
||||
ESP_LOGCONFIG(TAG, "DAC7678 initialised");
|
||||
}
|
||||
}
|
||||
|
||||
void DAC7678Output::register_channel(DAC7678Channel *channel) {
|
||||
|
||||
@@ -251,7 +251,7 @@ bool DallasTemperatureSensor::check_scratch_pad() {
|
||||
config_validity = ((this->scratch_pad_[4] & 0x10) == 0x10);
|
||||
}
|
||||
|
||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||
#ifdef ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
||||
ESP_LOGVV(TAG, "Scratch pad: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X (%02X)", this->scratch_pad_[0],
|
||||
this->scratch_pad_[1], this->scratch_pad_[2], this->scratch_pad_[3], this->scratch_pad_[4],
|
||||
this->scratch_pad_[5], this->scratch_pad_[6], this->scratch_pad_[7], this->scratch_pad_[8],
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esp_one_wire.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace dallas {
|
||||
|
||||
|
||||
@@ -85,7 +85,9 @@ bool HOT IRAM_ATTR ESPOneWire::read_bit() {
|
||||
// whereas on esp-idf it already happens during the pin_mode(OUTPUT)
|
||||
// manually correct for this with these constants.
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
||||
uint32_t timing_constant = 14;
|
||||
#elif defined(USE_ESP32_FRAMEWORK_ESP_IDF)
|
||||
uint32_t timing_constant = 12;
|
||||
#else
|
||||
uint32_t timing_constant = 14;
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace daly_bms {
|
||||
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
import esphome.final_validate as fv
|
||||
from esphome.components import logger
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import (
|
||||
CONF_BLOCK,
|
||||
CONF_DEVICE,
|
||||
CONF_FRAGMENTATION,
|
||||
CONF_FREE,
|
||||
CONF_ID,
|
||||
CONF_LEVEL,
|
||||
CONF_LOGGER,
|
||||
CONF_DEVICE,
|
||||
CONF_FREE,
|
||||
CONF_FRAGMENTATION,
|
||||
CONF_BLOCK,
|
||||
CONF_LOOP_TIME,
|
||||
)
|
||||
|
||||
@@ -43,18 +39,6 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
|
||||
|
||||
def _final_validate(_):
|
||||
logger_conf = fv.full_config.get()[CONF_LOGGER]
|
||||
severity = logger.LOG_LEVEL_SEVERITY.index(logger_conf[CONF_LEVEL])
|
||||
if severity < logger.LOG_LEVEL_SEVERITY.index("DEBUG"):
|
||||
raise cv.Invalid(
|
||||
"The debug component requires the logger to be at least at DEBUG level"
|
||||
)
|
||||
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = _final_validate
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
@@ -38,9 +38,14 @@ static uint32_t get_free_heap() {
|
||||
|
||||
void DebugComponent::dump_config() {
|
||||
std::string device_info;
|
||||
std::string reset_reason;
|
||||
device_info.reserve(256);
|
||||
|
||||
#ifndef ESPHOME_LOG_HAS_DEBUG
|
||||
ESP_LOGE(TAG, "Debug Component requires debug log level!");
|
||||
this->status_set_error();
|
||||
return;
|
||||
#endif
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Debug component:");
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
LOG_TEXT_SENSOR(" ", "Device info", this->device_info_);
|
||||
@@ -141,6 +146,7 @@ void DebugComponent::dump_config() {
|
||||
device_info += "|EFuse MAC: ";
|
||||
device_info += mac;
|
||||
|
||||
const char *reset_reason;
|
||||
switch (rtc_get_reset_reason(0)) {
|
||||
case POWERON_RESET:
|
||||
reset_reason = "Power On Reset";
|
||||
@@ -190,7 +196,7 @@ void DebugComponent::dump_config() {
|
||||
default:
|
||||
reset_reason = "Unknown Reset Reason";
|
||||
}
|
||||
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason);
|
||||
device_info += "|Reset: ";
|
||||
device_info += reset_reason;
|
||||
|
||||
@@ -264,8 +270,6 @@ void DebugComponent::dump_config() {
|
||||
device_info += ESP.getResetReason().c_str();
|
||||
device_info += "|";
|
||||
device_info += ESP.getResetInfo().c_str();
|
||||
|
||||
reset_reason = ESP.getResetReason().c_str();
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
@@ -274,9 +278,6 @@ void DebugComponent::dump_config() {
|
||||
device_info.resize(255);
|
||||
this->device_info_->publish_state(device_info);
|
||||
}
|
||||
if (this->reset_reason_ != nullptr) {
|
||||
this->reset_reason_->publish_state(reset_reason);
|
||||
}
|
||||
#endif // USE_TEXT_SENSOR
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ class DebugComponent : public PollingComponent {
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void set_device_info_sensor(text_sensor::TextSensor *device_info) { device_info_ = device_info; }
|
||||
void set_reset_reason_sensor(text_sensor::TextSensor *reset_reason) { reset_reason_ = reset_reason; }
|
||||
#endif // USE_TEXT_SENSOR
|
||||
#ifdef USE_SENSOR
|
||||
void set_free_sensor(sensor::Sensor *free_sensor) { free_sensor_ = free_sensor; }
|
||||
@@ -51,7 +50,6 @@ class DebugComponent : public PollingComponent {
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
text_sensor::TextSensor *device_info_{nullptr};
|
||||
text_sensor::TextSensor *reset_reason_{nullptr};
|
||||
#endif // USE_TEXT_SENSOR
|
||||
};
|
||||
|
||||
|
||||
@@ -1,29 +1,18 @@
|
||||
from esphome.components import text_sensor
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import (
|
||||
CONF_DEVICE,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
ICON_CHIP,
|
||||
ICON_RESTART,
|
||||
)
|
||||
from esphome.const import CONF_DEVICE, ENTITY_CATEGORY_DIAGNOSTIC
|
||||
|
||||
from . import CONF_DEBUG_ID, DebugComponent
|
||||
|
||||
DEPENDENCIES = ["debug"]
|
||||
|
||||
|
||||
CONF_RESET_REASON = "reset_reason"
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_DEBUG_ID): cv.use_id(DebugComponent),
|
||||
cv.Optional(CONF_DEVICE): text_sensor.text_sensor_schema(
|
||||
icon=ICON_CHIP,
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
),
|
||||
cv.Optional(CONF_RESET_REASON): text_sensor.text_sensor_schema(
|
||||
icon=ICON_RESTART,
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC
|
||||
),
|
||||
}
|
||||
)
|
||||
@@ -35,6 +24,3 @@ async def to_code(config):
|
||||
if CONF_DEVICE in config:
|
||||
sens = await text_sensor.new_text_sensor(config[CONF_DEVICE])
|
||||
cg.add(debug_component.set_device_info_sensor(sens))
|
||||
if CONF_RESET_REASON in config:
|
||||
sens = await text_sensor.new_text_sensor(config[CONF_RESET_REASON])
|
||||
cg.add(debug_component.set_reset_reason_sensor(sens))
|
||||
|
||||
@@ -114,9 +114,9 @@ void DeepSleepComponent::begin_sleep(bool manual) {
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Beginning Deep Sleep");
|
||||
if (this->sleep_duration_.has_value()) {
|
||||
if (this->sleep_duration_.has_value())
|
||||
ESP_LOGI(TAG, "Sleeping for %" PRId64 "us", *this->sleep_duration_);
|
||||
}
|
||||
|
||||
App.run_safe_shutdown_hooks();
|
||||
|
||||
#if defined(USE_ESP32)
|
||||
|
||||
@@ -77,16 +77,14 @@ void DFPlayer::loop() {
|
||||
case 0x3A:
|
||||
if (argument == 1) {
|
||||
ESP_LOGI(TAG, "USB loaded");
|
||||
} else if (argument == 2) {
|
||||
} else if (argument == 2)
|
||||
ESP_LOGI(TAG, "TF Card loaded");
|
||||
}
|
||||
break;
|
||||
case 0x3B:
|
||||
if (argument == 1) {
|
||||
ESP_LOGI(TAG, "USB unloaded");
|
||||
} else if (argument == 2) {
|
||||
} else if (argument == 2)
|
||||
ESP_LOGI(TAG, "TF Card unloaded");
|
||||
}
|
||||
break;
|
||||
case 0x3F:
|
||||
if (argument == 1) {
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "display_color_utils.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_TIME
|
||||
#include "esphome/components/time/real_time_clock.h"
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <dsmr/parser.h>
|
||||
#include <dsmr/fields.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace dsmr {
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace ektf2232 {
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import esphome.config_validation as cv
|
||||
|
||||
from esphome import pins
|
||||
from esphome.components import i2c, touchscreen
|
||||
from esphome.const import CONF_ID, CONF_INTERRUPT_PIN
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
@@ -17,8 +17,10 @@ EKTF2232Touchscreen = ektf2232_ns.class_(
|
||||
)
|
||||
|
||||
CONF_EKTF2232_ID = "ektf2232_id"
|
||||
CONF_INTERRUPT_PIN = "interrupt_pin"
|
||||
CONF_RTS_PIN = "rts_pin"
|
||||
|
||||
|
||||
CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
|
||||
cv.Schema(
|
||||
{
|
||||
|
||||
@@ -129,27 +129,27 @@ def _format_framework_espidf_version(ver: cv.Version) -> str:
|
||||
# The default/recommended arduino framework version
|
||||
# - https://github.com/espressif/arduino-esp32/releases
|
||||
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif32
|
||||
RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(2, 0, 5)
|
||||
RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(1, 0, 6)
|
||||
# The platformio/espressif32 version to use for arduino frameworks
|
||||
# - https://github.com/platformio/platform-espressif32/releases
|
||||
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
|
||||
ARDUINO_PLATFORM_VERSION = cv.Version(5, 2, 0)
|
||||
ARDUINO_PLATFORM_VERSION = cv.Version(3, 5, 0)
|
||||
|
||||
# The default/recommended esp-idf framework version
|
||||
# - https://github.com/espressif/esp-idf/releases
|
||||
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
|
||||
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 4, 2)
|
||||
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 3, 2)
|
||||
# The platformio/espressif32 version to use for esp-idf frameworks
|
||||
# - https://github.com/platformio/platform-espressif32/releases
|
||||
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
|
||||
ESP_IDF_PLATFORM_VERSION = cv.Version(5, 2, 0)
|
||||
ESP_IDF_PLATFORM_VERSION = cv.Version(3, 5, 0)
|
||||
|
||||
|
||||
def _arduino_check_versions(value):
|
||||
value = value.copy()
|
||||
lookups = {
|
||||
"dev": (cv.Version(2, 0, 5), "https://github.com/espressif/arduino-esp32.git"),
|
||||
"latest": (cv.Version(2, 0, 5), None),
|
||||
"dev": (cv.Version(2, 0, 0), "https://github.com/espressif/arduino-esp32.git"),
|
||||
"latest": (cv.Version(1, 0, 6), None),
|
||||
"recommended": (RECOMMENDED_ARDUINO_FRAMEWORK_VERSION, None),
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ def _esp_idf_check_versions(value):
|
||||
value = value.copy()
|
||||
lookups = {
|
||||
"dev": (cv.Version(5, 0, 0), "https://github.com/espressif/esp-idf.git"),
|
||||
"latest": (cv.Version(4, 4, 2), None),
|
||||
"latest": (cv.Version(4, 3, 2), None),
|
||||
"recommended": (RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION, None),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .const import VARIANT_ESP32, VARIANT_ESP32S2, VARIANT_ESP32C3, VARIANT_ESP32S3
|
||||
from .const import VARIANT_ESP32, VARIANT_ESP32S2, VARIANT_ESP32C3
|
||||
|
||||
ESP32_BASE_PINS = {
|
||||
"TX": 1,
|
||||
@@ -42,64 +42,6 @@ ESP32_BASE_PINS = {
|
||||
}
|
||||
|
||||
ESP32_BOARD_PINS = {
|
||||
"adafruit_qtpy_esp32c3": {
|
||||
"A0": 4,
|
||||
"A1": 3,
|
||||
"A2": 1,
|
||||
"A3": 0,
|
||||
"SDA": 5,
|
||||
"SCL": 6,
|
||||
"MOSI": 7,
|
||||
"MISO": 8,
|
||||
"SCK": 10,
|
||||
"RX": 20,
|
||||
"TX": 21,
|
||||
"NEOPIXEL": 2,
|
||||
"PIN_NEOPIXEL": 2,
|
||||
"BUTTON": 9,
|
||||
"SWITCH": 9,
|
||||
},
|
||||
"adafruit_qtpy_esp32s2": {
|
||||
"A0": 18,
|
||||
"A1": 17,
|
||||
"A2": 9,
|
||||
"A3": 8,
|
||||
"SDA": 7,
|
||||
"SCL": 6,
|
||||
"MOSI": 35,
|
||||
"MISO": 37,
|
||||
"SCK": 36,
|
||||
"RX": 16,
|
||||
"TX": 5,
|
||||
"SDA1": 41,
|
||||
"SCL1": 40,
|
||||
"NEOPIXEL": 39,
|
||||
"PIN_NEOPIXEL": 39,
|
||||
"NEOPIXEL_POWER": 38,
|
||||
"D0": 0,
|
||||
"BUTTON": 0,
|
||||
"SWITCH": 0,
|
||||
},
|
||||
"adafruit_qtpy_esp32": {
|
||||
"A0": 26,
|
||||
"A1": 25,
|
||||
"A2": 27,
|
||||
"A3": 15,
|
||||
"SDA": 4,
|
||||
"SCL": 33,
|
||||
"MOSI": 13,
|
||||
"MISO": 12,
|
||||
"SCK": 14,
|
||||
"RX": 7,
|
||||
"TX": 32,
|
||||
"SDA1": 22,
|
||||
"SCL1": 19,
|
||||
"NEOPIXEL": 5,
|
||||
"PIN_NEOPIXEL": 5,
|
||||
"NEOPIXEL_POWER": 8,
|
||||
"BUTTON": 0,
|
||||
"SWITCH": 0,
|
||||
},
|
||||
"alksesp32": {
|
||||
"A0": 32,
|
||||
"A1": 33,
|
||||
@@ -608,25 +550,6 @@ ESP32_BOARD_PINS = {
|
||||
},
|
||||
"lolin_d32": {"LED": 5, "_VBAT": 35},
|
||||
"lolin_d32_pro": {"LED": 5, "_VBAT": 35},
|
||||
"lolin_s2_mini": {
|
||||
"TX": 43,
|
||||
"RX": 44,
|
||||
"SPICS1": 29,
|
||||
"SPIHD": 31,
|
||||
"SPIWP": 32,
|
||||
"SPICS0": 33,
|
||||
"SPICLK": 34,
|
||||
"SPIQ": 35,
|
||||
"SPID": 36,
|
||||
"MISO": 9,
|
||||
"MOSI": 11,
|
||||
"SCK": 7,
|
||||
"SCL": 35,
|
||||
"SDA": 33,
|
||||
"DAC1": 17,
|
||||
"DAC2": 18,
|
||||
"LED": 15,
|
||||
},
|
||||
"lopy": {
|
||||
"A1": 37,
|
||||
"A2": 38,
|
||||
@@ -1061,8 +984,6 @@ ESP32_BOARD_PINS = {
|
||||
"D13": 2,
|
||||
},
|
||||
"xinabox_cw02": {"LED": 27},
|
||||
"upesy_wroom": {"LED": 2},
|
||||
"upesy_wrover": {"LED": 2},
|
||||
}
|
||||
|
||||
"""
|
||||
@@ -1079,42 +1000,12 @@ done | sort
|
||||
"""
|
||||
|
||||
BOARD_TO_VARIANT = {
|
||||
"adafruit_feather_esp32s2_tft": VARIANT_ESP32S2,
|
||||
"adafruit_feather_esp32s3_nopsram": VARIANT_ESP32S3,
|
||||
"adafruit_feather_esp32s3_tft": VARIANT_ESP32S3,
|
||||
"adafruit_feather_esp32s3": VARIANT_ESP32S3,
|
||||
"adafruit_feather_esp32_v2": VARIANT_ESP32,
|
||||
"adafruit_funhouse_esp32s2": VARIANT_ESP32S2,
|
||||
"adafruit_itsybitsy_esp32": VARIANT_ESP32,
|
||||
"adafruit_magtag29_esp32s2": VARIANT_ESP32S2,
|
||||
"adafruit_metro_esp32s2": VARIANT_ESP32S2,
|
||||
"adafruit_qtpy_esp32c3": VARIANT_ESP32C3,
|
||||
"adafruit_qtpy_esp32s2": VARIANT_ESP32S2,
|
||||
"adafruit_qtpy_esp32s3_nopsram": VARIANT_ESP32S3,
|
||||
"adafruit_qtpy_esp32": VARIANT_ESP32,
|
||||
"airm2m_core_esp32c3": VARIANT_ESP32C3,
|
||||
"alksesp32": VARIANT_ESP32,
|
||||
"atmegazero_esp32s2": VARIANT_ESP32S2,
|
||||
"az-delivery-devkit-v4": VARIANT_ESP32,
|
||||
"bee_motion_mini": VARIANT_ESP32C3,
|
||||
"bee_motion_s3": VARIANT_ESP32S3,
|
||||
"bee_motion": VARIANT_ESP32S2,
|
||||
"bee_s3": VARIANT_ESP32S3,
|
||||
"bpi-bit": VARIANT_ESP32,
|
||||
"briki_abc_esp32": VARIANT_ESP32,
|
||||
"briki_mbc-wb_esp32": VARIANT_ESP32,
|
||||
"cnrs_aw2eth": VARIANT_ESP32,
|
||||
"connaxio_espoir": VARIANT_ESP32,
|
||||
"d-duino-32": VARIANT_ESP32,
|
||||
"deneyapkart1A": VARIANT_ESP32,
|
||||
"deneyapkartg": VARIANT_ESP32C3,
|
||||
"deneyapkart": VARIANT_ESP32,
|
||||
"deneyapmini": VARIANT_ESP32S2,
|
||||
"denky32": VARIANT_ESP32,
|
||||
"denky_d4": VARIANT_ESP32,
|
||||
"dfrobot_beetle_esp32c3": VARIANT_ESP32C3,
|
||||
"dfrobot_firebeetle2_esp32s3": VARIANT_ESP32S3,
|
||||
"dpu_esp32": VARIANT_ESP32,
|
||||
"esp320": VARIANT_ESP32,
|
||||
"esp32-c3-devkitm-1": VARIANT_ESP32C3,
|
||||
"esp32cam": VARIANT_ESP32,
|
||||
@@ -1127,12 +1018,8 @@ BOARD_TO_VARIANT = {
|
||||
"esp32-poe-iso": VARIANT_ESP32,
|
||||
"esp32-poe": VARIANT_ESP32,
|
||||
"esp32-pro": VARIANT_ESP32,
|
||||
"esp32-s2-franzininho": VARIANT_ESP32S2,
|
||||
"esp32-s2-kaluga-1": VARIANT_ESP32S2,
|
||||
"esp32-s2-saola-1": VARIANT_ESP32S2,
|
||||
"esp32s3box": VARIANT_ESP32S3,
|
||||
"esp32s3camlcd": VARIANT_ESP32S3,
|
||||
"esp32-s3-devkitc-1": VARIANT_ESP32S3,
|
||||
"esp32thing_plus": VARIANT_ESP32,
|
||||
"esp32thing": VARIANT_ESP32,
|
||||
"esp32vn-iot-uno": VARIANT_ESP32,
|
||||
@@ -1145,8 +1032,6 @@ BOARD_TO_VARIANT = {
|
||||
"featheresp32": VARIANT_ESP32,
|
||||
"firebeetle32": VARIANT_ESP32,
|
||||
"fm-devkit": VARIANT_ESP32,
|
||||
"franzininho_wifi_esp32s2": VARIANT_ESP32S2,
|
||||
"franzininho_wifi_msc_esp32s2": VARIANT_ESP32S2,
|
||||
"frogboard": VARIANT_ESP32,
|
||||
"healthypi4": VARIANT_ESP32,
|
||||
"heltec_wifi_kit_32_v2": VARIANT_ESP32,
|
||||
@@ -1164,18 +1049,13 @@ BOARD_TO_VARIANT = {
|
||||
"iotaap_magnolia": VARIANT_ESP32,
|
||||
"iotbusio": VARIANT_ESP32,
|
||||
"iotbusproteus": VARIANT_ESP32,
|
||||
"kb32-ft": VARIANT_ESP32,
|
||||
"kits-edu": VARIANT_ESP32,
|
||||
"labplus_mpython": VARIANT_ESP32,
|
||||
"lionbit": VARIANT_ESP32,
|
||||
"lolin32_lite": VARIANT_ESP32,
|
||||
"lolin32": VARIANT_ESP32,
|
||||
"lolin_c3_mini": VARIANT_ESP32C3,
|
||||
"lolin_d32_pro": VARIANT_ESP32,
|
||||
"lolin_d32": VARIANT_ESP32,
|
||||
"lolin_s2_mini": VARIANT_ESP32S2,
|
||||
"lolin_s2_pico": VARIANT_ESP32S2,
|
||||
"lolin_s3": VARIANT_ESP32S3,
|
||||
"lopy4": VARIANT_ESP32,
|
||||
"lopy": VARIANT_ESP32,
|
||||
"m5stack-atom": VARIANT_ESP32,
|
||||
@@ -1184,7 +1064,6 @@ BOARD_TO_VARIANT = {
|
||||
"m5stack-coreink": VARIANT_ESP32,
|
||||
"m5stack-fire": VARIANT_ESP32,
|
||||
"m5stack-grey": VARIANT_ESP32,
|
||||
"m5stack-station": VARIANT_ESP32,
|
||||
"m5stack-timer-cam": VARIANT_ESP32,
|
||||
"m5stick-c": VARIANT_ESP32,
|
||||
"magicbit": VARIANT_ESP32,
|
||||
@@ -1193,12 +1072,9 @@ BOARD_TO_VARIANT = {
|
||||
"mhetesp32devkit": VARIANT_ESP32,
|
||||
"mhetesp32minikit": VARIANT_ESP32,
|
||||
"microduino-core-esp32": VARIANT_ESP32,
|
||||
"micros2": VARIANT_ESP32S2,
|
||||
"minimain_esp32s2": VARIANT_ESP32S2,
|
||||
"nano32": VARIANT_ESP32,
|
||||
"nina_w10": VARIANT_ESP32,
|
||||
"node32s": VARIANT_ESP32,
|
||||
"nodemcu-32s2": VARIANT_ESP32S2,
|
||||
"nodemcu-32s": VARIANT_ESP32,
|
||||
"nscreen-32": VARIANT_ESP32,
|
||||
"odroid_esp32": VARIANT_ESP32,
|
||||
@@ -1210,20 +1086,11 @@ BOARD_TO_VARIANT = {
|
||||
"pycom_gpy": VARIANT_ESP32,
|
||||
"qchip": VARIANT_ESP32,
|
||||
"quantum": VARIANT_ESP32,
|
||||
"seeed_xiao_esp32c3": VARIANT_ESP32C3,
|
||||
"sensesiot_weizen": VARIANT_ESP32,
|
||||
"sg-o_airMon": VARIANT_ESP32,
|
||||
"s_odi_ultra": VARIANT_ESP32,
|
||||
"sparkfun_esp32_iot_redboard": VARIANT_ESP32,
|
||||
"sparkfun_esp32micromod": VARIANT_ESP32,
|
||||
"sparkfun_esp32s2_thing_plus_c": VARIANT_ESP32,
|
||||
"sparkfun_esp32s2_thing_plus": VARIANT_ESP32S2,
|
||||
"sparkfun_lora_gateway_1-channel": VARIANT_ESP32,
|
||||
"tamc_termod_s3": VARIANT_ESP32S3,
|
||||
"tinypico": VARIANT_ESP32,
|
||||
"trueverit-iot-driver-mk2": VARIANT_ESP32,
|
||||
"trueverit-iot-driver-mk3": VARIANT_ESP32,
|
||||
"trueverit-iot-driver": VARIANT_ESP32,
|
||||
"ttgo-lora32-v1": VARIANT_ESP32,
|
||||
"ttgo-lora32-v21": VARIANT_ESP32,
|
||||
"ttgo-lora32-v2": VARIANT_ESP32,
|
||||
@@ -1231,32 +1098,13 @@ BOARD_TO_VARIANT = {
|
||||
"ttgo-t7-v13-mini32": VARIANT_ESP32,
|
||||
"ttgo-t7-v14-mini32": VARIANT_ESP32,
|
||||
"ttgo-t-beam": VARIANT_ESP32,
|
||||
"ttgo-t-oi-plus": VARIANT_ESP32C3,
|
||||
"ttgo-t-watch": VARIANT_ESP32,
|
||||
"turta_iot_node": VARIANT_ESP32,
|
||||
"um_feathers2_neo": VARIANT_ESP32S2,
|
||||
"um_feathers2": VARIANT_ESP32S2,
|
||||
"um_feathers3": VARIANT_ESP32S3,
|
||||
"um_pros3": VARIANT_ESP32S3,
|
||||
"um_rmp": VARIANT_ESP32S2,
|
||||
"um_tinys2": VARIANT_ESP32S2,
|
||||
"um_tinys3": VARIANT_ESP32S3,
|
||||
"unphone7": VARIANT_ESP32,
|
||||
"unphone8": VARIANT_ESP32S3,
|
||||
"unphone9": VARIANT_ESP32S3,
|
||||
"upesy_wroom": VARIANT_ESP32,
|
||||
"upesy_wrover": VARIANT_ESP32,
|
||||
"vintlabs-devkit-v1": VARIANT_ESP32,
|
||||
"watchy": VARIANT_ESP32,
|
||||
"wemosbat": VARIANT_ESP32,
|
||||
"wemos_d1_mini32": VARIANT_ESP32,
|
||||
"wemos_d1_uno32": VARIANT_ESP32,
|
||||
"wesp32": VARIANT_ESP32,
|
||||
"widora-air": VARIANT_ESP32,
|
||||
"wifiduino32c3": VARIANT_ESP32C3,
|
||||
"wifiduino32s3": VARIANT_ESP32S3,
|
||||
"wifiduino32": VARIANT_ESP32,
|
||||
"wipy3": VARIANT_ESP32,
|
||||
"wt32-eth01": VARIANT_ESP32,
|
||||
"xinabox_cw02": VARIANT_ESP32,
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ from .gpio_esp32_s3 import esp32_s3_validate_gpio_pin, esp32_s3_validate_support
|
||||
from .gpio_esp32_h2 import esp32_h2_validate_gpio_pin, esp32_h2_validate_supports
|
||||
|
||||
|
||||
ESP32InternalGPIOPin = esp32_ns.class_("ESP32InternalGPIOPin", cg.InternalGPIOPin)
|
||||
IDFInternalGPIOPin = esp32_ns.class_("IDFInternalGPIOPin", cg.InternalGPIOPin)
|
||||
ArduinoInternalGPIOPin = esp32_ns.class_("ArduinoInternalGPIOPin", cg.InternalGPIOPin)
|
||||
|
||||
|
||||
def _lookup_pin(value):
|
||||
@@ -172,10 +173,18 @@ DRIVE_STRENGTHS = {
|
||||
gpio_num_t = cg.global_ns.enum("gpio_num_t")
|
||||
|
||||
|
||||
def _choose_pin_declaration(value):
|
||||
if CORE.using_esp_idf:
|
||||
return cv.declare_id(IDFInternalGPIOPin)(value)
|
||||
if CORE.using_arduino:
|
||||
return cv.declare_id(ArduinoInternalGPIOPin)(value)
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
CONF_DRIVE_STRENGTH = "drive_strength"
|
||||
ESP32_PIN_SCHEMA = cv.All(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32InternalGPIOPin),
|
||||
cv.GenerateID(): _choose_pin_declaration,
|
||||
cv.Required(CONF_NUMBER): validate_gpio_pin,
|
||||
cv.Optional(CONF_MODE, default={}): cv.Schema(
|
||||
{
|
||||
@@ -187,7 +196,8 @@ ESP32_PIN_SCHEMA = cv.All(
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
cv.Optional(CONF_DRIVE_STRENGTH, default="20mA"): cv.All(
|
||||
cv.SplitDefault(CONF_DRIVE_STRENGTH, esp32_idf="20mA"): cv.All(
|
||||
cv.only_with_esp_idf,
|
||||
cv.float_with_unit("current", "mA", optional_unit=True),
|
||||
cv.enum(DRIVE_STRENGTHS),
|
||||
),
|
||||
@@ -200,7 +210,10 @@ ESP32_PIN_SCHEMA = cv.All(
|
||||
async def esp32_pin_to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(getattr(gpio_num_t, f"GPIO_NUM_{num}")))
|
||||
if CORE.using_esp_idf:
|
||||
cg.add(var.set_pin(getattr(gpio_num_t, f"GPIO_NUM_{num}")))
|
||||
else:
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
if CONF_DRIVE_STRENGTH in config:
|
||||
cg.add(var.set_drive_strength(config[CONF_DRIVE_STRENGTH]))
|
||||
|
||||
114
esphome/components/esp32/gpio_arduino.cpp
Normal file
114
esphome/components/esp32/gpio_arduino.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
||||
|
||||
#include "gpio_arduino.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <esp32-hal-gpio.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32 {
|
||||
|
||||
static const char *const TAG = "esp32";
|
||||
|
||||
static int IRAM_ATTR flags_to_mode(gpio::Flags flags) {
|
||||
if (flags == gpio::FLAG_INPUT) {
|
||||
return INPUT;
|
||||
} else if (flags == gpio::FLAG_OUTPUT) {
|
||||
return OUTPUT;
|
||||
} else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
|
||||
return INPUT_PULLUP;
|
||||
} else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLDOWN)) {
|
||||
return INPUT_PULLDOWN;
|
||||
} else if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) {
|
||||
return OUTPUT_OPEN_DRAIN;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct ISRPinArg {
|
||||
uint8_t pin;
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
ISRInternalGPIOPin ArduinoInternalGPIOPin::to_isr() const {
|
||||
auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
arg->pin = pin_;
|
||||
arg->inverted = inverted_;
|
||||
return ISRInternalGPIOPin((void *) arg);
|
||||
}
|
||||
|
||||
void ArduinoInternalGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const {
|
||||
uint8_t arduino_mode = DISABLED;
|
||||
switch (type) {
|
||||
case gpio::INTERRUPT_RISING_EDGE:
|
||||
arduino_mode = inverted_ ? FALLING : RISING;
|
||||
break;
|
||||
case gpio::INTERRUPT_FALLING_EDGE:
|
||||
arduino_mode = inverted_ ? RISING : FALLING;
|
||||
break;
|
||||
case gpio::INTERRUPT_ANY_EDGE:
|
||||
arduino_mode = CHANGE;
|
||||
break;
|
||||
case gpio::INTERRUPT_LOW_LEVEL:
|
||||
arduino_mode = inverted_ ? ONHIGH : ONLOW;
|
||||
break;
|
||||
case gpio::INTERRUPT_HIGH_LEVEL:
|
||||
arduino_mode = inverted_ ? ONLOW : ONHIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
attachInterruptArg(pin_, func, arg, arduino_mode);
|
||||
}
|
||||
|
||||
void ArduinoInternalGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
pinMode(pin_, flags_to_mode(flags)); // NOLINT
|
||||
}
|
||||
|
||||
std::string ArduinoInternalGPIOPin::dump_summary() const {
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "GPIO%u", pin_);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool ArduinoInternalGPIOPin::digital_read() {
|
||||
return bool(digitalRead(pin_)) != inverted_; // NOLINT
|
||||
}
|
||||
void ArduinoInternalGPIOPin::digital_write(bool value) {
|
||||
digitalWrite(pin_, value != inverted_ ? 1 : 0); // NOLINT
|
||||
}
|
||||
void ArduinoInternalGPIOPin::detach_interrupt() const {
|
||||
detachInterrupt(pin_); // NOLINT
|
||||
}
|
||||
|
||||
} // namespace esp32
|
||||
|
||||
using namespace esp32;
|
||||
|
||||
bool IRAM_ATTR ISRInternalGPIOPin::digital_read() {
|
||||
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
|
||||
return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT
|
||||
}
|
||||
void IRAM_ATTR ISRInternalGPIOPin::digital_write(bool value) {
|
||||
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
|
||||
digitalWrite(arg->pin, value != arg->inverted ? 1 : 0); // NOLINT
|
||||
}
|
||||
void IRAM_ATTR ISRInternalGPIOPin::clear_interrupt() {
|
||||
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
GPIO.status_w1tc.val = 1UL << arg->pin;
|
||||
#else
|
||||
if (arg->pin < 32) {
|
||||
GPIO.status_w1tc = 1UL << arg->pin;
|
||||
} else {
|
||||
GPIO.status1_w1tc.intr_st = 1UL << (arg->pin - 32);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
|
||||
pinMode(arg->pin, flags_to_mode(flags)); // NOLINT
|
||||
}
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32_FRAMEWORK_ARDUINO
|
||||
36
esphome/components/esp32/gpio_arduino.h
Normal file
36
esphome/components/esp32/gpio_arduino.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32 {
|
||||
|
||||
class ArduinoInternalGPIOPin : public InternalGPIOPin {
|
||||
public:
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
void setup() override { pin_mode(flags_); }
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
std::string dump_summary() const override;
|
||||
void detach_interrupt() const override;
|
||||
ISRInternalGPIOPin to_isr() const override;
|
||||
uint8_t get_pin() const override { return pin_; }
|
||||
bool is_inverted() const override { return inverted_; }
|
||||
|
||||
protected:
|
||||
void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const override;
|
||||
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
|
||||
} // namespace esp32
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32_FRAMEWORK_ARDUINO
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifdef USE_ESP32
|
||||
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
||||
|
||||
#include "gpio.h"
|
||||
#include "gpio_idf.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
@@ -8,11 +8,13 @@ namespace esp32 {
|
||||
|
||||
static const char *const TAG = "esp32";
|
||||
|
||||
bool ESP32InternalGPIOPin::isr_service_installed = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
bool IDFInternalGPIOPin::isr_service_installed = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
static gpio_mode_t IRAM_ATTR flags_to_mode(gpio::Flags flags) {
|
||||
flags = (gpio::Flags)(flags & ~(gpio::FLAG_PULLUP | gpio::FLAG_PULLDOWN));
|
||||
if (flags == gpio::FLAG_INPUT) {
|
||||
if (flags == gpio::FLAG_NONE) {
|
||||
return GPIO_MODE_DISABLE;
|
||||
} else if (flags == gpio::FLAG_INPUT) {
|
||||
return GPIO_MODE_INPUT;
|
||||
} else if (flags == gpio::FLAG_OUTPUT) {
|
||||
return GPIO_MODE_OUTPUT;
|
||||
@@ -23,7 +25,7 @@ static gpio_mode_t IRAM_ATTR flags_to_mode(gpio::Flags flags) {
|
||||
} else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_OUTPUT)) {
|
||||
return GPIO_MODE_INPUT_OUTPUT;
|
||||
} else {
|
||||
// unsupported or gpio::FLAG_NONE
|
||||
// unsupported
|
||||
return GPIO_MODE_DISABLE;
|
||||
}
|
||||
}
|
||||
@@ -33,14 +35,14 @@ struct ISRPinArg {
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
ISRInternalGPIOPin ESP32InternalGPIOPin::to_isr() const {
|
||||
ISRInternalGPIOPin IDFInternalGPIOPin::to_isr() const {
|
||||
auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
arg->pin = pin_;
|
||||
arg->inverted = inverted_;
|
||||
return ISRInternalGPIOPin((void *) arg);
|
||||
}
|
||||
|
||||
void ESP32InternalGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const {
|
||||
void IDFInternalGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const {
|
||||
gpio_int_type_t idf_type = GPIO_INTR_ANYEDGE;
|
||||
switch (type) {
|
||||
case gpio::INTERRUPT_RISING_EDGE:
|
||||
@@ -72,13 +74,13 @@ void ESP32InternalGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpi
|
||||
gpio_isr_handler_add(pin_, func, arg);
|
||||
}
|
||||
|
||||
std::string ESP32InternalGPIOPin::dump_summary() const {
|
||||
std::string IDFInternalGPIOPin::dump_summary() const {
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "GPIO%u", static_cast<uint32_t>(pin_));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void ESP32InternalGPIOPin::setup() {
|
||||
void IDFInternalGPIOPin::setup() {
|
||||
gpio_config_t conf{};
|
||||
conf.pin_bit_mask = 1ULL << static_cast<uint32_t>(pin_);
|
||||
conf.mode = flags_to_mode(flags_);
|
||||
@@ -86,12 +88,10 @@ void ESP32InternalGPIOPin::setup() {
|
||||
conf.pull_down_en = flags_ & gpio::FLAG_PULLDOWN ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE;
|
||||
conf.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_config(&conf);
|
||||
if (flags_ & gpio::FLAG_OUTPUT) {
|
||||
gpio_set_drive_capability(pin_, drive_strength_);
|
||||
}
|
||||
gpio_set_drive_capability(pin_, drive_strength_);
|
||||
}
|
||||
|
||||
void ESP32InternalGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
void IDFInternalGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
// can't call gpio_config here because that logs in esp-idf which may cause issues
|
||||
gpio_set_direction(pin_, flags_to_mode(flags));
|
||||
gpio_pull_mode_t pull_mode = GPIO_FLOATING;
|
||||
@@ -105,9 +105,9 @@ void ESP32InternalGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
gpio_set_pull_mode(pin_, pull_mode);
|
||||
}
|
||||
|
||||
bool ESP32InternalGPIOPin::digital_read() { return bool(gpio_get_level(pin_)) != inverted_; }
|
||||
void ESP32InternalGPIOPin::digital_write(bool value) { gpio_set_level(pin_, value != inverted_ ? 1 : 0); }
|
||||
void ESP32InternalGPIOPin::detach_interrupt() const { gpio_intr_disable(pin_); }
|
||||
bool IDFInternalGPIOPin::digital_read() { return bool(gpio_get_level(pin_)) != inverted_; }
|
||||
void IDFInternalGPIOPin::digital_write(bool value) { gpio_set_level(pin_, value != inverted_ ? 1 : 0); }
|
||||
void IDFInternalGPIOPin::detach_interrupt() const { gpio_intr_disable(pin_); }
|
||||
|
||||
} // namespace esp32
|
||||
|
||||
@@ -140,4 +140,4 @@ void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
#endif // USE_ESP32_FRAMEWORK_ESP_IDF
|
||||
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
||||
#include "esphome/core/hal.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32 {
|
||||
|
||||
class ESP32InternalGPIOPin : public InternalGPIOPin {
|
||||
class IDFInternalGPIOPin : public InternalGPIOPin {
|
||||
public:
|
||||
void set_pin(gpio_num_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
@@ -37,4 +37,4 @@ class ESP32InternalGPIOPin : public InternalGPIOPin {
|
||||
} // namespace esp32
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
#endif // USE_ESP32_FRAMEWORK_ESP_IDF
|
||||
@@ -16,15 +16,7 @@ BLECharacteristic::~BLECharacteristic() {
|
||||
delete desc; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
}
|
||||
|
||||
void BLECharacteristic::release_descriptors() {
|
||||
this->parsed = false;
|
||||
for (auto &desc : this->descriptors)
|
||||
delete desc; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
this->descriptors.clear();
|
||||
}
|
||||
|
||||
void BLECharacteristic::parse_descriptors() {
|
||||
this->parsed = true;
|
||||
uint16_t offset = 0;
|
||||
esp_gattc_descr_elem_t result;
|
||||
|
||||
@@ -57,8 +49,6 @@ void BLECharacteristic::parse_descriptors() {
|
||||
}
|
||||
|
||||
BLEDescriptor *BLECharacteristic::get_descriptor(espbt::ESPBTUUID uuid) {
|
||||
if (!this->parsed)
|
||||
this->parse_descriptors();
|
||||
for (auto &desc : this->descriptors) {
|
||||
if (desc->uuid == uuid)
|
||||
return desc;
|
||||
@@ -69,8 +59,6 @@ BLEDescriptor *BLECharacteristic::get_descriptor(uint16_t uuid) {
|
||||
return this->get_descriptor(espbt::ESPBTUUID::from_uint16(uuid));
|
||||
}
|
||||
BLEDescriptor *BLECharacteristic::get_descriptor_by_handle(uint16_t handle) {
|
||||
if (!this->parsed)
|
||||
this->parse_descriptors();
|
||||
for (auto &desc : this->descriptors) {
|
||||
if (desc->handle == handle)
|
||||
return desc;
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "ble_descriptor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32_ble_client {
|
||||
|
||||
@@ -18,13 +16,11 @@ class BLEService;
|
||||
class BLECharacteristic {
|
||||
public:
|
||||
~BLECharacteristic();
|
||||
bool parsed = false;
|
||||
espbt::ESPBTUUID uuid;
|
||||
uint16_t handle;
|
||||
esp_gatt_char_prop_t properties;
|
||||
std::vector<BLEDescriptor *> descriptors;
|
||||
void parse_descriptors();
|
||||
void release_descriptors();
|
||||
BLEDescriptor *get_descriptor(espbt::ESPBTUUID uuid);
|
||||
BLEDescriptor *get_descriptor(uint16_t uuid);
|
||||
BLEDescriptor *get_descriptor_by_handle(uint16_t handle);
|
||||
|
||||
@@ -9,13 +9,6 @@ namespace esphome {
|
||||
namespace esp32_ble_client {
|
||||
|
||||
static const char *const TAG = "esp32_ble_client";
|
||||
static const esp_bt_uuid_t NOTIFY_DESC_UUID = {
|
||||
.len = ESP_UUID_LEN_16,
|
||||
.uuid =
|
||||
{
|
||||
.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,
|
||||
},
|
||||
};
|
||||
|
||||
void BLEClientBase::setup() {
|
||||
static uint8_t connection_index = 0;
|
||||
@@ -30,9 +23,7 @@ void BLEClientBase::setup() {
|
||||
}
|
||||
|
||||
void BLEClientBase::loop() {
|
||||
// READY_TO_CONNECT means we have discovered the device
|
||||
// and the scanner has been stopped by the tracker.
|
||||
if (this->state_ == espbt::ClientState::READY_TO_CONNECT) {
|
||||
if (this->state_ == espbt::ClientState::DISCOVERED) {
|
||||
this->connect();
|
||||
}
|
||||
}
|
||||
@@ -60,8 +51,7 @@ bool BLEClientBase::parse_device(const espbt::ESPBTDevice &device) {
|
||||
}
|
||||
|
||||
void BLEClientBase::connect() {
|
||||
ESP_LOGI(TAG, "[%d] [%s] 0x%02x Attempting BLE connection", this->connection_index_, this->address_str_.c_str(),
|
||||
this->remote_addr_type_);
|
||||
ESP_LOGI(TAG, "[%d] [%s] Attempting BLE connection", this->connection_index_, this->address_str_.c_str());
|
||||
auto ret = esp_ble_gattc_open(this->gattc_if_, this->remote_bda_, this->remote_addr_type_, true);
|
||||
if (ret) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_open error, status=%d", this->connection_index_, this->address_str_.c_str(),
|
||||
@@ -73,8 +63,6 @@ void BLEClientBase::connect() {
|
||||
}
|
||||
|
||||
void BLEClientBase::disconnect() {
|
||||
if (this->state_ == espbt::ClientState::IDLE || this->state_ == espbt::ClientState::DISCONNECTING)
|
||||
return;
|
||||
ESP_LOGI(TAG, "[%d] [%s] Disconnecting.", this->connection_index_, this->address_str_.c_str());
|
||||
auto err = esp_ble_gattc_close(this->gattc_if_, this->conn_id_);
|
||||
if (err != ESP_OK) {
|
||||
@@ -82,22 +70,12 @@ void BLEClientBase::disconnect() {
|
||||
err);
|
||||
}
|
||||
|
||||
if (this->state_ == espbt::ClientState::SEARCHING || this->state_ == espbt::ClientState::READY_TO_CONNECT ||
|
||||
this->state_ == espbt::ClientState::DISCOVERED) {
|
||||
if (this->state_ == espbt::ClientState::SEARCHING) {
|
||||
this->set_address(0);
|
||||
this->set_state(espbt::ClientState::IDLE);
|
||||
} else {
|
||||
this->set_state(espbt::ClientState::DISCONNECTING);
|
||||
}
|
||||
}
|
||||
|
||||
void BLEClientBase::release_services() {
|
||||
for (auto &svc : this->services_)
|
||||
delete svc; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
this->services_.clear();
|
||||
esp_ble_gattc_cache_clean(this->remote_bda_);
|
||||
}
|
||||
|
||||
bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t esp_gattc_if,
|
||||
esp_ble_gattc_cb_param_t *param) {
|
||||
if (event == ESP_GATTC_REG_EVT && this->app_id != param->reg.app_id)
|
||||
@@ -123,24 +101,17 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
case ESP_GATTC_OPEN_EVT: {
|
||||
ESP_LOGV(TAG, "[%d] [%s] ESP_GATTC_OPEN_EVT", this->connection_index_, this->address_str_.c_str());
|
||||
this->conn_id_ = param->open.conn_id;
|
||||
this->service_count_ = 0;
|
||||
if (param->open.status != ESP_GATT_OK && param->open.status != ESP_GATT_ALREADY_OPEN) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Connection failed, status=%d", this->connection_index_, this->address_str_.c_str(),
|
||||
param->open.status);
|
||||
this->set_state(espbt::ClientState::IDLE);
|
||||
break;
|
||||
}
|
||||
if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) {
|
||||
this->set_state(espbt::ClientState::CONNECTED);
|
||||
this->state_ = espbt::ClientState::ESTABLISHED;
|
||||
break;
|
||||
}
|
||||
auto ret = esp_ble_gattc_send_mtu_req(this->gattc_if_, param->open.conn_id);
|
||||
if (ret) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_send_mtu_req failed, status=%x", this->connection_index_,
|
||||
this->address_str_.c_str(), ret);
|
||||
}
|
||||
esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_CFG_MTU_EVT: {
|
||||
@@ -153,6 +124,7 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
ESP_LOGV(TAG, "[%d] [%s] cfg_mtu status %d, mtu %d", this->connection_index_, this->address_str_.c_str(),
|
||||
param->cfg_mtu.status, param->cfg_mtu.mtu);
|
||||
this->mtu_ = param->cfg_mtu.mtu;
|
||||
esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_DISCONNECT_EVT: {
|
||||
@@ -160,17 +132,13 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
return false;
|
||||
ESP_LOGV(TAG, "[%d] [%s] ESP_GATTC_DISCONNECT_EVT, reason %d", this->connection_index_,
|
||||
this->address_str_.c_str(), param->disconnect.reason);
|
||||
this->release_services();
|
||||
for (auto &svc : this->services_)
|
||||
delete svc; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
this->services_.clear();
|
||||
this->set_state(espbt::ClientState::IDLE);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_SEARCH_RES_EVT: {
|
||||
this->service_count_++;
|
||||
if (this->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
|
||||
// V3 clients don't need services initialized since
|
||||
// they only request by handle after receiving the services.
|
||||
break;
|
||||
}
|
||||
BLEService *ble_service = new BLEService(); // NOLINT(cppcoreguidelines-owning-memory)
|
||||
ble_service->uuid = espbt::ESPBTUUID::from_uuid(param->search_res.srvc_id.uuid);
|
||||
ble_service->start_handle = param->search_res.start_handle;
|
||||
@@ -182,49 +150,27 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
ESP_LOGV(TAG, "[%d] [%s] ESP_GATTC_SEARCH_CMPL_EVT", this->connection_index_, this->address_str_.c_str());
|
||||
for (auto &svc : this->services_) {
|
||||
ESP_LOGV(TAG, "[%d] [%s] Service UUID: %s", this->connection_index_, this->address_str_.c_str(),
|
||||
ESP_LOGI(TAG, "[%d] [%s] Service UUID: %s", this->connection_index_, this->address_str_.c_str(),
|
||||
svc->uuid.to_string().c_str());
|
||||
ESP_LOGV(TAG, "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", this->connection_index_,
|
||||
ESP_LOGI(TAG, "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", this->connection_index_,
|
||||
this->address_str_.c_str(), svc->start_handle, svc->end_handle);
|
||||
svc->parse_characteristics();
|
||||
}
|
||||
this->set_state(espbt::ClientState::CONNECTED);
|
||||
this->state_ = espbt::ClientState::ESTABLISHED;
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
|
||||
if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE ||
|
||||
this->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
|
||||
// Client is responsible for flipping the descriptor value
|
||||
// when using the cache
|
||||
auto *descr = this->get_config_descriptor(param->reg_for_notify.handle);
|
||||
if (descr->uuid.get_uuid().len != ESP_UUID_LEN_16 ||
|
||||
descr->uuid.get_uuid().uuid.uuid16 != ESP_GATT_UUID_CHAR_CLIENT_CONFIG) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] Handle 0x%x (uuid %s) is not a client config char uuid", this->connection_index_,
|
||||
this->address_str_.c_str(), param->reg_for_notify.handle, descr->uuid.to_string().c_str());
|
||||
break;
|
||||
}
|
||||
esp_gattc_descr_elem_t desc_result;
|
||||
uint16_t count = 1;
|
||||
esp_gatt_status_t descr_status =
|
||||
esp_ble_gattc_get_descr_by_char_handle(this->gattc_if_, this->connection_index_, param->reg_for_notify.handle,
|
||||
NOTIFY_DESC_UUID, &desc_result, &count);
|
||||
if (descr_status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_get_descr_by_char_handle error, status=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), descr_status);
|
||||
break;
|
||||
}
|
||||
esp_gattc_char_elem_t char_result;
|
||||
esp_gatt_status_t char_status =
|
||||
esp_ble_gattc_get_all_char(this->gattc_if_, this->connection_index_, param->reg_for_notify.handle,
|
||||
param->reg_for_notify.handle, &char_result, &count, 0);
|
||||
if (char_status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", this->connection_index_,
|
||||
this->address_str_.c_str(), char_status);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
1 = notify
|
||||
2 = indicate
|
||||
*/
|
||||
uint16_t notify_en = char_result.properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY ? 1 : 2;
|
||||
esp_err_t status =
|
||||
esp_ble_gattc_write_char_descr(this->gattc_if_, this->conn_id_, desc_result.handle, sizeof(notify_en),
|
||||
uint16_t notify_en = 1;
|
||||
auto status =
|
||||
esp_ble_gattc_write_char_descr(this->gattc_if_, this->conn_id_, descr->handle, sizeof(notify_en),
|
||||
(uint8_t *) ¬ify_en, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_write_char_descr error, status=%d", this->connection_index_,
|
||||
@@ -341,8 +287,6 @@ BLECharacteristic *BLEClientBase::get_characteristic(uint16_t service, uint16_t
|
||||
|
||||
BLECharacteristic *BLEClientBase::get_characteristic(uint16_t handle) {
|
||||
for (auto *svc : this->services_) {
|
||||
if (!svc->parsed)
|
||||
svc->parse_characteristics();
|
||||
for (auto *chr : svc->characteristics) {
|
||||
if (chr->handle == handle)
|
||||
return chr;
|
||||
@@ -354,10 +298,8 @@ BLECharacteristic *BLEClientBase::get_characteristic(uint16_t handle) {
|
||||
BLEDescriptor *BLEClientBase::get_config_descriptor(uint16_t handle) {
|
||||
auto *chr = this->get_characteristic(handle);
|
||||
if (chr != nullptr) {
|
||||
if (!chr->parsed)
|
||||
chr->parse_descriptors();
|
||||
for (auto &desc : chr->descriptors) {
|
||||
if (desc->uuid.get_uuid().uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG)
|
||||
if (desc->uuid.get_uuid().uuid.uuid16 == 0x2902)
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
@@ -381,11 +323,7 @@ BLEDescriptor *BLEClientBase::get_descriptor(uint16_t service, uint16_t chr, uin
|
||||
|
||||
BLEDescriptor *BLEClientBase::get_descriptor(uint16_t handle) {
|
||||
for (auto *svc : this->services_) {
|
||||
if (!svc->parsed)
|
||||
svc->parse_characteristics();
|
||||
for (auto *chr : svc->characteristics) {
|
||||
if (!chr->parsed)
|
||||
chr->parse_descriptors();
|
||||
for (auto *desc : chr->descriptors) {
|
||||
if (desc->handle == handle)
|
||||
return desc;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <esp_bt_defs.h>
|
||||
#include <esp_gap_ble_api.h>
|
||||
@@ -34,7 +33,6 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
|
||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
||||
void connect() override;
|
||||
void disconnect();
|
||||
void release_services();
|
||||
|
||||
bool connected() { return this->state_ == espbt::ClientState::ESTABLISHED; }
|
||||
|
||||
@@ -44,7 +42,7 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
|
||||
memset(this->remote_bda_, 0, sizeof(this->remote_bda_));
|
||||
this->address_str_ = "";
|
||||
} else {
|
||||
this->address_str_ = str_snprintf("%02X:%02X:%02X:%02X:%02X:%02X", 17, (uint8_t)(this->address_ >> 40) & 0xff,
|
||||
this->address_str_ = str_snprintf("%02x:%02x:%02x:%02x:%02x:%02x", 17, (uint8_t)(this->address_ >> 40) & 0xff,
|
||||
(uint8_t)(this->address_ >> 32) & 0xff, (uint8_t)(this->address_ >> 24) & 0xff,
|
||||
(uint8_t)(this->address_ >> 16) & 0xff, (uint8_t)(this->address_ >> 8) & 0xff,
|
||||
(uint8_t)(this->address_ >> 0) & 0xff);
|
||||
@@ -68,14 +66,11 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
|
||||
int get_gattc_if() const { return this->gattc_if_; }
|
||||
uint8_t *get_remote_bda() { return this->remote_bda_; }
|
||||
esp_ble_addr_type_t get_remote_addr_type() const { return this->remote_addr_type_; }
|
||||
void set_remote_addr_type(esp_ble_addr_type_t address_type) { this->remote_addr_type_ = address_type; }
|
||||
uint16_t get_conn_id() const { return this->conn_id_; }
|
||||
uint64_t get_address() const { return this->address_; }
|
||||
|
||||
uint8_t get_connection_index() const { return this->connection_index_; }
|
||||
|
||||
virtual void set_connection_type(espbt::ConnectionType ct) { this->connection_type_ = ct; }
|
||||
|
||||
protected:
|
||||
int gattc_if_;
|
||||
esp_bd_addr_t remote_bda_;
|
||||
@@ -84,9 +79,7 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
|
||||
uint64_t address_{0};
|
||||
std::string address_str_{};
|
||||
uint8_t connection_index_;
|
||||
int16_t service_count_{0};
|
||||
uint16_t mtu_{23};
|
||||
espbt::ConnectionType connection_type_{espbt::ConnectionType::V1};
|
||||
|
||||
std::vector<BLEService *> services_;
|
||||
};
|
||||
|
||||
@@ -11,8 +11,6 @@ namespace esp32_ble_client {
|
||||
static const char *const TAG = "esp32_ble_client";
|
||||
|
||||
BLECharacteristic *BLEService::get_characteristic(espbt::ESPBTUUID uuid) {
|
||||
if (!this->parsed)
|
||||
this->parse_characteristics();
|
||||
for (auto &chr : this->characteristics) {
|
||||
if (chr->uuid == uuid)
|
||||
return chr;
|
||||
@@ -29,15 +27,7 @@ BLEService::~BLEService() {
|
||||
delete chr; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
}
|
||||
|
||||
void BLEService::release_characteristics() {
|
||||
this->parsed = false;
|
||||
for (auto &chr : this->characteristics)
|
||||
delete chr; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
this->characteristics.clear();
|
||||
}
|
||||
|
||||
void BLEService::parse_characteristics() {
|
||||
this->parsed = true;
|
||||
uint16_t offset = 0;
|
||||
esp_gattc_char_elem_t result;
|
||||
|
||||
@@ -64,9 +54,10 @@ void BLEService::parse_characteristics() {
|
||||
characteristic->handle = result.char_handle;
|
||||
characteristic->service = this;
|
||||
this->characteristics.push_back(characteristic);
|
||||
ESP_LOGV(TAG, "[%d] [%s] characteristic %s, handle 0x%x, properties 0x%x", this->client->get_connection_index(),
|
||||
ESP_LOGI(TAG, "[%d] [%s] characteristic %s, handle 0x%x, properties 0x%x", this->client->get_connection_index(),
|
||||
this->client->address_str().c_str(), characteristic->uuid.to_string().c_str(), characteristic->handle,
|
||||
characteristic->properties);
|
||||
characteristic->parse_descriptors();
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "ble_characteristic.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32_ble_client {
|
||||
|
||||
@@ -18,14 +16,12 @@ class BLEClientBase;
|
||||
class BLEService {
|
||||
public:
|
||||
~BLEService();
|
||||
bool parsed = false;
|
||||
espbt::ESPBTUUID uuid;
|
||||
uint16_t start_handle;
|
||||
uint16_t end_handle;
|
||||
std::vector<BLECharacteristic *> characteristics;
|
||||
BLEClientBase *client;
|
||||
void parse_characteristics();
|
||||
void release_characteristics();
|
||||
BLECharacteristic *get_characteristic(espbt::ESPBTUUID uuid);
|
||||
BLECharacteristic *get_characteristic(uint16_t uuid);
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "ble_characteristic.h"
|
||||
#include "esphome/components/esp32_ble/ble_uuid.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <esp_gap_ble_api.h>
|
||||
|
||||
@@ -238,11 +238,6 @@ async def to_code(config):
|
||||
|
||||
if CORE.using_esp_idf:
|
||||
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)
|
||||
# https://github.com/espressif/esp-idf/issues/4101
|
||||
# https://github.com/espressif/esp-idf/issues/2503
|
||||
# Match arduino CONFIG_BTU_TASK_STACK_SIZE
|
||||
# https://github.com/espressif/arduino-esp32/blob/fd72cf46ad6fc1a6de99c1d83ba8eba17d80a4ee/tools/sdk/esp32/sdkconfig#L1866
|
||||
add_idf_sdkconfig_option("CONFIG_BTU_TASK_STACK_SIZE", 8192)
|
||||
|
||||
cg.add_define("USE_OTA_STATE_CALLBACK") # To be notified when an OTA update starts
|
||||
|
||||
|
||||
@@ -66,11 +66,7 @@ void ESP32BLETracker::setup() {
|
||||
#endif
|
||||
|
||||
if (this->scan_continuous_) {
|
||||
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
this->start_scan_(true);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Cannot start scan!");
|
||||
}
|
||||
this->start_scan_(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,144 +83,86 @@ void ESP32BLETracker::loop() {
|
||||
ble_event = this->ble_events_.pop();
|
||||
}
|
||||
|
||||
int connecting = 0;
|
||||
int discovered = 0;
|
||||
int searching = 0;
|
||||
int disconnecting = 0;
|
||||
if (this->scanner_idle_) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool connecting = false;
|
||||
for (auto *client : this->clients_) {
|
||||
switch (client->state()) {
|
||||
case ClientState::DISCONNECTING:
|
||||
disconnecting++;
|
||||
break;
|
||||
case ClientState::DISCOVERED:
|
||||
discovered++;
|
||||
break;
|
||||
case ClientState::SEARCHING:
|
||||
searching++;
|
||||
break;
|
||||
case ClientState::CONNECTING:
|
||||
case ClientState::READY_TO_CONNECT:
|
||||
connecting++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (client->state() == ClientState::CONNECTING || client->state() == ClientState::DISCOVERED)
|
||||
connecting = true;
|
||||
}
|
||||
|
||||
if (!connecting && xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
if (this->scan_continuous_) {
|
||||
this->start_scan_(false);
|
||||
} else if (xSemaphoreTake(this->scan_end_lock_, 0L) && !this->scanner_idle_) {
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
this->end_of_scan_();
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool promote_to_connecting = discovered && !searching && !connecting;
|
||||
|
||||
if (!this->scanner_idle_) {
|
||||
if (this->scan_result_index_ && // if it looks like we have a scan result we will take the lock
|
||||
xSemaphoreTake(this->scan_result_lock_, 5L / portTICK_PERIOD_MS)) {
|
||||
uint32_t index = this->scan_result_index_;
|
||||
if (index) {
|
||||
if (index >= 16) {
|
||||
ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up.");
|
||||
}
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
ESPBTDevice device;
|
||||
device.parse_scan_rst(this->scan_result_buffer_[i]);
|
||||
if (xSemaphoreTake(this->scan_result_lock_, 5L / portTICK_PERIOD_MS)) {
|
||||
uint32_t index = this->scan_result_index_;
|
||||
xSemaphoreGive(this->scan_result_lock_);
|
||||
|
||||
bool found = false;
|
||||
for (auto *listener : this->listeners_) {
|
||||
if (listener->parse_device(device))
|
||||
found = true;
|
||||
}
|
||||
if (index >= 16) {
|
||||
ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up.");
|
||||
}
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
ESPBTDevice device;
|
||||
device.parse_scan_rst(this->scan_result_buffer_[i]);
|
||||
|
||||
for (auto *client : this->clients_) {
|
||||
if (client->parse_device(device)) {
|
||||
found = true;
|
||||
if (!connecting && client->state() == ClientState::DISCOVERED) {
|
||||
promote_to_connecting = true;
|
||||
}
|
||||
bool found = false;
|
||||
for (auto *listener : this->listeners_) {
|
||||
if (listener->parse_device(device))
|
||||
found = true;
|
||||
}
|
||||
|
||||
for (auto *client : this->clients_) {
|
||||
if (client->parse_device(device)) {
|
||||
found = true;
|
||||
if (client->state() == ClientState::DISCOVERED) {
|
||||
esp_ble_gap_stop_scanning();
|
||||
#ifdef USE_ARDUINO
|
||||
constexpr TickType_t block_time = 10L / portTICK_PERIOD_MS;
|
||||
#else
|
||||
constexpr TickType_t block_time = 0L; // PR #3594
|
||||
#endif
|
||||
if (xSemaphoreTake(this->scan_end_lock_, block_time)) {
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && !this->scan_continuous_) {
|
||||
this->print_bt_device_info(device);
|
||||
}
|
||||
}
|
||||
this->scan_result_index_ = 0;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
this->print_bt_device_info(device);
|
||||
}
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(this->scan_result_lock_, 10L / portTICK_PERIOD_MS)) {
|
||||
this->scan_result_index_ = 0;
|
||||
xSemaphoreGive(this->scan_result_lock_);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Avoid starting the scanner if:
|
||||
- we are already scanning
|
||||
- we are connecting to a device
|
||||
- we are disconnecting from a device
|
||||
|
||||
Otherwise the scanner could fail to ever start again
|
||||
and our only way to recover is to reboot.
|
||||
|
||||
https://github.com/espressif/esp-idf/issues/6688
|
||||
|
||||
*/
|
||||
if (!connecting && !disconnecting && xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
if (this->scan_continuous_) {
|
||||
if (!promote_to_connecting && !this->scan_start_failed_ && !this->scan_set_param_failed_) {
|
||||
this->start_scan_(false);
|
||||
} else {
|
||||
// We didn't start the scan, so we need to release the lock
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
}
|
||||
} else if (!this->scanner_idle_) {
|
||||
this->end_of_scan_();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->scan_start_failed_ || this->scan_set_param_failed_) {
|
||||
if (this->scan_start_fail_count_ == 255) {
|
||||
ESP_LOGE(TAG, "ESP-IDF BLE scan could not restart after 255 attempts, rebooting to restore BLE stack...");
|
||||
App.reboot();
|
||||
}
|
||||
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Stopping scan after failure...");
|
||||
esp_ble_gap_stop_scanning();
|
||||
this->cancel_timeout("scan");
|
||||
}
|
||||
if (this->scan_start_failed_) {
|
||||
ESP_LOGE(TAG, "Scan start failed: %d", this->scan_start_failed_);
|
||||
this->scan_start_failed_ = ESP_BT_STATUS_SUCCESS;
|
||||
}
|
||||
if (this->scan_set_param_failed_) {
|
||||
ESP_LOGE(TAG, "Scan set param failed: %d", this->scan_set_param_failed_);
|
||||
this->scan_set_param_failed_ = ESP_BT_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a discovered client and no connecting
|
||||
// clients and no clients using the scanner to search for
|
||||
// devices, then stop scanning and promote the discovered
|
||||
// client to ready to connect.
|
||||
if (promote_to_connecting) {
|
||||
for (auto *client : this->clients_) {
|
||||
if (client->state() == ClientState::DISCOVERED) {
|
||||
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
// Scanner is not running since we got the
|
||||
// lock, so we can promote the client.
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
// We only want to promote one client at a time.
|
||||
// once the scanner is fully stopped.
|
||||
client->set_state(ClientState::READY_TO_CONNECT);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Pausing scan to make connection...");
|
||||
esp_ble_gap_stop_scanning();
|
||||
this->cancel_timeout("scan");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this->scan_set_param_failed_) {
|
||||
ESP_LOGE(TAG, "Scan set param failed: %d", this->scan_set_param_failed_);
|
||||
this->scan_set_param_failed_ = ESP_BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (this->scan_start_failed_) {
|
||||
ESP_LOGE(TAG, "Scan start failed: %d", this->scan_start_failed_);
|
||||
this->scan_start_failed_ = ESP_BT_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void ESP32BLETracker::start_scan() {
|
||||
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
this->start_scan_(true);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Scan requested when a scan is already in progress. Ignoring.");
|
||||
@@ -318,9 +256,8 @@ bool ESP32BLETracker::ble_setup() {
|
||||
}
|
||||
|
||||
void ESP32BLETracker::start_scan_(bool first) {
|
||||
// The lock must be held when calling this function.
|
||||
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
ESP_LOGE(TAG, "start_scan called without holding scan_end_lock_");
|
||||
if (!xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
ESP_LOGW(TAG, "Cannot start scan!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -341,15 +278,14 @@ void ESP32BLETracker::start_scan_(bool first) {
|
||||
esp_ble_gap_start_scanning(this->scan_duration_);
|
||||
|
||||
this->set_timeout("scan", this->scan_duration_ * 2000, []() {
|
||||
ESP_LOGE(TAG, "ESP-IDF BLE scan never terminated, rebooting to restore BLE stack...");
|
||||
ESP_LOGW(TAG, "ESP-IDF BLE scan never terminated, rebooting to restore BLE stack...");
|
||||
App.reboot();
|
||||
});
|
||||
}
|
||||
|
||||
void ESP32BLETracker::end_of_scan_() {
|
||||
// The lock must be held when calling this function.
|
||||
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
ESP_LOGE(TAG, "end_of_scan_ called without holding the scan_end_lock_");
|
||||
if (!xSemaphoreTake(this->scan_end_lock_, 0L)) {
|
||||
ESP_LOGW(TAG, "Cannot clean up end of scan!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -401,12 +337,6 @@ void ESP32BLETracker::gap_scan_set_param_complete_(const esp_ble_gap_cb_param_t:
|
||||
|
||||
void ESP32BLETracker::gap_scan_start_complete_(const esp_ble_gap_cb_param_t::ble_scan_start_cmpl_evt_param ¶m) {
|
||||
this->scan_start_failed_ = param.status;
|
||||
if (param.status == ESP_BT_STATUS_SUCCESS) {
|
||||
this->scan_start_fail_count_ = 0;
|
||||
} else {
|
||||
this->scan_start_fail_count_++;
|
||||
xSemaphoreGive(this->scan_end_lock_);
|
||||
}
|
||||
}
|
||||
|
||||
void ESP32BLETracker::gap_scan_stop_complete_(const esp_ble_gap_cb_param_t::ble_scan_stop_cmpl_evt_param ¶m) {
|
||||
@@ -847,9 +777,6 @@ void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_p
|
||||
this->service_datas_.push_back(data);
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_AD_TYPE_INT_RANGE:
|
||||
// Avoid logging this as it's very verbose
|
||||
break;
|
||||
default: {
|
||||
ESP_LOGV(TAG, "Unhandled type: advType: 0x%02x", record_type);
|
||||
break;
|
||||
@@ -904,9 +831,8 @@ void ESP32BLETracker::print_bt_device_info(const ESPBTDevice &device) {
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, " Address Type: %s", address_type_s);
|
||||
if (!device.get_name().empty()) {
|
||||
if (!device.get_name().empty())
|
||||
ESP_LOGD(TAG, " Name: '%s'", device.get_name().c_str());
|
||||
}
|
||||
for (auto &tx_power : device.get_tx_powers()) {
|
||||
ESP_LOGD(TAG, " TX Power: %d", tx_power);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <esp_gap_ble_api.h>
|
||||
#include <esp_gattc_api.h>
|
||||
#include <esp_bt_defs.h>
|
||||
@@ -145,18 +143,12 @@ class ESPBTDeviceListener {
|
||||
};
|
||||
|
||||
enum class ClientState {
|
||||
// Connection is allocated
|
||||
INIT,
|
||||
// Client is disconnecting
|
||||
DISCONNECTING,
|
||||
// Connection is idle, no device detected.
|
||||
IDLE,
|
||||
// Searching for device.
|
||||
SEARCHING,
|
||||
// Device advertisement found.
|
||||
DISCOVERED,
|
||||
// Device is discovered and the scanner is stopped
|
||||
READY_TO_CONNECT,
|
||||
// Connection in progress.
|
||||
CONNECTING,
|
||||
// Initial connection established.
|
||||
@@ -165,18 +157,6 @@ enum class ClientState {
|
||||
ESTABLISHED,
|
||||
};
|
||||
|
||||
enum class ConnectionType {
|
||||
// The default connection type, we hold all the services in ram
|
||||
// for the duration of the connection.
|
||||
V1,
|
||||
// The client has a cache of the services and mtu so we should not
|
||||
// fetch them again
|
||||
V3_WITH_CACHE,
|
||||
// The client does not need the services and mtu once we send them
|
||||
// so we should wipe them from memory as soon as we send them
|
||||
V3_WITHOUT_CACHE
|
||||
};
|
||||
|
||||
class ESPBTClient : public ESPBTDeviceListener {
|
||||
public:
|
||||
virtual bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
@@ -253,7 +233,6 @@ class ESP32BLETracker : public Component {
|
||||
uint32_t scan_duration_;
|
||||
uint32_t scan_interval_;
|
||||
uint32_t scan_window_;
|
||||
uint8_t scan_start_fail_count_;
|
||||
bool scan_continuous_;
|
||||
bool scan_active_;
|
||||
bool scanner_idle_;
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <cstring>
|
||||
|
||||
#include <esp_gap_ble_api.h>
|
||||
#include <esp_gattc_api.h>
|
||||
|
||||
@@ -54,7 +54,7 @@ void ESP32Camera::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " HREF Pin: %d", conf.pin_href);
|
||||
ESP_LOGCONFIG(TAG, " Pixel Clock Pin: %d", conf.pin_pclk);
|
||||
ESP_LOGCONFIG(TAG, " External Clock: Pin:%d Frequency:%u", conf.pin_xclk, conf.xclk_freq_hz);
|
||||
ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sccb_sda, conf.pin_sccb_scl);
|
||||
ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sscb_sda, conf.pin_sscb_scl);
|
||||
ESP_LOGCONFIG(TAG, " Reset Pin: %d", conf.pin_reset);
|
||||
switch (this->config_.frame_size) {
|
||||
case FRAMESIZE_QQVGA:
|
||||
@@ -209,8 +209,8 @@ void ESP32Camera::set_external_clock(uint8_t pin, uint32_t frequency) {
|
||||
this->config_.xclk_freq_hz = frequency;
|
||||
}
|
||||
void ESP32Camera::set_i2c_pins(uint8_t sda, uint8_t scl) {
|
||||
this->config_.pin_sccb_sda = sda;
|
||||
this->config_.pin_sccb_scl = scl;
|
||||
this->config_.pin_sscb_sda = sda;
|
||||
this->config_.pin_sscb_scl = scl;
|
||||
}
|
||||
void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
|
||||
void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }
|
||||
|
||||
@@ -177,9 +177,8 @@ void ESP32ImprovComponent::set_state_(improv::State state) {
|
||||
}
|
||||
|
||||
void ESP32ImprovComponent::set_error_(improv::Error error) {
|
||||
if (error != improv::ERROR_NONE) {
|
||||
if (error != improv::ERROR_NONE)
|
||||
ESP_LOGE(TAG, "Error: %d", error);
|
||||
}
|
||||
if (this->error_->get_value().empty() || this->error_->get_value()[0] != error) {
|
||||
uint8_t data[1]{error};
|
||||
this->error_->set_value(data, 1);
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <improv.h>
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include <esp_idf_version.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include <driver/touch_sensor.h>
|
||||
#else
|
||||
|
||||
@@ -5,14 +5,12 @@ extern "C" {
|
||||
#include "spi_flash.h"
|
||||
}
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#include "preferences.h"
|
||||
#include <cstring>
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "preferences.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "esphome/core/defines.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace esp8266 {
|
||||
|
||||
@@ -30,17 +30,16 @@ CONF_POWER_PIN = "power_pin"
|
||||
EthernetType = ethernet_ns.enum("EthernetType")
|
||||
ETHERNET_TYPES = {
|
||||
"LAN8720": EthernetType.ETHERNET_TYPE_LAN8720,
|
||||
"RTL8201": EthernetType.ETHERNET_TYPE_RTL8201,
|
||||
"DP83848": EthernetType.ETHERNET_TYPE_DP83848,
|
||||
"TLK110": EthernetType.ETHERNET_TYPE_TLK110,
|
||||
"IP101": EthernetType.ETHERNET_TYPE_IP101,
|
||||
}
|
||||
|
||||
emac_rmii_clock_gpio_t = cg.global_ns.enum("emac_rmii_clock_gpio_t")
|
||||
eth_clock_mode_t = cg.global_ns.enum("eth_clock_mode_t")
|
||||
CLK_MODES = {
|
||||
"GPIO0_IN": emac_rmii_clock_gpio_t.EMAC_CLK_IN_GPIO,
|
||||
"GPIO0_OUT": emac_rmii_clock_gpio_t.EMAC_APPL_CLK_OUT_GPIO,
|
||||
"GPIO16_OUT": emac_rmii_clock_gpio_t.EMAC_CLK_OUT_GPIO,
|
||||
"GPIO17_OUT": emac_rmii_clock_gpio_t.EMAC_CLK_OUT_180_GPIO,
|
||||
"GPIO0_IN": eth_clock_mode_t.ETH_CLOCK_GPIO0_IN,
|
||||
"GPIO0_OUT": eth_clock_mode_t.ETH_CLOCK_GPIO0_OUT,
|
||||
"GPIO16_OUT": eth_clock_mode_t.ETH_CLOCK_GPIO16_OUT,
|
||||
"GPIO17_OUT": eth_clock_mode_t.ETH_CLOCK_GPIO17_OUT,
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +78,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
CLK_MODES, upper=True, space="_"
|
||||
),
|
||||
cv.Optional(CONF_PHY_ADDR, default=0): cv.int_range(min=0, max=31),
|
||||
cv.Optional(CONF_POWER_PIN): pins.internal_gpio_output_pin_number,
|
||||
cv.Optional(CONF_POWER_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_MANUAL_IP): MANUAL_IP_SCHEMA,
|
||||
cv.Optional(CONF_DOMAIN, default=".local"): cv.domain_name,
|
||||
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
||||
@@ -90,6 +89,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
_validate,
|
||||
cv.only_with_arduino,
|
||||
)
|
||||
|
||||
|
||||
@@ -117,12 +117,13 @@ async def to_code(config):
|
||||
cg.add(var.set_use_address(config[CONF_USE_ADDRESS]))
|
||||
|
||||
if CONF_POWER_PIN in config:
|
||||
cg.add(var.set_power_pin(config[CONF_POWER_PIN]))
|
||||
pin = await cg.gpio_pin_expression(config[CONF_POWER_PIN])
|
||||
cg.add(var.set_power_pin(pin))
|
||||
|
||||
if CONF_MANUAL_IP in config:
|
||||
cg.add(var.set_manual_ip(manual_ip(config[CONF_MANUAL_IP])))
|
||||
|
||||
cg.add_define("USE_ETHERNET")
|
||||
|
||||
if CORE.using_arduino:
|
||||
if CORE.is_esp32:
|
||||
cg.add_library("WiFi", None)
|
||||
|
||||
@@ -3,10 +3,21 @@
|
||||
#include "esphome/core/util.h"
|
||||
#include "esphome/core/application.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
||||
|
||||
#include <eth_phy/phy_lan8720.h>
|
||||
#include <eth_phy/phy_ip101.h>
|
||||
#include <eth_phy/phy_tlk110.h>
|
||||
#include <lwip/dns.h>
|
||||
#include "esp_event.h"
|
||||
|
||||
/// Macro for IDF version comparison
|
||||
#ifndef ESP_IDF_VERSION_VAL
|
||||
#define ESP_IDF_VERSION_VAL(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch))
|
||||
#endif
|
||||
|
||||
// Defined in WiFiGeneric.cpp, sets global initialized flag, starts network event task queue and calls
|
||||
// tcpip_adapter_init()
|
||||
extern void tcpipInit(); // NOLINT(readability-identifier-naming)
|
||||
|
||||
namespace esphome {
|
||||
namespace ethernet {
|
||||
@@ -26,49 +37,25 @@ EthernetComponent::EthernetComponent() { global_eth_component = this; }
|
||||
|
||||
void EthernetComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Ethernet...");
|
||||
// Delay here to allow power to stabilise before Ethernet is initialised.
|
||||
delay(300); // NOLINT
|
||||
|
||||
esp_err_t err;
|
||||
err = esp_netif_init();
|
||||
ESPHL_ERROR_CHECK(err, "ETH netif init error");
|
||||
err = esp_event_loop_create_default();
|
||||
ESPHL_ERROR_CHECK(err, "ETH event loop error");
|
||||
auto f = std::bind(&EthernetComponent::on_wifi_event_, this, std::placeholders::_1, std::placeholders::_2);
|
||||
WiFi.onEvent(f);
|
||||
|
||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
this->eth_netif_ = esp_netif_new(&cfg);
|
||||
if (this->power_pin_ != nullptr) {
|
||||
this->power_pin_->setup();
|
||||
}
|
||||
|
||||
// Init MAC and PHY configs to default
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
|
||||
phy_config.phy_addr = this->phy_addr_;
|
||||
if (this->power_pin_ != -1)
|
||||
phy_config.reset_gpio_num = this->power_pin_;
|
||||
|
||||
mac_config.smi_mdc_gpio_num = this->mdc_pin_;
|
||||
mac_config.smi_mdio_gpio_num = this->mdio_pin_;
|
||||
mac_config.clock_config.rmii.clock_mode = this->clk_mode_ == EMAC_CLK_IN_GPIO ? EMAC_CLK_EXT_IN : EMAC_CLK_OUT;
|
||||
mac_config.clock_config.rmii.clock_gpio = this->clk_mode_;
|
||||
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
|
||||
|
||||
esp_eth_phy_t *phy;
|
||||
switch (this->type_) {
|
||||
case ETHERNET_TYPE_LAN8720: {
|
||||
phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
memcpy(&this->eth_config_, &phy_lan8720_default_ethernet_config, sizeof(eth_config_t));
|
||||
break;
|
||||
}
|
||||
case ETHERNET_TYPE_RTL8201: {
|
||||
phy = esp_eth_phy_new_rtl8201(&phy_config);
|
||||
break;
|
||||
}
|
||||
case ETHERNET_TYPE_DP83848: {
|
||||
phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||
case ETHERNET_TYPE_TLK110: {
|
||||
memcpy(&this->eth_config_, &phy_tlk110_default_ethernet_config, sizeof(eth_config_t));
|
||||
break;
|
||||
}
|
||||
case ETHERNET_TYPE_IP101: {
|
||||
phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
memcpy(&this->eth_config_, &phy_ip101_default_ethernet_config, sizeof(eth_config_t));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -77,23 +64,23 @@ void EthernetComponent::setup() {
|
||||
}
|
||||
}
|
||||
|
||||
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
|
||||
this->eth_handle_ = nullptr;
|
||||
err = esp_eth_driver_install(ð_config, &this->eth_handle_);
|
||||
ESPHL_ERROR_CHECK(err, "ETH driver install error");
|
||||
/* attach Ethernet driver to TCP/IP stack */
|
||||
err = esp_netif_attach(this->eth_netif_, esp_eth_new_netif_glue(this->eth_handle_));
|
||||
ESPHL_ERROR_CHECK(err, "ETH netif attach error");
|
||||
this->eth_config_.phy_addr = static_cast<eth_phy_base_t>(this->phy_addr_);
|
||||
this->eth_config_.clock_mode = this->clk_mode_;
|
||||
this->eth_config_.gpio_config = EthernetComponent::eth_phy_config_gpio;
|
||||
this->eth_config_.tcpip_input = tcpip_adapter_eth_input;
|
||||
|
||||
// Register user defined event handers
|
||||
err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &EthernetComponent::eth_event_handler, nullptr);
|
||||
ESPHL_ERROR_CHECK(err, "ETH event handler register error");
|
||||
err = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &EthernetComponent::got_ip_event_handler, nullptr);
|
||||
ESPHL_ERROR_CHECK(err, "GOT IP event handler register error");
|
||||
if (this->power_pin_ != nullptr) {
|
||||
this->orig_power_enable_fun_ = this->eth_config_.phy_power_enable;
|
||||
this->eth_config_.phy_power_enable = EthernetComponent::eth_phy_power_enable;
|
||||
}
|
||||
|
||||
/* start Ethernet driver state machine */
|
||||
err = esp_eth_start(this->eth_handle_);
|
||||
ESPHL_ERROR_CHECK(err, "ETH start error");
|
||||
tcpipInit();
|
||||
|
||||
esp_err_t err;
|
||||
err = esp_eth_init(&this->eth_config_);
|
||||
ESPHL_ERROR_CHECK(err, "ETH init error");
|
||||
err = esp_eth_enable();
|
||||
ESPHL_ERROR_CHECK(err, "ETH enable error");
|
||||
}
|
||||
|
||||
void EthernetComponent::loop() {
|
||||
@@ -143,12 +130,8 @@ void EthernetComponent::dump_config() {
|
||||
eth_type = "LAN8720";
|
||||
break;
|
||||
|
||||
case ETHERNET_TYPE_RTL8201:
|
||||
eth_type = "RTL8201";
|
||||
break;
|
||||
|
||||
case ETHERNET_TYPE_DP83848:
|
||||
eth_type = "DP83848";
|
||||
case ETHERNET_TYPE_TLK110:
|
||||
eth_type = "TLK110";
|
||||
break;
|
||||
|
||||
case ETHERNET_TYPE_IP101:
|
||||
@@ -162,9 +145,7 @@ void EthernetComponent::dump_config() {
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Ethernet:");
|
||||
this->dump_connect_params_();
|
||||
if (this->power_pin_ != -1) {
|
||||
ESP_LOGCONFIG(TAG, " Power Pin: %u", this->power_pin_);
|
||||
}
|
||||
LOG_PIN(" Power Pin: ", this->power_pin_);
|
||||
ESP_LOGCONFIG(TAG, " MDC Pin: %u", this->mdc_pin_);
|
||||
ESP_LOGCONFIG(TAG, " MDIO Pin: %u", this->mdio_pin_);
|
||||
ESP_LOGCONFIG(TAG, " Type: %s", eth_type.c_str());
|
||||
@@ -175,30 +156,34 @@ float EthernetComponent::get_setup_priority() const { return setup_priority::WIF
|
||||
bool EthernetComponent::can_proceed() { return this->is_connected(); }
|
||||
|
||||
network::IPAddress EthernetComponent::get_ip_address() {
|
||||
esp_netif_ip_info_t ip;
|
||||
esp_netif_get_ip_info(this->eth_netif_, &ip);
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip);
|
||||
return {ip.ip.addr};
|
||||
}
|
||||
|
||||
void EthernetComponent::eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event, void *event_data) {
|
||||
void EthernetComponent::on_wifi_event_(system_event_id_t event, system_event_info_t info) {
|
||||
const char *event_name;
|
||||
|
||||
switch (event) {
|
||||
case ETHERNET_EVENT_START:
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
event_name = "ETH started";
|
||||
global_eth_component->started_ = true;
|
||||
this->started_ = true;
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
event_name = "ETH stopped";
|
||||
global_eth_component->started_ = false;
|
||||
global_eth_component->connected_ = false;
|
||||
this->started_ = false;
|
||||
this->connected_ = false;
|
||||
break;
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
event_name = "ETH connected";
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
event_name = "ETH disconnected";
|
||||
global_eth_component->connected_ = false;
|
||||
this->connected_ = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
event_name = "ETH Got IP";
|
||||
this->connected_ = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -207,23 +192,17 @@ void EthernetComponent::eth_event_handler(void *arg, esp_event_base_t event_base
|
||||
ESP_LOGV(TAG, "[Ethernet event] %s (num=%d)", event_name, event);
|
||||
}
|
||||
|
||||
void EthernetComponent::got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id,
|
||||
void *event_data) {
|
||||
global_eth_component->connected_ = true;
|
||||
ESP_LOGV(TAG, "[Ethernet event] ETH Got IP (num=%d)", event_id);
|
||||
}
|
||||
|
||||
void EthernetComponent::start_connect_() {
|
||||
this->connect_begin_ = millis();
|
||||
this->status_set_warning();
|
||||
|
||||
esp_err_t err;
|
||||
err = esp_netif_set_hostname(this->eth_netif_, App.get_name().c_str());
|
||||
err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, App.get_name().c_str());
|
||||
if (err != ERR_OK) {
|
||||
ESP_LOGW(TAG, "esp_netif_set_hostname failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGW(TAG, "tcpip_adapter_set_hostname failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
esp_netif_ip_info_t info;
|
||||
tcpip_adapter_ip_info_t info;
|
||||
if (this->manual_ip_.has_value()) {
|
||||
info.ip.addr = static_cast<uint32_t>(this->manual_ip_->static_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(this->manual_ip_->gateway);
|
||||
@@ -234,19 +213,11 @@ void EthernetComponent::start_connect_() {
|
||||
info.netmask.addr = 0;
|
||||
}
|
||||
|
||||
esp_netif_dhcp_status_t status = ESP_NETIF_DHCP_INIT;
|
||||
|
||||
err = esp_netif_dhcpc_get_status(this->eth_netif_, &status);
|
||||
ESPHL_ERROR_CHECK(err, "DHCPC Get Status Failed!");
|
||||
|
||||
ESP_LOGV(TAG, "DHCP Client Status: %d", status);
|
||||
|
||||
err = esp_netif_dhcpc_stop(this->eth_netif_);
|
||||
if (err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
|
||||
err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH);
|
||||
if (err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) {
|
||||
ESPHL_ERROR_CHECK(err, "DHCPC stop error");
|
||||
}
|
||||
|
||||
err = esp_netif_set_ip_info(this->eth_netif_, &info);
|
||||
err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info);
|
||||
ESPHL_ERROR_CHECK(err, "DHCPC set IP info error");
|
||||
|
||||
if (this->manual_ip_.has_value()) {
|
||||
@@ -263,8 +234,8 @@ void EthernetComponent::start_connect_() {
|
||||
dns_setserver(1, &d);
|
||||
}
|
||||
} else {
|
||||
err = esp_netif_dhcpc_start(this->eth_netif_);
|
||||
if (err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED) {
|
||||
err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH);
|
||||
if (err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED) {
|
||||
ESPHL_ERROR_CHECK(err, "DHCPC start error");
|
||||
}
|
||||
}
|
||||
@@ -273,46 +244,53 @@ void EthernetComponent::start_connect_() {
|
||||
this->status_set_warning();
|
||||
}
|
||||
|
||||
void EthernetComponent::eth_phy_config_gpio() {
|
||||
phy_rmii_configure_data_interface_pins();
|
||||
phy_rmii_smi_configure_pins(global_eth_component->mdc_pin_, global_eth_component->mdio_pin_);
|
||||
}
|
||||
|
||||
void EthernetComponent::eth_phy_power_enable(bool enable) {
|
||||
global_eth_component->power_pin_->digital_write(enable);
|
||||
// power up takes some time, datasheet says max 300µs
|
||||
delay(1);
|
||||
global_eth_component->orig_power_enable_fun_(enable);
|
||||
}
|
||||
|
||||
bool EthernetComponent::is_connected() { return this->state_ == EthernetComponentState::CONNECTED; }
|
||||
|
||||
void EthernetComponent::dump_connect_params_() {
|
||||
esp_netif_ip_info_t ip;
|
||||
esp_netif_get_ip_info(this->eth_netif_, &ip);
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip);
|
||||
ESP_LOGCONFIG(TAG, " IP Address: %s", network::IPAddress(ip.ip.addr).str().c_str());
|
||||
ESP_LOGCONFIG(TAG, " Hostname: '%s'", App.get_name().c_str());
|
||||
ESP_LOGCONFIG(TAG, " Subnet: %s", network::IPAddress(ip.netmask.addr).str().c_str());
|
||||
ESP_LOGCONFIG(TAG, " Gateway: %s", network::IPAddress(ip.gw.addr).str().c_str());
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(3, 3, 4)
|
||||
const ip_addr_t *dns_ip1 = dns_getserver(0);
|
||||
const ip_addr_t *dns_ip2 = dns_getserver(1);
|
||||
|
||||
#else
|
||||
ip_addr_t tmp_ip1 = dns_getserver(0);
|
||||
const ip_addr_t *dns_ip1 = &tmp_ip1;
|
||||
ip_addr_t tmp_ip2 = dns_getserver(1);
|
||||
const ip_addr_t *dns_ip2 = &tmp_ip2;
|
||||
#endif
|
||||
ESP_LOGCONFIG(TAG, " DNS1: %s", network::IPAddress(dns_ip1->u_addr.ip4.addr).str().c_str());
|
||||
ESP_LOGCONFIG(TAG, " DNS2: %s", network::IPAddress(dns_ip2->u_addr.ip4.addr).str().c_str());
|
||||
|
||||
esp_err_t err;
|
||||
|
||||
uint8_t mac[6];
|
||||
err = esp_eth_ioctl(this->eth_handle_, ETH_CMD_G_MAC_ADDR, &mac);
|
||||
ESPHL_ERROR_CHECK(err, "ETH_CMD_G_MAC error");
|
||||
esp_eth_get_mac(mac);
|
||||
ESP_LOGCONFIG(TAG, " MAC Address: %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
eth_duplex_t duplex_mode;
|
||||
err = esp_eth_ioctl(this->eth_handle_, ETH_CMD_G_DUPLEX_MODE, &duplex_mode);
|
||||
ESPHL_ERROR_CHECK(err, "ETH_CMD_G_DUPLEX_MODE error");
|
||||
ESP_LOGCONFIG(TAG, " Is Full Duplex: %s", YESNO(duplex_mode == ETH_DUPLEX_FULL));
|
||||
|
||||
eth_speed_t speed;
|
||||
err = esp_eth_ioctl(this->eth_handle_, ETH_CMD_G_SPEED, &speed);
|
||||
ESPHL_ERROR_CHECK(err, "ETH_CMD_G_SPEED error");
|
||||
ESP_LOGCONFIG(TAG, " Link Speed: %u", speed == ETH_SPEED_100M ? 100 : 10);
|
||||
ESP_LOGCONFIG(TAG, " Is Full Duplex: %s", YESNO(this->eth_config_.phy_get_duplex_mode()));
|
||||
ESP_LOGCONFIG(TAG, " Link Up: %s", YESNO(this->eth_config_.phy_check_link()));
|
||||
ESP_LOGCONFIG(TAG, " Link Speed: %u", this->eth_config_.phy_get_speed_mode() ? 100 : 10);
|
||||
}
|
||||
|
||||
void EthernetComponent::set_phy_addr(uint8_t phy_addr) { this->phy_addr_ = phy_addr; }
|
||||
void EthernetComponent::set_power_pin(int power_pin) { this->power_pin_ = power_pin; }
|
||||
void EthernetComponent::set_power_pin(GPIOPin *power_pin) { this->power_pin_ = power_pin; }
|
||||
void EthernetComponent::set_mdc_pin(uint8_t mdc_pin) { this->mdc_pin_ = mdc_pin; }
|
||||
void EthernetComponent::set_mdio_pin(uint8_t mdio_pin) { this->mdio_pin_ = mdio_pin; }
|
||||
void EthernetComponent::set_type(EthernetType type) { this->type_ = type; }
|
||||
void EthernetComponent::set_clk_mode(emac_rmii_clock_gpio_t clk_mode) { this->clk_mode_ = clk_mode; }
|
||||
void EthernetComponent::set_clk_mode(eth_clock_mode_t clk_mode) { this->clk_mode_ = clk_mode; }
|
||||
void EthernetComponent::set_manual_ip(const ManualIP &manual_ip) { this->manual_ip_ = manual_ip; }
|
||||
|
||||
std::string EthernetComponent::get_use_address() const {
|
||||
@@ -327,4 +305,4 @@ void EthernetComponent::set_use_address(const std::string &use_address) { this->
|
||||
} // namespace ethernet
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
#endif // USE_ESP32_FRAMEWORK_ARDUINO
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/network/ip_address.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include "esp_eth.h"
|
||||
#include "esp_eth_mac.h"
|
||||
#include "esp_netif.h"
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFiType.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace ethernet {
|
||||
|
||||
enum EthernetType {
|
||||
ETHERNET_TYPE_LAN8720 = 0,
|
||||
ETHERNET_TYPE_RTL8201,
|
||||
ETHERNET_TYPE_DP83848,
|
||||
ETHERNET_TYPE_TLK110,
|
||||
ETHERNET_TYPE_IP101,
|
||||
};
|
||||
|
||||
@@ -45,11 +45,11 @@ class EthernetComponent : public Component {
|
||||
bool is_connected();
|
||||
|
||||
void set_phy_addr(uint8_t phy_addr);
|
||||
void set_power_pin(int power_pin);
|
||||
void set_power_pin(GPIOPin *power_pin);
|
||||
void set_mdc_pin(uint8_t mdc_pin);
|
||||
void set_mdio_pin(uint8_t mdio_pin);
|
||||
void set_type(EthernetType type);
|
||||
void set_clk_mode(emac_rmii_clock_gpio_t clk_mode);
|
||||
void set_clk_mode(eth_clock_mode_t clk_mode);
|
||||
void set_manual_ip(const ManualIP &manual_ip);
|
||||
|
||||
network::IPAddress get_ip_address();
|
||||
@@ -57,27 +57,28 @@ class EthernetComponent : public Component {
|
||||
void set_use_address(const std::string &use_address);
|
||||
|
||||
protected:
|
||||
static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
||||
void on_wifi_event_(system_event_id_t event, system_event_info_t info);
|
||||
void start_connect_();
|
||||
void dump_connect_params_();
|
||||
|
||||
static void eth_phy_config_gpio();
|
||||
static void eth_phy_power_enable(bool enable);
|
||||
|
||||
std::string use_address_;
|
||||
uint8_t phy_addr_{0};
|
||||
int power_pin_{-1};
|
||||
GPIOPin *power_pin_{nullptr};
|
||||
uint8_t mdc_pin_{23};
|
||||
uint8_t mdio_pin_{18};
|
||||
EthernetType type_{ETHERNET_TYPE_LAN8720};
|
||||
emac_rmii_clock_gpio_t clk_mode_{EMAC_CLK_IN_GPIO};
|
||||
eth_clock_mode_t clk_mode_{ETH_CLOCK_GPIO0_IN};
|
||||
optional<ManualIP> manual_ip_{};
|
||||
|
||||
bool started_{false};
|
||||
bool connected_{false};
|
||||
EthernetComponentState state_{EthernetComponentState::STOPPED};
|
||||
uint32_t connect_begin_;
|
||||
esp_netif_t *eth_netif_{nullptr};
|
||||
esp_eth_handle_t eth_handle_;
|
||||
eth_config_t eth_config_;
|
||||
eth_phy_power_enable_func orig_power_enable_fun_;
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
@@ -86,4 +87,4 @@ extern EthernetComponent *global_eth_component;
|
||||
} // namespace ethernet
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
#endif // USE_ESP32_FRAMEWORK_ARDUINO
|
||||
|
||||
@@ -12,7 +12,9 @@ namespace ethernet_info {
|
||||
class IPAddressEthernetInfo : public PollingComponent, public text_sensor::TextSensor {
|
||||
public:
|
||||
void update() override {
|
||||
auto ip = ethernet::global_eth_component->get_ip_address();
|
||||
tcpip_adapter_ip_info_t tcpip;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &tcpip);
|
||||
auto ip = tcpip.ip.addr;
|
||||
if (ip != this->last_ip_) {
|
||||
this->last_ip_ = ip;
|
||||
this->publish_state(network::IPAddress(ip).str());
|
||||
|
||||
@@ -14,9 +14,8 @@ static const char *const EZO_CALIBRATION_TYPE_STRINGS[] = {"LOW", "MID", "HIGH"}
|
||||
void EZOSensor::dump_config() {
|
||||
LOG_SENSOR("", "EZO", this);
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
if (this->is_failed())
|
||||
ESP_LOGE(TAG, "Communication with EZO circuit failed!");
|
||||
}
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,8 @@ static const std::string DOSING_MODE_CONTINUOUS = "Continuous";
|
||||
|
||||
void EzoPMP::dump_config() {
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
if (this->is_failed())
|
||||
ESP_LOGE(TAG, "Communication with EZO-PMP circuit failed!");
|
||||
}
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,18 +20,14 @@ const LogString *fan_direction_to_string(FanDirection direction) {
|
||||
void FanCall::perform() {
|
||||
ESP_LOGD(TAG, "'%s' - Setting:", this->parent_.get_name().c_str());
|
||||
this->validate_();
|
||||
if (this->binary_state_.has_value()) {
|
||||
if (this->binary_state_.has_value())
|
||||
ESP_LOGD(TAG, " State: %s", ONOFF(*this->binary_state_));
|
||||
}
|
||||
if (this->oscillating_.has_value()) {
|
||||
if (this->oscillating_.has_value())
|
||||
ESP_LOGD(TAG, " Oscillating: %s", YESNO(*this->oscillating_));
|
||||
}
|
||||
if (this->speed_.has_value()) {
|
||||
if (this->speed_.has_value())
|
||||
ESP_LOGD(TAG, " Speed: %d", *this->speed_);
|
||||
}
|
||||
if (this->direction_.has_value()) {
|
||||
if (this->direction_.has_value())
|
||||
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_)));
|
||||
}
|
||||
|
||||
this->parent_.control(*this);
|
||||
}
|
||||
@@ -94,15 +90,12 @@ void Fan::publish_state() {
|
||||
|
||||
ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str());
|
||||
ESP_LOGD(TAG, " State: %s", ONOFF(this->state));
|
||||
if (traits.supports_speed()) {
|
||||
if (traits.supports_speed())
|
||||
ESP_LOGD(TAG, " Speed: %d", this->speed);
|
||||
}
|
||||
if (traits.supports_oscillation()) {
|
||||
if (traits.supports_oscillation())
|
||||
ESP_LOGD(TAG, " Oscillating: %s", YESNO(this->oscillating));
|
||||
}
|
||||
if (traits.supports_direction()) {
|
||||
if (traits.supports_direction())
|
||||
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
|
||||
}
|
||||
|
||||
this->state_callback_.call();
|
||||
this->save_state_();
|
||||
@@ -154,12 +147,10 @@ void Fan::dump_traits_(const char *tag, const char *prefix) {
|
||||
ESP_LOGCONFIG(tag, "%s Speed: YES", prefix);
|
||||
ESP_LOGCONFIG(tag, "%s Speed count: %d", prefix, this->get_traits().supported_speed_count());
|
||||
}
|
||||
if (this->get_traits().supports_oscillation()) {
|
||||
if (this->get_traits().supports_oscillation())
|
||||
ESP_LOGCONFIG(tag, "%s Oscillation: YES", prefix);
|
||||
}
|
||||
if (this->get_traits().supports_direction()) {
|
||||
if (this->get_traits().supports_direction())
|
||||
ESP_LOGCONFIG(tag, "%s Direction: YES", prefix);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fan
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace fingerprint_grow {
|
||||
|
||||
|
||||
@@ -2,10 +2,20 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import switch
|
||||
from esphome.const import CONF_INTERLOCK, CONF_PIN
|
||||
from esphome.const import CONF_INTERLOCK, CONF_PIN, CONF_RESTORE_MODE
|
||||
from .. import gpio_ns
|
||||
|
||||
GPIOSwitch = gpio_ns.class_("GPIOSwitch", switch.Switch, cg.Component)
|
||||
GPIOSwitchRestoreMode = gpio_ns.enum("GPIOSwitchRestoreMode")
|
||||
|
||||
RESTORE_MODES = {
|
||||
"RESTORE_DEFAULT_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_OFF,
|
||||
"RESTORE_DEFAULT_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_ON,
|
||||
"ALWAYS_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_OFF,
|
||||
"ALWAYS_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON,
|
||||
"RESTORE_INVERTED_DEFAULT_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF,
|
||||
"RESTORE_INVERTED_DEFAULT_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON,
|
||||
}
|
||||
|
||||
CONF_INTERLOCK_WAIT_TIME = "interlock_wait_time"
|
||||
CONFIG_SCHEMA = (
|
||||
@@ -13,6 +23,9 @@ CONFIG_SCHEMA = (
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RESTORE_MODE, default="RESTORE_DEFAULT_OFF"): cv.enum(
|
||||
RESTORE_MODES, upper=True, space="_"
|
||||
),
|
||||
cv.Optional(CONF_INTERLOCK): cv.ensure_list(cv.use_id(switch.Switch)),
|
||||
cv.Optional(
|
||||
CONF_INTERLOCK_WAIT_TIME, default="0ms"
|
||||
@@ -30,6 +43,8 @@ async def to_code(config):
|
||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||
cg.add(var.set_pin(pin))
|
||||
|
||||
cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE]))
|
||||
|
||||
if CONF_INTERLOCK in config:
|
||||
interlock = []
|
||||
for it in config[CONF_INTERLOCK]:
|
||||
|
||||
@@ -10,7 +10,27 @@ float GPIOSwitch::get_setup_priority() const { return setup_priority::HARDWARE;
|
||||
void GPIOSwitch::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up GPIO Switch '%s'...", this->name_.c_str());
|
||||
|
||||
bool initial_state = Switch::get_initial_state_with_restore_mode();
|
||||
bool initial_state = false;
|
||||
switch (this->restore_mode_) {
|
||||
case GPIO_SWITCH_RESTORE_DEFAULT_OFF:
|
||||
initial_state = this->get_initial_state().value_or(false);
|
||||
break;
|
||||
case GPIO_SWITCH_RESTORE_DEFAULT_ON:
|
||||
initial_state = this->get_initial_state().value_or(true);
|
||||
break;
|
||||
case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF:
|
||||
initial_state = !this->get_initial_state().value_or(true);
|
||||
break;
|
||||
case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON:
|
||||
initial_state = !this->get_initial_state().value_or(false);
|
||||
break;
|
||||
case GPIO_SWITCH_ALWAYS_OFF:
|
||||
initial_state = false;
|
||||
break;
|
||||
case GPIO_SWITCH_ALWAYS_ON:
|
||||
initial_state = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// write state before setup
|
||||
if (initial_state) {
|
||||
@@ -29,6 +49,28 @@ void GPIOSwitch::setup() {
|
||||
void GPIOSwitch::dump_config() {
|
||||
LOG_SWITCH("", "GPIO Switch", this);
|
||||
LOG_PIN(" Pin: ", this->pin_);
|
||||
const LogString *restore_mode = LOG_STR("");
|
||||
switch (this->restore_mode_) {
|
||||
case GPIO_SWITCH_RESTORE_DEFAULT_OFF:
|
||||
restore_mode = LOG_STR("Restore (Defaults to OFF)");
|
||||
break;
|
||||
case GPIO_SWITCH_RESTORE_DEFAULT_ON:
|
||||
restore_mode = LOG_STR("Restore (Defaults to ON)");
|
||||
break;
|
||||
case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON:
|
||||
restore_mode = LOG_STR("Restore inverted (Defaults to ON)");
|
||||
break;
|
||||
case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF:
|
||||
restore_mode = LOG_STR("Restore inverted (Defaults to OFF)");
|
||||
break;
|
||||
case GPIO_SWITCH_ALWAYS_OFF:
|
||||
restore_mode = LOG_STR("Always OFF");
|
||||
break;
|
||||
case GPIO_SWITCH_ALWAYS_ON:
|
||||
restore_mode = LOG_STR("Always ON");
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Restore Mode: %s", LOG_STR_ARG(restore_mode));
|
||||
if (!this->interlock_.empty()) {
|
||||
ESP_LOGCONFIG(TAG, " Interlocks:");
|
||||
for (auto *lock : this->interlock_) {
|
||||
@@ -69,6 +111,7 @@ void GPIOSwitch::write_state(bool state) {
|
||||
this->pin_->digital_write(state);
|
||||
this->publish_state(state);
|
||||
}
|
||||
void GPIOSwitch::set_restore_mode(GPIOSwitchRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
|
||||
void GPIOSwitch::set_interlock(const std::vector<Switch *> &interlock) { this->interlock_ = interlock; }
|
||||
|
||||
} // namespace gpio
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user