1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-02 16:11:53 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Jesse Hills
cdce8bb9be Bump api minor version 2024-12-06 16:36:38 +13:00
Jesse Hills
d64cfd18ed [project] Split Project name and manufacturer config 2024-12-06 16:32:07 +13:00
47 changed files with 348 additions and 995 deletions

View File

@@ -65,7 +65,7 @@ jobs:
pip3 install build
python3 -m build
- name: Publish
uses: pypa/gh-action-pypi-publish@v1.12.3
uses: pypa/gh-action-pypi-publish@v1.12.2
deploy-docker:
name: Build ESPHome ${{ matrix.platform }}

View File

@@ -355,7 +355,6 @@ esphome/components/sdl/* @clydebarrow
esphome/components/sdm_meter/* @jesserockz @polyfaces
esphome/components/sdp3x/* @Azimath
esphome/components/seeed_mr24hpc1/* @limengdu
esphome/components/seeed_mr60bha2/* @limengdu
esphome/components/seeed_mr60fda2/* @limengdu
esphome/components/selec_meter/* @sourabhjaiswal
esphome/components/select/* @esphome/core

View File

@@ -169,7 +169,7 @@ ARG BUILD_VERSION=dev
LABEL \
org.opencontainers.image.authors="The ESPHome Authors" \
org.opencontainers.image.title="ESPHome" \
org.opencontainers.image.description="ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems" \
org.opencontainers.image.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \
org.opencontainers.image.url="https://esphome.io/" \
org.opencontainers.image.documentation="https://esphome.io/" \
org.opencontainers.image.source="https://github.com/esphome/esphome" \
@@ -206,7 +206,7 @@ RUN if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
# Labels
LABEL \
io.hass.name="ESPHome" \
io.hass.description="ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems" \
io.hass.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \
io.hass.type="addon" \
io.hass.version="${BUILD_VERSION}"
# io.hass.arch is inherited from addon-debian-base

View File

@@ -1,13 +1,30 @@
#ifdef USE_ESP32
#include "adc_sensor.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#ifdef USE_ESP8266
#ifdef USE_ADC_SENSOR_VCC
#include <Esp.h>
ADC_MODE(ADC_VCC)
#else
#include <Arduino.h>
#endif
#endif
#ifdef USE_RP2040
#ifdef CYW43_USES_VSYS_PIN
#include "pico/cyw43_arch.h"
#endif
#include <hardware/adc.h>
#endif
namespace esphome {
namespace adc {
static const char *const TAG = "adc.esp32";
static const char *const TAG = "adc";
// 13-bit for S2, 12-bit for all other ESP32 variants
#ifdef USE_ESP32
static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
#ifndef SOC_ADC_RTC_MAX_BITWIDTH
@@ -15,15 +32,24 @@ static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_widt
static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 13;
#else
static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
#endif // USE_ESP32_VARIANT_ESP32S2
#endif // SOC_ADC_RTC_MAX_BITWIDTH
#endif
#endif
static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1;
static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1;
static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1; // 4095 (12 bit) or 8191 (13 bit)
static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1; // 2048 (12 bit) or 4096 (13 bit)
#endif
void ADCSensor::setup() {
#ifdef USE_RP2040
extern "C"
#endif
void
ADCSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
#if !defined(USE_ADC_SENSOR_VCC) && !defined(USE_RP2040)
this->pin_->setup();
#endif
#ifdef USE_ESP32
if (this->channel1_ != ADC1_CHANNEL_MAX) {
adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
if (!this->autorange_) {
@@ -35,6 +61,7 @@ void ADCSensor::setup() {
}
}
// load characteristics for each attenuation
for (int32_t i = 0; i <= ADC_ATTEN_DB_12_COMPAT; i++) {
auto adc_unit = this->channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2;
auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
@@ -52,10 +79,31 @@ void ADCSensor::setup() {
break;
}
}
#endif // USE_ESP32
#ifdef USE_RP2040
static bool initialized = false;
if (!initialized) {
adc_init();
initialized = true;
}
#endif
ESP_LOGCONFIG(TAG, "ADC '%s' setup finished!", this->get_name().c_str());
}
void ADCSensor::dump_config() {
LOG_SENSOR("", "ADC Sensor", this);
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
#ifdef USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Pin: VCC");
#else
LOG_PIN(" Pin: ", this->pin_);
#endif
#endif // USE_ESP8266 || USE_LIBRETINY
#ifdef USE_ESP32
LOG_PIN(" Pin: ", this->pin_);
if (this->autorange_) {
ESP_LOGCONFIG(TAG, " Attenuation: auto");
@@ -77,10 +125,55 @@ void ADCSensor::dump_config() {
break;
}
}
#endif // USE_ESP32
#ifdef USE_RP2040
if (this->is_temperature_) {
ESP_LOGCONFIG(TAG, " Pin: Temperature");
} else {
#ifdef USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Pin: VCC");
#else
LOG_PIN(" Pin: ", this->pin_);
#endif // USE_ADC_SENSOR_VCC
}
#endif // USE_RP2040
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
LOG_UPDATE_INTERVAL(this);
}
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
void ADCSensor::update() {
float value_v = this->sample();
ESP_LOGV(TAG, "'%s': Got voltage=%.4fV", this->get_name().c_str(), value_v);
this->publish_state(value_v);
}
void ADCSensor::set_sample_count(uint8_t sample_count) {
if (sample_count != 0) {
this->sample_count_ = sample_count;
}
}
#ifdef USE_ESP8266
float ADCSensor::sample() {
uint32_t raw = 0;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
#ifdef USE_ADC_SENSOR_VCC
raw += ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
#else
raw += analogRead(this->pin_->get_pin()); // NOLINT
#endif
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
if (this->output_raw_) {
return raw;
}
return raw / 1024.0f;
}
#endif
#ifdef USE_ESP32
float ADCSensor::sample() {
if (!this->autorange_) {
uint32_t sum = 0;
@@ -147,17 +240,93 @@ float ADCSensor::sample() {
uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_2_5]);
uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_0]);
// Contribution of each value, in range 0-2048 (12 bit ADC) or 0-4096 (13 bit ADC)
uint32_t c12 = std::min(raw12, ADC_HALF);
uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF);
uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF);
uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF);
// max theoretical csum value is 4096*4 = 16384
uint32_t csum = c12 + c6 + c2 + c0;
// each mv is max 3900; so max value is 3900*4096*4, fits in unsigned32
uint32_t mv_scaled = (mv12 * c12) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
return mv_scaled / (float) (csum * 1000U);
}
#endif // USE_ESP32
#ifdef USE_RP2040
float ADCSensor::sample() {
if (this->is_temperature_) {
adc_set_temp_sensor_enabled(true);
delay(1);
adc_select_input(4);
uint32_t raw = 0;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += adc_read();
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
adc_set_temp_sensor_enabled(false);
if (this->output_raw_) {
return raw;
}
return raw * 3.3f / 4096.0f;
} else {
uint8_t pin = this->pin_->get_pin();
#ifdef CYW43_USES_VSYS_PIN
if (pin == PICO_VSYS_PIN) {
// Measuring VSYS on Raspberry Pico W needs to be wrapped with
// `cyw43_thread_enter()`/`cyw43_thread_exit()` as discussed in
// https://github.com/raspberrypi/pico-sdk/issues/1222, since Wifi chip and
// VSYS ADC both share GPIO29
cyw43_thread_enter();
}
#endif // CYW43_USES_VSYS_PIN
adc_gpio_init(pin);
adc_select_input(pin - 26);
uint32_t raw = 0;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += adc_read();
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
#ifdef CYW43_USES_VSYS_PIN
if (pin == PICO_VSYS_PIN) {
cyw43_thread_exit();
}
#endif // CYW43_USES_VSYS_PIN
if (this->output_raw_) {
return raw;
}
float coeff = pin == PICO_VSYS_PIN ? 3.0 : 1.0;
return raw * 3.3f / 4096.0f * coeff;
}
}
#endif
#ifdef USE_LIBRETINY
float ADCSensor::sample() {
uint32_t raw = 0;
if (this->output_raw_) {
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += analogRead(this->pin_->get_pin()); // NOLINT
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
return raw;
}
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += analogReadVoltage(this->pin_->get_pin()); // NOLINT
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
return raw / 1000.0f;
}
#endif // USE_LIBRETINY
#ifdef USE_ESP8266
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
#endif
} // namespace adc
} // namespace esphome
#endif // USE_ESP32

View File

@@ -3,12 +3,13 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/voltage_sampler/voltage_sampler.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include "esphome/core/hal.h"
#ifdef USE_ESP32
#include <esp_adc_cal.h>
#include "driver/adc.h"
#endif // USE_ESP32
#endif
namespace esphome {
namespace adc {
@@ -42,7 +43,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
this->channel1_ = ADC1_CHANNEL_MAX;
}
void set_autorange(bool autorange) { this->autorange_ = autorange; }
#endif // USE_ESP32
#endif
/// Update ADC values
void update() override;
@@ -58,11 +59,11 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
#ifdef USE_ESP8266
std::string unique_id() override;
#endif // USE_ESP8266
#endif
#ifdef USE_RP2040
void set_is_temperature() { this->is_temperature_ = true; }
#endif // USE_RP2040
#endif
protected:
InternalGPIOPin *pin_;
@@ -71,7 +72,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
#ifdef USE_RP2040
bool is_temperature_{false};
#endif // USE_RP2040
#endif
#ifdef USE_ESP32
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
@@ -82,8 +83,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM] = {};
#else
esp_adc_cal_characteristics_t cal_characteristics_[ADC_ATTEN_MAX] = {};
#endif // ESP_IDF_VERSION_MAJOR
#endif // USE_ESP32
#endif
#endif
};
} // namespace adc

View File

@@ -1,24 +0,0 @@
#include "adc_sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc {
static const char *const TAG = "adc.common";
void ADCSensor::update() {
float value_v = this->sample();
ESP_LOGV(TAG, "'%s': Got voltage=%.4fV", this->get_name().c_str(), value_v);
this->publish_state(value_v);
}
void ADCSensor::set_sample_count(uint8_t sample_count) {
if (sample_count != 0) {
this->sample_count_ = sample_count;
}
}
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
} // namespace adc
} // namespace esphome

View File

@@ -1,58 +0,0 @@
#ifdef USE_ESP8266
#include "adc_sensor.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#ifdef USE_ADC_SENSOR_VCC
#include <Esp.h>
ADC_MODE(ADC_VCC)
#else
#include <Arduino.h>
#endif // USE_ADC_SENSOR_VCC
namespace esphome {
namespace adc {
static const char *const TAG = "adc.esp8266";
void ADCSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
#ifndef USE_ADC_SENSOR_VCC
this->pin_->setup();
#endif
}
void ADCSensor::dump_config() {
LOG_SENSOR("", "ADC Sensor", this);
#ifdef USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Pin: VCC");
#else
LOG_PIN(" Pin: ", this->pin_);
#endif // USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
LOG_UPDATE_INTERVAL(this);
}
float ADCSensor::sample() {
uint32_t raw = 0;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
#ifdef USE_ADC_SENSOR_VCC
raw += ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
#else
raw += analogRead(this->pin_->get_pin()); // NOLINT
#endif // USE_ADC_SENSOR_VCC
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
if (this->output_raw_) {
return raw;
}
return raw / 1024.0f;
}
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
} // namespace adc
} // namespace esphome
#endif // USE_ESP8266

View File

@@ -1,48 +0,0 @@
#ifdef USE_LIBRETINY
#include "adc_sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc {
static const char *const TAG = "adc.libretiny";
void ADCSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
#ifndef USE_ADC_SENSOR_VCC
this->pin_->setup();
#endif // !USE_ADC_SENSOR_VCC
}
void ADCSensor::dump_config() {
LOG_SENSOR("", "ADC Sensor", this);
#ifdef USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Pin: VCC");
#else // USE_ADC_SENSOR_VCC
LOG_PIN(" Pin: ", this->pin_);
#endif // USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
LOG_UPDATE_INTERVAL(this);
}
float ADCSensor::sample() {
uint32_t raw = 0;
if (this->output_raw_) {
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += analogRead(this->pin_->get_pin()); // NOLINT
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
return raw;
}
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += analogReadVoltage(this->pin_->get_pin()); // NOLINT
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
return raw / 1000.0f;
}
} // namespace adc
} // namespace esphome
#endif // USE_LIBRETINY

View File

@@ -1,93 +0,0 @@
#ifdef USE_RP2040
#include "adc_sensor.h"
#include "esphome/core/log.h"
#ifdef CYW43_USES_VSYS_PIN
#include "pico/cyw43_arch.h"
#endif // CYW43_USES_VSYS_PIN
#include <hardware/adc.h>
namespace esphome {
namespace adc {
static const char *const TAG = "adc.rp2040";
void ADCSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
static bool initialized = false;
if (!initialized) {
adc_init();
initialized = true;
}
}
void ADCSensor::dump_config() {
LOG_SENSOR("", "ADC Sensor", this);
if (this->is_temperature_) {
ESP_LOGCONFIG(TAG, " Pin: Temperature");
} else {
#ifdef USE_ADC_SENSOR_VCC
ESP_LOGCONFIG(TAG, " Pin: VCC");
#else
LOG_PIN(" Pin: ", this->pin_);
#endif // USE_ADC_SENSOR_VCC
}
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
LOG_UPDATE_INTERVAL(this);
}
float ADCSensor::sample() {
if (this->is_temperature_) {
adc_set_temp_sensor_enabled(true);
delay(1);
adc_select_input(4);
uint32_t raw = 0;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += adc_read();
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
adc_set_temp_sensor_enabled(false);
if (this->output_raw_) {
return raw;
}
return raw * 3.3f / 4096.0f;
}
uint8_t pin = this->pin_->get_pin();
#ifdef CYW43_USES_VSYS_PIN
if (pin == PICO_VSYS_PIN) {
// Measuring VSYS on Raspberry Pico W needs to be wrapped with
// `cyw43_thread_enter()`/`cyw43_thread_exit()` as discussed in
// https://github.com/raspberrypi/pico-sdk/issues/1222, since Wifi chip and
// VSYS ADC both share GPIO29
cyw43_thread_enter();
}
#endif // CYW43_USES_VSYS_PIN
adc_gpio_init(pin);
adc_select_input(pin - 26);
uint32_t raw = 0;
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
raw += adc_read();
}
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
#ifdef CYW43_USES_VSYS_PIN
if (pin == PICO_VSYS_PIN) {
cyw43_thread_exit();
}
#endif // CYW43_USES_VSYS_PIN
if (this->output_raw_) {
return raw;
}
float coeff = pin == PICO_VSYS_PIN ? 3.0f : 1.0f;
return raw * 3.3f / 4096.0f * coeff;
}
} // namespace adc
} // namespace esphome
#endif // USE_RP2040

View File

@@ -213,6 +213,7 @@ message DeviceInfoResponse {
// The esphome project details if set
string project_name = 8;
string project_version = 9;
string project_manufacturer = 18;
uint32 webserver_port = 10;

View File

@@ -1429,7 +1429,7 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) {
HelloResponse resp;
resp.api_version_major = 1;
resp.api_version_minor = 10;
resp.api_version_minor = 11;
resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
resp.name = App.get_name();
@@ -1479,7 +1479,13 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
resp.has_deep_sleep = deep_sleep::global_has_deep_sleep;
#endif
#ifdef ESPHOME_PROJECT_NAME
resp.project_name = ESPHOME_PROJECT_NAME;
if (this->client_api_version_major_ > 1 ||
(this->client_api_version_major_ == 1 && this->client_api_version_minor_ >= 11)) {
resp.project_name = ESPHOME_PROJECT_NAME;
resp.project_manufacturer = ESPHOME_PROJECT_MANUFACTURER;
} else {
resp.project_name = ESPHOME_PROJECT_MANUFACTURER "." ESPHOME_PROJECT_NAME;
}
resp.project_version = ESPHOME_PROJECT_VERSION;
#endif
#ifdef USE_WEBSERVER

View File

@@ -826,6 +826,10 @@ bool DeviceInfoResponse::decode_length(uint32_t field_id, ProtoLengthDelimited v
this->project_version = value.as_string();
return true;
}
case 18: {
this->project_manufacturer = value.as_string();
return true;
}
case 12: {
this->manufacturer = value.as_string();
return true;
@@ -852,6 +856,7 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_bool(7, this->has_deep_sleep);
buffer.encode_string(8, this->project_name);
buffer.encode_string(9, this->project_version);
buffer.encode_string(18, this->project_manufacturer);
buffer.encode_uint32(10, this->webserver_port);
buffer.encode_uint32(11, this->legacy_bluetooth_proxy_version);
buffer.encode_uint32(15, this->bluetooth_proxy_feature_flags);
@@ -901,6 +906,10 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
out.append("'").append(this->project_version).append("'");
out.append("\n");
out.append(" project_manufacturer: ");
out.append("'").append(this->project_manufacturer).append("'");
out.append("\n");
out.append(" webserver_port: ");
sprintf(buffer, "%" PRIu32, this->webserver_port);
out.append(buffer);

View File

@@ -346,6 +346,7 @@ class DeviceInfoResponse : public ProtoMessage {
bool has_deep_sleep{false};
std::string project_name{};
std::string project_version{};
std::string project_manufacturer{};
uint32_t webserver_port{0};
uint32_t legacy_bluetooth_proxy_version{0};
uint32_t bluetooth_proxy_feature_flags{0};

View File

@@ -1,6 +1,6 @@
#include "display.h"
#include <utility>
#include "display_color_utils.h"
#include <utility>
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
@@ -670,7 +670,7 @@ void Display::strftime(int x, int y, BaseFont *font, Color color, Color backgrou
this->print(x, y, font, color, align, buffer, background);
}
void Display::strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time) {
this->strftime(x, y, font, color, COLOR_OFF, align, format, time);
this->strftime(x, y, font, color, COLOR_OFF, TextAlign::TOP_LEFT, format, time);
}
void Display::strftime(int x, int y, BaseFont *font, Color color, const char *format, ESPTime time) {
this->strftime(x, y, font, color, COLOR_OFF, TextAlign::TOP_LEFT, format, time);

View File

@@ -1,12 +1,4 @@
from .const import (
VARIANT_ESP32,
VARIANT_ESP32C2,
VARIANT_ESP32C3,
VARIANT_ESP32C6,
VARIANT_ESP32H2,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
)
from .const import VARIANT_ESP32, VARIANT_ESP32C3, VARIANT_ESP32S2, VARIANT_ESP32S3
ESP32_BASE_PINS = {
"TX": 1,
@@ -1352,26 +1344,6 @@ done | sort
"""
BOARDS = {
"4d_systems_esp32s3_gen4_r8n16": {
"name": "4D Systems GEN4-ESP32 16MB (ESP32S3-R8N16)",
"variant": VARIANT_ESP32S3,
},
"adafruit_camera_esp32s3": {
"name": "Adafruit pyCamera S3",
"variant": VARIANT_ESP32S3,
},
"adafruit_feather_esp32c6": {
"name": "Adafruit Feather ESP32-C6",
"variant": VARIANT_ESP32C6,
},
"adafruit_feather_esp32s2": {
"name": "Adafruit Feather ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"adafruit_feather_esp32s2_reversetft": {
"name": "Adafruit Feather ESP32-S2 Reverse TFT",
"variant": VARIANT_ESP32S2,
},
"adafruit_feather_esp32s2_tft": {
"name": "Adafruit Feather ESP32-S2 TFT",
"variant": VARIANT_ESP32S2,
@@ -1384,10 +1356,6 @@ BOARDS = {
"name": "Adafruit Feather ESP32-S3 No PSRAM",
"variant": VARIANT_ESP32S3,
},
"adafruit_feather_esp32s3_reversetft": {
"name": "Adafruit Feather ESP32-S3 Reverse TFT",
"variant": VARIANT_ESP32S3,
},
"adafruit_feather_esp32s3_tft": {
"name": "Adafruit Feather ESP32-S3 TFT",
"variant": VARIANT_ESP32S3,
@@ -1408,18 +1376,10 @@ BOARDS = {
"name": "Adafruit MagTag 2.9",
"variant": VARIANT_ESP32S2,
},
"adafruit_matrixportal_esp32s3": {
"name": "Adafruit MatrixPortal ESP32-S3",
"variant": VARIANT_ESP32S3,
},
"adafruit_metro_esp32s2": {
"name": "Adafruit Metro ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"adafruit_metro_esp32s3": {
"name": "Adafruit Metro ESP32-S3",
"variant": VARIANT_ESP32S3,
},
"adafruit_qtpy_esp32c3": {
"name": "Adafruit QT Py ESP32-C3",
"variant": VARIANT_ESP32C3,
@@ -1432,18 +1392,10 @@ BOARDS = {
"name": "Adafruit QT Py ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"adafruit_qtpy_esp32s3_n4r2": {
"name": "Adafruit QT Py ESP32-S3 (4M Flash 2M PSRAM)",
"variant": VARIANT_ESP32S3,
},
"adafruit_qtpy_esp32s3_nopsram": {
"name": "Adafruit QT Py ESP32-S3 No PSRAM",
"variant": VARIANT_ESP32S3,
},
"adafruit_qualia_s3_rgb666": {
"name": "Adafruit Qualia ESP32-S3 RGB666",
"variant": VARIANT_ESP32S3,
},
"airm2m_core_esp32c3": {
"name": "AirM2M CORE ESP32C3",
"variant": VARIANT_ESP32C3,
@@ -1452,30 +1404,14 @@ BOARDS = {
"name": "ALKS ESP32",
"variant": VARIANT_ESP32,
},
"arduino_nano_esp32": {
"name": "Arduino Nano ESP32",
"variant": VARIANT_ESP32S3,
},
"atd147_s3": {
"name": "ArtronShop ATD1.47-S3",
"variant": VARIANT_ESP32S3,
},
"atmegazero_esp32s2": {
"name": "EspinalLab ATMegaZero ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"aventen_s3_sync": {
"name": "Aventen S3 Sync",
"variant": VARIANT_ESP32S3,
},
"az-delivery-devkit-v4": {
"name": "AZ-Delivery ESP-32 Dev Kit C V4",
"variant": VARIANT_ESP32,
},
"bee_data_logger": {
"name": "Smart Bee Data Logger",
"variant": VARIANT_ESP32S3,
},
"bee_motion_mini": {
"name": "Smart Bee Motion Mini",
"variant": VARIANT_ESP32C3,
@@ -1500,6 +1436,14 @@ BOARDS = {
"name": "BPI-Leaf-S3",
"variant": VARIANT_ESP32S3,
},
"briki_abc_esp32": {
"name": "Briki ABC (MBC-WB) - ESP32",
"variant": VARIANT_ESP32,
},
"briki_mbc-wb_esp32": {
"name": "Briki MBC-WB - ESP32",
"variant": VARIANT_ESP32,
},
"cnrs_aw2eth": {
"name": "CNRS AW2ETH",
"variant": VARIANT_ESP32,
@@ -1552,38 +1496,18 @@ BOARDS = {
"name": "DFRobot Beetle ESP32-C3",
"variant": VARIANT_ESP32C3,
},
"dfrobot_firebeetle2_esp32e": {
"name": "DFRobot Firebeetle 2 ESP32-E",
"variant": VARIANT_ESP32,
},
"dfrobot_firebeetle2_esp32s3": {
"name": "DFRobot Firebeetle 2 ESP32-S3",
"variant": VARIANT_ESP32S3,
},
"dfrobot_romeo_esp32s3": {
"name": "DFRobot Romeo ESP32-S3",
"variant": VARIANT_ESP32S3,
},
"dpu_esp32": {
"name": "TAMC DPU ESP32",
"variant": VARIANT_ESP32,
},
"edgebox-esp-100": {
"name": "Seeed Studio Edgebox-ESP-100",
"variant": VARIANT_ESP32S3,
},
"esp320": {
"name": "Electronic SweetPeas ESP320",
"variant": VARIANT_ESP32,
},
"esp32-c2-devkitm-1": {
"name": "Espressif ESP32-C2-DevKitM-1",
"variant": VARIANT_ESP32C2,
},
"esp32-c3-devkitc-02": {
"name": "Espressif ESP32-C3-DevKitC-02",
"variant": VARIANT_ESP32C3,
},
"esp32-c3-devkitm-1": {
"name": "Espressif ESP32-C3-DevKitM-1",
"variant": VARIANT_ESP32C3,
@@ -1592,14 +1516,6 @@ BOARDS = {
"name": "Ai-Thinker ESP-C3-M1-I-Kit",
"variant": VARIANT_ESP32C3,
},
"esp32-c6-devkitc-1": {
"name": "Espressif ESP32-C6-DevKitC-1",
"variant": VARIANT_ESP32C6,
},
"esp32-c6-devkitm-1": {
"name": "Espressif ESP32-C6-DevKitM-1",
"variant": VARIANT_ESP32C6,
},
"esp32cam": {
"name": "AI Thinker ESP32-CAM",
"variant": VARIANT_ESP32,
@@ -1628,14 +1544,6 @@ BOARDS = {
"name": "OLIMEX ESP32-GATEWAY",
"variant": VARIANT_ESP32,
},
"esp32-h2-devkitm-1": {
"name": "Espressif ESP32-H2-DevKit",
"variant": VARIANT_ESP32H2,
},
"esp32-pico-devkitm-2": {
"name": "Espressif ESP32-PICO-DevKitM-2",
"variant": VARIANT_ESP32,
},
"esp32-poe-iso": {
"name": "OLIMEX ESP32-PoE-ISO",
"variant": VARIANT_ESP32,
@@ -1672,22 +1580,10 @@ BOARDS = {
"name": "Espressif ESP32-S3-DevKitC-1-N8 (8 MB QD, No PSRAM)",
"variant": VARIANT_ESP32S3,
},
"esp32-s3-devkitm-1": {
"name": "Espressif ESP32-S3-DevKitM-1",
"esp32-s3-korvo-2": {
"name": "Espressif ESP32-S3-Korvo-2",
"variant": VARIANT_ESP32S3,
},
"esp32s3_powerfeather": {
"name": "ESP32-S3 PowerFeather",
"variant": VARIANT_ESP32S3,
},
"esp32s3usbotg": {
"name": "Espressif ESP32-S3-USB-OTG",
"variant": VARIANT_ESP32S3,
},
"esp32-solo1": {
"name": "Espressif Generic ESP32-solo1 4M Flash",
"variant": VARIANT_ESP32,
},
"esp32thing": {
"name": "SparkFun ESP32 Thing",
"variant": VARIANT_ESP32,
@@ -1756,9 +1652,9 @@ BOARDS = {
"name": "Heltec WiFi Kit 32",
"variant": VARIANT_ESP32,
},
"heltec_wifi_kit_32_V3": {
"name": "Heltec WiFi Kit 32 (V3)",
"variant": VARIANT_ESP32S3,
"heltec_wifi_kit_32_v2": {
"name": "Heltec WiFi Kit 32 (V2)",
"variant": VARIANT_ESP32,
},
"heltec_wifi_lora_32": {
"name": "Heltec WiFi LoRa 32",
@@ -1768,10 +1664,6 @@ BOARDS = {
"name": "Heltec WiFi LoRa 32 (V2)",
"variant": VARIANT_ESP32,
},
"heltec_wifi_lora_32_V3": {
"name": "Heltec WiFi LoRa 32 (V3)",
"variant": VARIANT_ESP32S3,
},
"heltec_wireless_stick_lite": {
"name": "Heltec Wireless Stick Lite",
"variant": VARIANT_ESP32,
@@ -1816,14 +1708,6 @@ BOARDS = {
"name": "oddWires IoT-Bus Proteus",
"variant": VARIANT_ESP32,
},
"ioxesp32": {
"name": "ArtronShop IOXESP32",
"variant": VARIANT_ESP32,
},
"ioxesp32ps": {
"name": "ArtronShop IOXESP32PS",
"variant": VARIANT_ESP32,
},
"kb32-ft": {
"name": "MakerAsia KB32-FT",
"variant": VARIANT_ESP32,
@@ -1836,26 +1720,10 @@ BOARDS = {
"name": "Labplus mPython",
"variant": VARIANT_ESP32,
},
"lilka_v2": {
"name": "Lilka v2",
"variant": VARIANT_ESP32S3,
},
"lilygo-t-display": {
"name": "LilyGo T-Display",
"variant": VARIANT_ESP32,
},
"lilygo-t-display-s3": {
"name": "LilyGo T-Display-S3",
"variant": VARIANT_ESP32S3,
},
"lionbit": {
"name": "Lion:Bit Dev Board",
"variant": VARIANT_ESP32,
},
"lionbits3": {
"name": "Lion:Bit S3 STEM Dev Board",
"variant": VARIANT_ESP32S3,
},
"lolin32_lite": {
"name": "WEMOS LOLIN32 Lite",
"variant": VARIANT_ESP32,
@@ -1884,18 +1752,10 @@ BOARDS = {
"name": "WEMOS LOLIN S2 PICO",
"variant": VARIANT_ESP32S2,
},
"lolin_s3_mini": {
"name": "WEMOS LOLIN S3 Mini",
"variant": VARIANT_ESP32S3,
},
"lolin_s3": {
"name": "WEMOS LOLIN S3",
"variant": VARIANT_ESP32S3,
},
"lolin_s3_pro": {
"name": "WEMOS LOLIN S3 PRO",
"variant": VARIANT_ESP32S3,
},
"lopy4": {
"name": "Pycom LoPy4",
"variant": VARIANT_ESP32,
@@ -1908,18 +1768,10 @@ BOARDS = {
"name": "M5Stack-ATOM",
"variant": VARIANT_ESP32,
},
"m5stack-atoms3": {
"name": "M5Stack AtomS3",
"variant": VARIANT_ESP32S3,
},
"m5stack-core2": {
"name": "M5Stack Core2",
"variant": VARIANT_ESP32,
},
"m5stack-core-esp32-16M": {
"name": "M5Stack Core ESP32 16M",
"variant": VARIANT_ESP32,
},
"m5stack-core-esp32": {
"name": "M5Stack Core ESP32",
"variant": VARIANT_ESP32,
@@ -1928,10 +1780,6 @@ BOARDS = {
"name": "M5Stack-Core Ink",
"variant": VARIANT_ESP32,
},
"m5stack-cores3": {
"name": "M5Stack CoreS3",
"variant": VARIANT_ESP32S3,
},
"m5stack-fire": {
"name": "M5Stack FIRE",
"variant": VARIANT_ESP32,
@@ -1940,14 +1788,6 @@ BOARDS = {
"name": "M5Stack GREY ESP32",
"variant": VARIANT_ESP32,
},
"m5stack_paper": {
"name": "M5Stack Paper",
"variant": VARIANT_ESP32,
},
"m5stack-stamps3": {
"name": "M5Stack StampS3",
"variant": VARIANT_ESP32S3,
},
"m5stack-station": {
"name": "M5Stack Station",
"variant": VARIANT_ESP32,
@@ -1956,10 +1796,6 @@ BOARDS = {
"name": "M5Stack Timer CAM",
"variant": VARIANT_ESP32,
},
"m5stamp-pico": {
"name": "M5Stamp-Pico",
"variant": VARIANT_ESP32,
},
"m5stick-c": {
"name": "M5Stick-C",
"variant": VARIANT_ESP32,
@@ -1996,26 +1832,10 @@ BOARDS = {
"name": "Deparment of Alchemy MiniMain ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"motorgo_mini_1": {
"name": "MotorGo Mini 1 (ESP32-S3)",
"variant": VARIANT_ESP32S3,
},
"namino_arancio": {
"name": "Namino Arancio",
"variant": VARIANT_ESP32S3,
},
"namino_rosso": {
"name": "Namino Rosso",
"variant": VARIANT_ESP32S3,
},
"nano32": {
"name": "MakerAsia Nano32",
"variant": VARIANT_ESP32,
},
"nebulas3": {
"name": "Kinetic Dynamics Nebula S3",
"variant": VARIANT_ESP32S3,
},
"nina_w10": {
"name": "u-blox NINA-W10 series",
"variant": VARIANT_ESP32,
@@ -2076,22 +1896,10 @@ BOARDS = {
"name": "Munich Labs RedPill ESP32-S3",
"variant": VARIANT_ESP32S3,
},
"roboheart_hercules": {
"name": "RoboHeart Hercules",
"variant": VARIANT_ESP32,
},
"seeed_xiao_esp32c3": {
"name": "Seeed Studio XIAO ESP32C3",
"variant": VARIANT_ESP32C3,
},
"seeed_xiao_esp32s3": {
"name": "Seeed Studio XIAO ESP32S3",
"variant": VARIANT_ESP32S3,
},
"sensebox_mcu_esp32s2": {
"name": "senseBox MCU-S2 ESP32-S2",
"variant": VARIANT_ESP32S2,
},
"sensesiot_weizen": {
"name": "LOGISENSES Senses Weizen",
"variant": VARIANT_ESP32,
@@ -2104,10 +1912,6 @@ BOARDS = {
"name": "S.ODI Ultra v1",
"variant": VARIANT_ESP32,
},
"sparkfun_esp32c6_thing_plus": {
"name": "Sparkfun ESP32-C6 Thing Plus",
"variant": VARIANT_ESP32C6,
},
"sparkfun_esp32_iot_redboard": {
"name": "SparkFun ESP32 IoT RedBoard",
"variant": VARIANT_ESP32,
@@ -2200,10 +2004,6 @@ BOARDS = {
"name": "Unexpected Maker FeatherS3",
"variant": VARIANT_ESP32S3,
},
"um_nanos3": {
"name": "Unexpected Maker NanoS3",
"variant": VARIANT_ESP32S3,
},
"um_pros3": {
"name": "Unexpected Maker PROS3",
"variant": VARIANT_ESP32S3,
@@ -2240,14 +2040,6 @@ BOARDS = {
"name": "uPesy ESP32 Wrover DevKit",
"variant": VARIANT_ESP32,
},
"valtrack_v4_mfw_esp32_c3": {
"name": "Valetron Systems VALTRACK-V4MVF",
"variant": VARIANT_ESP32C3,
},
"valtrack_v4_vts_esp32_c3": {
"name": "Valetron Systems VALTRACK-V4VTS",
"variant": VARIANT_ESP32C3,
},
"vintlabs-devkit-v1": {
"name": "VintLabs ESP32 Devkit",
"variant": VARIANT_ESP32,

View File

@@ -27,9 +27,6 @@ namespace esp32_ble {
static const char *const TAG = "esp32_ble";
static RAMAllocator<BLEEvent> EVENT_ALLOCATOR( // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
RAMAllocator<BLEEvent>::ALLOW_FAILURE | RAMAllocator<BLEEvent>::ALLOC_INTERNAL);
void ESP32BLE::setup() {
global_ble = this;
ESP_LOGCONFIG(TAG, "Setting up BLE...");
@@ -325,8 +322,7 @@ void ESP32BLE::loop() {
default:
break;
}
ble_event->~BLEEvent();
EVENT_ALLOCATOR.deallocate(ble_event, 1);
delete ble_event; // NOLINT(cppcoreguidelines-owning-memory)
ble_event = this->ble_events_.pop();
}
if (this->advertising_ != nullptr) {
@@ -335,14 +331,9 @@ void ESP32BLE::loop() {
}
void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
if (new_event == nullptr) {
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
return;
}
new (new_event) BLEEvent(event, param);
BLEEvent *new_event = new BLEEvent(event, param); // NOLINT(cppcoreguidelines-owning-memory)
global_ble->ble_events_.push(new_event);
} // NOLINT(clang-analyzer-unix.Malloc)
} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
ESP_LOGV(TAG, "(BLE) gap_event_handler - %d", event);
@@ -353,14 +344,9 @@ void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap
void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param) {
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
if (new_event == nullptr) {
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
return;
}
new (new_event) BLEEvent(event, gatts_if, param);
BLEEvent *new_event = new BLEEvent(event, gatts_if, param); // NOLINT(cppcoreguidelines-owning-memory)
global_ble->ble_events_.push(new_event);
} // NOLINT(clang-analyzer-unix.Malloc)
} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param) {
@@ -372,14 +358,9 @@ void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if
void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) {
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
if (new_event == nullptr) {
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
return;
}
new (new_event) BLEEvent(event, gattc_if, param);
BLEEvent *new_event = new BLEEvent(event, gattc_if, param); // NOLINT(cppcoreguidelines-owning-memory)
global_ble->ble_events_.push(new_event);
} // NOLINT(clang-analyzer-unix.Malloc)
} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) {

View File

@@ -51,11 +51,8 @@ CONF_IGNORE_MISSING_GLYPHS = "ignore_missing_glyphs"
# Cache loaded freetype fonts
class FontCache(dict):
def __missing__(self, key):
try:
res = self[key] = freetype.Face(key)
return res
except freetype.FT_Exception as e:
raise cv.Invalid(f"Could not load Font file {key}: {e}") from e
res = self[key] = freetype.Face(key)
return res
FONT_CACHE = FontCache()

View File

@@ -133,11 +133,9 @@ void Font::print(int x_start, int y_start, display::Display *display, Color colo
auto diff_r = (float) color.r - (float) background.r;
auto diff_g = (float) color.g - (float) background.g;
auto diff_b = (float) color.b - (float) background.b;
auto diff_w = (float) color.w - (float) background.w;
auto b_r = (float) background.r;
auto b_g = (float) background.g;
auto b_b = (float) background.b;
auto b_w = (float) background.w;
auto b_b = (float) background.g;
for (int glyph_y = y_start + scan_y1; glyph_y != max_y; glyph_y++) {
for (int glyph_x = x_at + scan_x1; glyph_x != max_x; glyph_x++) {
uint8_t pixel = 0;
@@ -155,8 +153,8 @@ void Font::print(int x_start, int y_start, display::Display *display, Color colo
display->draw_pixel_at(glyph_x, glyph_y, color);
} else if (pixel != 0) {
auto on = (float) pixel / (float) bpp_max;
auto blended = Color((uint8_t) (diff_r * on + b_r), (uint8_t) (diff_g * on + b_g),
(uint8_t) (diff_b * on + b_b), (uint8_t) (diff_w * on + b_w));
auto blended =
Color((uint8_t) (diff_r * on + b_r), (uint8_t) (diff_g * on + b_g), (uint8_t) (diff_b * on + b_b));
display->draw_pixel_at(glyph_x, glyph_y, blended);
}
}

View File

@@ -17,14 +17,14 @@ void IDFI2CBus::setup() {
ESP_LOGCONFIG(TAG, "Setting up I2C bus...");
static i2c_port_t next_port = I2C_NUM_0;
port_ = next_port;
#if SOC_I2C_NUM > 1
#if I2C_NUM_MAX > 1
next_port = (next_port == I2C_NUM_0) ? I2C_NUM_1 : I2C_NUM_MAX;
#else
next_port = I2C_NUM_MAX;
#endif
if (port_ == I2C_NUM_MAX) {
ESP_LOGE(TAG, "Too many I2C buses configured. Max %u supported.", SOC_I2C_NUM);
ESP_LOGE(TAG, "Too many I2C buses configured");
this->mark_failed();
return;
}

View File

@@ -247,7 +247,7 @@ void I2SAudioSpeaker::speaker_task(void *params) {
// Ensure ring buffer is at least as large as the total size of the DMA buffers
const size_t ring_buffer_size =
std::max((uint32_t) dma_buffers_size, this_speaker->buffer_duration_ms_ * bytes_per_ms);
std::min((uint32_t) dma_buffers_size, this_speaker->buffer_duration_ms_ * bytes_per_ms);
if (this_speaker->send_esp_err_to_event_group_(this_speaker->allocate_buffers_(dma_buffers_size, ring_buffer_size))) {
// Failed to allocate buffers

View File

@@ -168,7 +168,6 @@ LV_EVENT_MAP = {
"READY": "READY",
"CANCEL": "CANCEL",
"ALL_EVENTS": "ALL",
"CHANGE": "VALUE_CHANGED",
}
LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)

View File

@@ -79,7 +79,7 @@ class ImgType(WidgetType):
if CONF_ANTIALIAS in config:
lv.img_set_antialias(w.obj, config[CONF_ANTIALIAS])
if mode := config.get(CONF_MODE):
await w.set_property("size_mode", mode)
lv.img_set_mode(w.obj, mode)
img_spec = ImgType()

View File

@@ -152,9 +152,9 @@ void ModbusController::on_modbus_read_registers(uint8_t function_code, uint16_t
}
SensorSet ModbusController::find_sensors_(ModbusRegisterType register_type, uint16_t start_address) const {
auto reg_it = std::find_if(
std::begin(this->register_ranges_), std::end(this->register_ranges_),
[=](RegisterRange const &r) { return (r.start_address == start_address && r.register_type == register_type); });
auto reg_it = find_if(begin(this->register_ranges_), end(this->register_ranges_), [=](RegisterRange const &r) {
return (r.start_address == start_address && r.register_type == register_type);
});
if (reg_it == this->register_ranges_.end()) {
ESP_LOGE(TAG, "No matching range for sensor found - start_address : 0x%X", start_address);
@@ -375,12 +375,12 @@ void ModbusController::loop() {
if (!this->incoming_queue_.empty()) {
auto &message = this->incoming_queue_.front();
if (message != nullptr)
this->process_modbus_data_(message.get());
process_modbus_data_(message.get());
this->incoming_queue_.pop();
} else {
// all messages processed send pending commands
this->send_next_command_();
send_next_command_();
}
}

View File

@@ -97,7 +97,7 @@ void ModbusSwitch::write_state(bool state) {
}
}
this->parent_->queue_command(cmd);
this->publish_state(state);
publish_state(state);
}
// ModbusSwitch end
} // namespace modbus_controller

View File

@@ -81,39 +81,16 @@ void QMC5883LComponent::dump_config() {
}
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
void QMC5883LComponent::update() {
i2c::ErrorCode err;
uint8_t status = false;
// Status byte gets cleared when data is read, so we have to read this first.
// If status and two axes are desired, it's possible to save one byte of traffic by enabling
// ROL_PNT in setup and reading 7 bytes starting at the status register.
// If status and all three axes are desired, using ROL_PNT saves you 3 bytes.
// But simply not reading status saves you 4 bytes always and is much simpler.
if (ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG) {
err = this->read_register(QMC5883L_REGISTER_STATUS, &status, 1);
if (err != i2c::ERROR_OK) {
this->status_set_warning(str_sprintf("status read failed (%d)", err).c_str());
return;
}
}
this->read_byte(QMC5883L_REGISTER_STATUS, &status);
uint16_t raw[3] = {0};
// Z must always be requested, otherwise the data registers will remain locked against updates.
// Skipping the Y axis if X and Z are needed actually requires an additional byte of comms.
// Starting partway through the axes does save you traffic.
uint8_t start, dest;
if (this->heading_sensor_ != nullptr || this->x_sensor_ != nullptr) {
start = QMC5883L_REGISTER_DATA_X_LSB;
dest = 0;
} else if (this->y_sensor_ != nullptr) {
start = QMC5883L_REGISTER_DATA_Y_LSB;
dest = 1;
} else {
start = QMC5883L_REGISTER_DATA_Z_LSB;
dest = 2;
}
err = this->read_bytes_16_le_(start, &raw[dest], 3 - dest);
if (err != i2c::ERROR_OK) {
this->status_set_warning(str_sprintf("mag read failed (%d)", err).c_str());
// Always request X,Y,Z regardless if there are sensors for them
// to avoid https://github.com/esphome/issues/issues/5731
uint16_t raw_x, raw_y, raw_z;
if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_X_LSB, &raw_x) ||
!this->read_byte_16_(QMC5883L_REGISTER_DATA_Y_LSB, &raw_y) ||
!this->read_byte_16_(QMC5883L_REGISTER_DATA_Z_LSB, &raw_z)) {
this->status_set_warning();
return;
}
@@ -130,18 +107,17 @@ void QMC5883LComponent::update() {
}
// in µT
const float x = int16_t(raw[0]) * mg_per_bit * 0.1f;
const float y = int16_t(raw[1]) * mg_per_bit * 0.1f;
const float z = int16_t(raw[2]) * mg_per_bit * 0.1f;
const float x = int16_t(raw_x) * mg_per_bit * 0.1f;
const float y = int16_t(raw_y) * mg_per_bit * 0.1f;
const float z = int16_t(raw_z) * mg_per_bit * 0.1f;
float heading = atan2f(0.0f - x, y) * 180.0f / M_PI;
float temp = NAN;
if (this->temperature_sensor_ != nullptr) {
uint16_t raw_temp;
err = this->read_bytes_16_le_(QMC5883L_REGISTER_TEMPERATURE_LSB, &raw_temp);
if (err != i2c::ERROR_OK) {
this->status_set_warning(str_sprintf("temp read failed (%d)", err).c_str());
if (!this->read_byte_16_(QMC5883L_REGISTER_TEMPERATURE_LSB, &raw_temp)) {
this->status_set_warning();
return;
}
temp = int16_t(raw_temp) * 0.01f;
@@ -162,13 +138,11 @@ void QMC5883LComponent::update() {
this->temperature_sensor_->publish_state(temp);
}
i2c::ErrorCode QMC5883LComponent::read_bytes_16_le_(uint8_t a_register, uint16_t *data, uint8_t len) {
i2c::ErrorCode err = this->read_register(a_register, reinterpret_cast<uint8_t *>(data), len * 2);
if (err != i2c::ERROR_OK)
return err;
for (size_t i = 0; i < len; i++)
data[i] = convert_little_endian(data[i]);
return err;
bool QMC5883LComponent::read_byte_16_(uint8_t a_register, uint16_t *data) {
if (!this->read_byte_16(a_register, data))
return false;
*data = (*data & 0x00FF) << 8 | (*data & 0xFF00) >> 8; // Flip Byte order, LSB first;
return true;
}
} // namespace qmc5883l

View File

@@ -55,7 +55,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
NONE = 0,
COMMUNICATION_FAILED,
} error_code_;
i2c::ErrorCode read_bytes_16_le_(uint8_t a_register, uint16_t *data, uint8_t len = 1);
bool read_byte_16_(uint8_t a_register, uint16_t *data);
HighFrequencyLoopRequester high_freq_;
};

View File

@@ -1,23 +1,24 @@
from esphome import pins
import esphome.codegen as cg
from esphome.components import esp32_rmt, remote_base
import esphome.config_validation as cv
from esphome import pins
from esphome.components import remote_base, esp32_rmt
from esphome.const import (
CONF_BUFFER_SIZE,
CONF_CLOCK_DIVIDER,
CONF_DUMP,
CONF_FILTER,
CONF_ID,
CONF_IDLE,
CONF_MEMORY_BLOCKS,
CONF_PIN,
CONF_RMT_CHANNEL,
CONF_TOLERANCE,
CONF_TYPE,
CONF_MEMORY_BLOCKS,
CONF_RMT_CHANNEL,
CONF_VALUE,
)
from esphome.core import CORE, TimePeriod
CONF_CLOCK_DIVIDER = "clock_divider"
AUTO_LOAD = ["remote_base"]
remote_receiver_ns = cg.esphome_ns.namespace("remote_receiver")
remote_base_ns = cg.esphome_ns.namespace("remote_base")

View File

@@ -1,41 +0,0 @@
import esphome.codegen as cg
from esphome.components import uart
import esphome.config_validation as cv
from esphome.const import CONF_ID
CODEOWNERS = ["@limengdu"]
DEPENDENCIES = ["uart"]
MULTI_CONF = True
mr60bha2_ns = cg.esphome_ns.namespace("seeed_mr60bha2")
MR60BHA2Component = mr60bha2_ns.class_(
"MR60BHA2Component", cg.Component, uart.UARTDevice
)
CONF_MR60BHA2_ID = "mr60bha2_id"
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(MR60BHA2Component),
}
)
.extend(uart.UART_DEVICE_SCHEMA)
.extend(cv.COMPONENT_SCHEMA)
)
FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
"seeed_mr60bha2",
require_tx=True,
require_rx=True,
baud_rate=115200,
parity="NONE",
stop_bits=1,
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await uart.register_uart_device(var, config)

View File

@@ -1,173 +0,0 @@
#include "seeed_mr60bha2.h"
#include "esphome/core/log.h"
#include <utility>
namespace esphome {
namespace seeed_mr60bha2 {
static const char *const TAG = "seeed_mr60bha2";
// Prints the component's configuration data. dump_config() prints all of the component's configuration
// items in an easy-to-read format, including the configuration key-value pairs.
void MR60BHA2Component::dump_config() {
ESP_LOGCONFIG(TAG, "MR60BHA2:");
#ifdef USE_SENSOR
LOG_SENSOR(" ", "Breath Rate Sensor", this->breath_rate_sensor_);
LOG_SENSOR(" ", "Heart Rate Sensor", this->heart_rate_sensor_);
LOG_SENSOR(" ", "Distance Sensor", this->distance_sensor_);
#endif
}
// main loop
void MR60BHA2Component::loop() {
uint8_t byte;
// Is there data on the serial port
while (this->available()) {
this->read_byte(&byte);
this->rx_message_.push_back(byte);
if (!this->validate_message_()) {
this->rx_message_.clear();
}
}
}
/**
* @brief Calculate the checksum for a byte array.
*
* This function calculates the checksum for the provided byte array using an
* XOR-based checksum algorithm.
*
* @param data The byte array to calculate the checksum for.
* @param len The length of the byte array.
* @return The calculated checksum.
*/
static uint8_t calculate_checksum(const uint8_t *data, size_t len) {
uint8_t checksum = 0;
for (size_t i = 0; i < len; i++) {
checksum ^= data[i];
}
checksum = ~checksum;
return checksum;
}
/**
* @brief Validate the checksum of a byte array.
*
* This function validates the checksum of the provided byte array by comparing
* it to the expected checksum.
*
* @param data The byte array to validate.
* @param len The length of the byte array.
* @param expected_checksum The expected checksum.
* @return True if the checksum is valid, false otherwise.
*/
static bool validate_checksum(const uint8_t *data, size_t len, uint8_t expected_checksum) {
return calculate_checksum(data, len) == expected_checksum;
}
bool MR60BHA2Component::validate_message_() {
size_t at = this->rx_message_.size() - 1;
auto *data = &this->rx_message_[0];
uint8_t new_byte = data[at];
if (at == 0) {
return new_byte == FRAME_HEADER_BUFFER;
}
if (at <= 2) {
return true;
}
uint16_t frame_id = encode_uint16(data[1], data[2]);
if (at <= 4) {
return true;
}
uint16_t length = encode_uint16(data[3], data[4]);
if (at <= 6) {
return true;
}
uint16_t frame_type = encode_uint16(data[5], data[6]);
if (frame_type != BREATH_RATE_TYPE_BUFFER && frame_type != HEART_RATE_TYPE_BUFFER &&
frame_type != DISTANCE_TYPE_BUFFER) {
return false;
}
uint8_t header_checksum = new_byte;
if (at == 7) {
if (!validate_checksum(data, 7, header_checksum)) {
ESP_LOGE(TAG, "HEAD_CKSUM_FRAME ERROR: 0x%02x", header_checksum);
ESP_LOGV(TAG, "GET FRAME: %s", format_hex_pretty(data, 8).c_str());
return false;
}
return true;
}
// Wait until all data is read
if (at - 8 < length) {
return true;
}
uint8_t data_checksum = new_byte;
if (at == 8 + length) {
if (!validate_checksum(data + 8, length, data_checksum)) {
ESP_LOGE(TAG, "DATA_CKSUM_FRAME ERROR: 0x%02x", data_checksum);
ESP_LOGV(TAG, "GET FRAME: %s", format_hex_pretty(data, 8 + length).c_str());
return false;
}
}
const uint8_t *frame_data = data + 8;
ESP_LOGV(TAG, "Received Frame: ID: 0x%04x, Type: 0x%04x, Data: [%s] Raw Data: [%s]", frame_id, frame_type,
format_hex_pretty(frame_data, length).c_str(), format_hex_pretty(this->rx_message_).c_str());
this->process_frame_(frame_id, frame_type, data + 8, length);
// Return false to reset rx buffer
return false;
}
void MR60BHA2Component::process_frame_(uint16_t frame_id, uint16_t frame_type, const uint8_t *data, size_t length) {
switch (frame_type) {
case BREATH_RATE_TYPE_BUFFER:
if (this->breath_rate_sensor_ != nullptr && length >= 4) {
uint32_t current_breath_rate_int = encode_uint32(data[3], data[2], data[1], data[0]);
if (current_breath_rate_int != 0) {
float breath_rate_float;
memcpy(&breath_rate_float, &current_breath_rate_int, sizeof(float));
this->breath_rate_sensor_->publish_state(breath_rate_float);
}
}
break;
case HEART_RATE_TYPE_BUFFER:
if (this->heart_rate_sensor_ != nullptr && length >= 4) {
uint32_t current_heart_rate_int = encode_uint32(data[3], data[2], data[1], data[0]);
if (current_heart_rate_int != 0) {
float heart_rate_float;
memcpy(&heart_rate_float, &current_heart_rate_int, sizeof(float));
this->heart_rate_sensor_->publish_state(heart_rate_float);
}
}
break;
case DISTANCE_TYPE_BUFFER:
if (!data[0]) {
if (this->distance_sensor_ != nullptr && length >= 8) {
uint32_t current_distance_int = encode_uint32(data[7], data[6], data[5], data[4]);
float distance_float;
memcpy(&distance_float, &current_distance_int, sizeof(float));
this->distance_sensor_->publish_state(distance_float);
}
}
break;
default:
break;
}
}
} // namespace seeed_mr60bha2
} // namespace esphome

View File

@@ -1,61 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
#include "esphome/components/uart/uart.h"
#include "esphome/core/automation.h"
#include "esphome/core/helpers.h"
#include <map>
namespace esphome {
namespace seeed_mr60bha2 {
static const uint8_t DATA_BUF_MAX_SIZE = 12;
static const uint8_t FRAME_BUF_MAX_SIZE = 21;
static const uint8_t LEN_TO_HEAD_CKSUM = 8;
static const uint8_t LEN_TO_DATA_FRAME = 9;
static const uint8_t FRAME_HEADER_BUFFER = 0x01;
static const uint16_t BREATH_RATE_TYPE_BUFFER = 0x0A14;
static const uint16_t HEART_RATE_TYPE_BUFFER = 0x0A15;
static const uint16_t DISTANCE_TYPE_BUFFER = 0x0A16;
enum FrameLocation {
LOCATE_FRAME_HEADER,
LOCATE_ID_FRAME1,
LOCATE_ID_FRAME2,
LOCATE_LENGTH_FRAME_H,
LOCATE_LENGTH_FRAME_L,
LOCATE_TYPE_FRAME1,
LOCATE_TYPE_FRAME2,
LOCATE_HEAD_CKSUM_FRAME, // Header checksum: [from the first byte to the previous byte of the HEAD_CKSUM bit]
LOCATE_DATA_FRAME,
LOCATE_DATA_CKSUM_FRAME, // Data checksum: [from the first to the previous byte of the DATA_CKSUM bit]
LOCATE_PROCESS_FRAME,
};
class MR60BHA2Component : public Component,
public uart::UARTDevice { // The class name must be the name defined by text_sensor.py
#ifdef USE_SENSOR
SUB_SENSOR(breath_rate);
SUB_SENSOR(heart_rate);
SUB_SENSOR(distance);
#endif
public:
float get_setup_priority() const override { return esphome::setup_priority::LATE; }
void dump_config() override;
void loop() override;
protected:
bool validate_message_();
void process_frame_(uint16_t frame_id, uint16_t frame_type, const uint8_t *data, size_t length);
std::vector<uint8_t> rx_message_;
};
} // namespace seeed_mr60bha2
} // namespace esphome

View File

@@ -1,57 +0,0 @@
import esphome.codegen as cg
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_DISTANCE,
DEVICE_CLASS_DISTANCE,
ICON_HEART_PULSE,
ICON_PULSE,
ICON_SIGNAL,
STATE_CLASS_MEASUREMENT,
UNIT_BEATS_PER_MINUTE,
UNIT_CENTIMETER,
)
from . import CONF_MR60BHA2_ID, MR60BHA2Component
DEPENDENCIES = ["seeed_mr60bha2"]
CONF_BREATH_RATE = "breath_rate"
CONF_HEART_RATE = "heart_rate"
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_MR60BHA2_ID): cv.use_id(MR60BHA2Component),
cv.Optional(CONF_BREATH_RATE): sensor.sensor_schema(
accuracy_decimals=2,
state_class=STATE_CLASS_MEASUREMENT,
icon=ICON_PULSE,
),
cv.Optional(CONF_HEART_RATE): sensor.sensor_schema(
accuracy_decimals=0,
icon=ICON_HEART_PULSE,
state_class=STATE_CLASS_MEASUREMENT,
unit_of_measurement=UNIT_BEATS_PER_MINUTE,
),
cv.Optional(CONF_DISTANCE): sensor.sensor_schema(
device_class=DEVICE_CLASS_DISTANCE,
state_class=STATE_CLASS_MEASUREMENT,
unit_of_measurement=UNIT_CENTIMETER,
accuracy_decimals=2,
icon=ICON_SIGNAL,
),
}
)
async def to_code(config):
mr60bha2_component = await cg.get_variable(config[CONF_MR60BHA2_ID])
if breath_rate_config := config.get(CONF_BREATH_RATE):
sens = await sensor.new_sensor(breath_rate_config)
cg.add(mr60bha2_component.set_breath_rate_sensor(sens))
if heart_rate_config := config.get(CONF_HEART_RATE):
sens = await sensor.new_sensor(heart_rate_config)
cg.add(mr60bha2_component.set_heart_rate_sensor(sens))
if distance_config := config.get(CONF_DISTANCE):
sens = await sensor.new_sensor(distance_config)
cg.add(mr60bha2_component.set_distance_sensor(sens))

View File

@@ -1,19 +1,19 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor, sensirion_common
from esphome import automation
from esphome.automation import maybe_simple_id
import esphome.codegen as cg
from esphome.components import i2c, sensirion_common, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,
CONF_OFFSET,
CONF_PM_1_0,
CONF_PM_10_0,
CONF_PM_2_5,
CONF_PM_4_0,
CONF_PM_10_0,
CONF_STORE_BASELINE,
CONF_TEMPERATURE,
CONF_TEMPERATURE_COMPENSATION,
DEVICE_CLASS_AQI,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_PM1,
@@ -51,6 +51,7 @@ CONF_LEARNING_TIME_OFFSET_HOURS = "learning_time_offset_hours"
CONF_NORMALIZED_OFFSET_SLOPE = "normalized_offset_slope"
CONF_NOX = "nox"
CONF_STD_INITIAL = "std_initial"
CONF_TEMPERATURE_COMPENSATION = "temperature_compensation"
CONF_TIME_CONSTANT = "time_constant"
CONF_VOC = "voc"
CONF_VOC_BASELINE = "voc_baseline"

View File

@@ -1,22 +1,23 @@
import esphome.codegen as cg
from esphome.components import i2c, sensirion_common, sensor
import esphome.config_validation as cv
from esphome.components import i2c, sensor, sensirion_common
from esphome.const import (
CONF_BASELINE,
CONF_COMPENSATION,
CONF_ECO2,
CONF_ID,
CONF_BASELINE,
CONF_ECO2,
CONF_STORE_BASELINE,
CONF_TEMPERATURE_SOURCE,
CONF_TVOC,
ICON_RADIATOR,
DEVICE_CLASS_CARBON_DIOXIDE,
DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
ENTITY_CATEGORY_DIAGNOSTIC,
ICON_MOLECULE_CO2,
ICON_RADIATOR,
STATE_CLASS_MEASUREMENT,
UNIT_PARTS_PER_BILLION,
UNIT_PARTS_PER_MILLION,
UNIT_PARTS_PER_BILLION,
ICON_MOLECULE_CO2,
ENTITY_CATEGORY_DIAGNOSTIC,
)
DEPENDENCIES = ["i2c"]
@@ -76,7 +77,7 @@ CONFIG_SCHEMA = (
),
}
)
.extend(cv.polling_component_schema("60s"))
.extend(cv.polling_component_schema("1s"))
.extend(i2c.i2c_device_schema(0x58))
)

View File

@@ -1,8 +1,8 @@
#include "sgp30.h"
#include <cinttypes>
#include "esphome/core/application.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
#include "esphome/core/application.h"
#include <cinttypes>
namespace esphome {
namespace sgp30 {
@@ -295,6 +295,10 @@ void SGP30Component::update() {
if (this->tvoc_sensor_ != nullptr)
this->tvoc_sensor_->publish_state(tvoc);
if (this->get_update_interval() != 1000) {
ESP_LOGW(TAG, "Update interval for SGP30 sensor must be set to 1s for optimized readout");
}
this->status_clear_warning();
this->send_env_data_();
this->read_iaq_baseline_();

View File

@@ -1,12 +1,11 @@
from esphome import automation
import esphome.codegen as cg
from esphome.components import i2c, sensor
from esphome import automation
import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import (
CONF_EC,
CONF_ID,
CONF_EC,
CONF_TEMPERATURE,
CONF_TEMPERATURE_COMPENSATION,
DEVICE_CLASS_EMPTY,
DEVICE_CLASS_TEMPERATURE,
ICON_EMPTY,
@@ -19,6 +18,7 @@ DEPENDENCIES = ["i2c"]
CONF_SOLUTION = "solution"
CONF_TEMPERATURE_SENSOR = "temperature_sensor"
CONF_TEMPERATURE_COMPENSATION = "temperature_compensation"
CONF_TEMPERATURE_COEFFICIENT = "temperature_coefficient"
ufire_ec_ns = cg.esphome_ns.namespace("ufire_ec")

View File

@@ -1,6 +1,6 @@
"""Constants used by esphome."""
__version__ = "2024.12.0b3"
__version__ = "2024.12.0-dev"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
VALID_SUBSTITUTIONS_CHARACTERS = (
@@ -131,9 +131,7 @@ CONF_CLIENT_CERTIFICATE = "client_certificate"
CONF_CLIENT_CERTIFICATE_KEY = "client_certificate_key"
CONF_CLIENT_ID = "client_id"
CONF_CLK_PIN = "clk_pin"
CONF_CLOCK_DIVIDER = "clock_divider"
CONF_CLOCK_PIN = "clock_pin"
CONF_CLOCK_RESOLUTION = "clock_resolution"
CONF_CLOSE_ACTION = "close_action"
CONF_CLOSE_DURATION = "close_duration"
CONF_CLOSE_ENDSTOP = "close_endstop"
@@ -465,6 +463,7 @@ CONF_MAGNITUDE = "magnitude"
CONF_MAINS_FILTER = "mains_filter"
CONF_MAKE_ID = "make_id"
CONF_MANUAL_IP = "manual_ip"
CONF_MANUFACTURER = "manufacturer"
CONF_MANUFACTURER_ID = "manufacturer_id"
CONF_MASK_DISTURBER = "mask_disturber"
CONF_MAX_BRIGHTNESS = "max_brightness"
@@ -741,7 +740,6 @@ CONF_RGB_ORDER = "rgb_order"
CONF_RGBW = "rgbw"
CONF_RISING_EDGE = "rising_edge"
CONF_RMT_CHANNEL = "rmt_channel"
CONF_RMT_SYMBOLS = "rmt_symbols"
CONF_ROTATION = "rotation"
CONF_ROW = "row"
CONF_RS_PIN = "rs_pin"
@@ -867,7 +865,6 @@ CONF_TARGET_TEMPERATURE_LOW_COMMAND_TOPIC = "target_temperature_low_command_topi
CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC = "target_temperature_low_state_topic"
CONF_TARGET_TEMPERATURE_STATE_TOPIC = "target_temperature_state_topic"
CONF_TEMPERATURE = "temperature"
CONF_TEMPERATURE_COMPENSATION = "temperature_compensation"
CONF_TEMPERATURE_OFFSET = "temperature_offset"
CONF_TEMPERATURE_SOURCE = "temperature_source"
CONF_TEMPERATURE_STEP = "temperature_step"
@@ -921,7 +918,6 @@ CONF_UPDATE_ON_BOOT = "update_on_boot"
CONF_URL = "url"
CONF_USE_ABBREVIATIONS = "use_abbreviations"
CONF_USE_ADDRESS = "use_address"
CONF_USE_DMA = "use_dma"
CONF_USE_FAHRENHEIT = "use_fahrenheit"
CONF_USERNAME = "username"
CONF_UUID = "uuid"
@@ -1006,7 +1002,6 @@ ICON_GRAIN = "mdi:grain"
ICON_GYROSCOPE_X = "mdi:axis-x-rotate-clockwise"
ICON_GYROSCOPE_Y = "mdi:axis-y-rotate-clockwise"
ICON_GYROSCOPE_Z = "mdi:axis-z-rotate-clockwise"
ICON_HEART_PULSE = "mdi:heart-pulse"
ICON_HEATING_COIL = "mdi:heating-coil"
ICON_KEY_PLUS = "mdi:key-plus"
ICON_LIGHTBULB = "mdi:lightbulb"
@@ -1046,7 +1041,6 @@ ICON_WEATHER_WINDY = "mdi:weather-windy"
ICON_WIFI = "mdi:wifi"
UNIT_AMPERE = "A"
UNIT_BEATS_PER_MINUTE = "bpm"
UNIT_BECQUEREL_PER_CUBIC_METER = "Bq/m³"
UNIT_BYTES = "B"
UNIT_CELSIUS = "°C"

View File

@@ -19,6 +19,7 @@ from esphome.const import (
CONF_FRIENDLY_NAME,
CONF_INCLUDES,
CONF_LIBRARIES,
CONF_MANUFACTURER,
CONF_MIN_VERSION,
CONF_NAME,
CONF_NAME_ADD_MAC_SUFFIX,
@@ -96,10 +97,33 @@ def valid_include(value):
return value
def valid_project_name(value: str):
if value.count(".") != 1:
raise cv.Invalid("project name needs to have a namespace")
return value
def _validate_project_info(config):
name = config[CONF_NAME]
dot_count = name.count(".")
if CONF_MANUFACTURER not in config:
if dot_count != 1:
raise cv.Invalid(
f"'{CONF_MANUFACTURER}' is a required option for [{CONF_PROJECT}]"
)
author, name = name.split(".", 1)
config[CONF_MANUFACTURER] = author
config[CONF_NAME] = name
_LOGGER.warning(
"Prefixing %s %s with %s namespace is deprecated and will be disallowed in a future release. "
"Please see current documentation for the correct way to define the %s information.",
CONF_PROJECT,
CONF_NAME,
CONF_MANUFACTURER,
CONF_PROJECT,
)
elif dot_count != 0:
author, name = name.split(".", 1)
raise cv.Invalid(
f"Remove {CONF_MANUFACTURER} namespace '{author}.' from the {CONF_PROJECT} {CONF_NAME}",
path=[CONF_NAME],
)
return config
if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
@@ -110,7 +134,6 @@ if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
else:
_compile_process_limit_default = cv.UNDEFINED
CONF_ESP8266_RESTORE_FROM_FLASH = "esp8266_restore_from_flash"
CONFIG_SCHEMA = cv.All(
cv.Schema(
@@ -145,20 +168,22 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_INCLUDES, default=[]): cv.ensure_list(valid_include),
cv.Optional(CONF_LIBRARIES, default=[]): cv.ensure_list(cv.string_strict),
cv.Optional(CONF_NAME_ADD_MAC_SUFFIX, default=False): cv.boolean,
cv.Optional(CONF_PROJECT): cv.Schema(
{
cv.Required(CONF_NAME): cv.All(
cv.string_strict, valid_project_name
),
cv.Required(CONF_VERSION): cv.string_strict,
cv.Optional(CONF_ON_UPDATE): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
ProjectUpdateTrigger
),
}
),
}
cv.Optional(CONF_PROJECT): cv.All(
cv.Schema(
{
cv.Optional(CONF_MANUFACTURER): cv.string_strict,
cv.Required(CONF_NAME): cv.string_strict,
cv.Required(CONF_VERSION): cv.string_strict,
cv.Optional(CONF_ON_UPDATE): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
ProjectUpdateTrigger
),
}
),
}
),
_validate_project_info,
),
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
cv.version_number, cv.validate_esphome_version
@@ -394,6 +419,7 @@ async def to_code(config):
if project_conf := config.get(CONF_PROJECT):
cg.add_define("ESPHOME_PROJECT_NAME", project_conf[CONF_NAME])
cg.add_define("ESPHOME_PROJECT_AUTHOR", project_conf[CONF_MANUFACTURER])
cg.add_define("ESPHOME_PROJECT_VERSION", project_conf[CONF_VERSION])
cg.add_define("ESPHOME_PROJECT_VERSION_30", project_conf[CONF_VERSION][:29])
for conf in project_conf.get(CONF_ON_UPDATE, []):

View File

@@ -10,6 +10,7 @@
// Informative flags
#define ESPHOME_BOARD "dummy_board"
#define ESPHOME_PROJECT_NAME "dummy project"
#define ESPHOME_PROJECT_MANUFACTURER "ESPHome"
#define ESPHOME_PROJECT_VERSION "v2"
#define ESPHOME_PROJECT_VERSION_30 "v2"
#define ESPHOME_VARIANT "ESP32"

View File

@@ -767,8 +767,7 @@ bool mac_address_is_valid(const uint8_t *mac) {
return !(is_all_zeros || is_all_ones);
}
void IRAM_ATTR HOT delay_microseconds_safe(uint32_t us) {
// avoids CPU locks that could trigger WDT or affect WiFi/BT stability
void delay_microseconds_safe(uint32_t us) { // avoids CPU locks that could trigger WDT or affect WiFi/BT stability
uint32_t start = micros();
const uint32_t lag = 5000; // microseconds, specifies the maximum time for a CPU busy-loop.

View File

@@ -108,12 +108,6 @@ def is_authenticated(handler: BaseHandler) -> bool:
return True
if settings.using_auth:
if auth_header := handler.request.headers.get("Authorization"):
assert isinstance(auth_header, str)
if auth_header.startswith("Basic "):
auth_decoded = base64.b64decode(auth_header[6:]).decode()
username, password = auth_decoded.split(":", 1)
return settings.check_password(username, password)
return handler.get_secure_cookie(AUTH_COOKIE_NAME) == COOKIE_AUTHENTICATED_YES
return True

View File

@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "esphome"
license = {text = "MIT"}
description = "ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems."
description = "Make creating custom firmwares for ESP32/ESP8266 super easy."
readme = "README.md"
authors = [
{name = "The ESPHome Authors", email = "esphome@nabucasa.com"}

View File

@@ -12,7 +12,7 @@ pyserial==3.5
platformio==6.1.16 # When updating platformio, also update Dockerfile
esptool==4.7.0
click==8.1.7
esphome-dashboard==20241217.1
esphome-dashboard==20241120.0
aioesphomeapi==24.6.2
zeroconf==0.132.2
puremagic==1.27

View File

@@ -1,4 +0,0 @@
sensor:
- platform: adc
pin: P23
name: Basic ADC Test

View File

@@ -165,11 +165,6 @@ lvgl:
- Nov
- Dec
selected_index: 1
on_change:
then:
- logger.log:
format: "Roller changed = %d: %s"
args: [x, text.c_str()]
on_value:
then:
- logger.log:
@@ -456,7 +451,6 @@ lvgl:
src: cat_image
align: top_left
y: "50"
mode: real
- tileview:
id: tileview_id
scrollbar_mode: active
@@ -653,7 +647,6 @@ lvgl:
grid_cell_row_pos: 0
grid_cell_column_pos: 0
src: !lambda return dog_image;
mode: virtual
on_click:
then:
- lvgl.tabview.select:

View File

@@ -1,19 +0,0 @@
uart:
- id: seeed_mr60fda2_uart
tx_pin: ${uart_tx_pin}
rx_pin: ${uart_rx_pin}
baud_rate: 115200
parity: NONE
stop_bits: 1
seeed_mr60bha2:
id: my_seeed_mr60bha2
sensor:
- platform: seeed_mr60bha2
breath_rate:
name: "Real-time respiratory rate"
heart_rate:
name: "Real-time heart rate"
distance:
name: "Distance to detection object"

View File

@@ -1,5 +0,0 @@
substitutions:
uart_tx_pin: GPIO5
uart_rx_pin: GPIO4
<<: !include common.yaml

View File

@@ -1,5 +0,0 @@
substitutions:
uart_tx_pin: GPIO5
uart_rx_pin: GPIO4
<<: !include common.yaml