mirror of
https://github.com/esphome/esphome.git
synced 2025-02-07 00:11:59 +01:00
Merge branch 'dev' into spdif_speaker
This commit is contained in:
commit
6bfcb3c1b2
@ -49,6 +49,7 @@ esphome/components/atc_mithermometer/* @ahpohl
|
||||
esphome/components/atm90e26/* @danieltwagner
|
||||
esphome/components/atm90e32/* @circuitsetup @descipher
|
||||
esphome/components/audio/* @kahrendt
|
||||
esphome/components/audio_adc/* @kbx81
|
||||
esphome/components/audio_dac/* @kbx81
|
||||
esphome/components/axs15231/* @clydebarrow
|
||||
esphome/components/b_parasite/* @rbaron
|
||||
@ -132,6 +133,7 @@ esphome/components/ens160_i2c/* @latonita
|
||||
esphome/components/ens160_spi/* @latonita
|
||||
esphome/components/ens210/* @itn3rd77
|
||||
esphome/components/es7210/* @kahrendt
|
||||
esphome/components/es8156/* @kbx81
|
||||
esphome/components/es8311/* @kahrendt @kroimon
|
||||
esphome/components/esp32/* @esphome/core
|
||||
esphome/components/esp32_ble/* @Rapsssito @jesserockz
|
||||
|
41
esphome/components/audio_adc/__init__.py
Normal file
41
esphome/components/audio_adc/__init__.py
Normal file
@ -0,0 +1,41 @@
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_MIC_GAIN
|
||||
from esphome.core import coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ["@kbx81"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
audio_adc_ns = cg.esphome_ns.namespace("audio_adc")
|
||||
AudioAdc = audio_adc_ns.class_("AudioAdc")
|
||||
|
||||
SetMicGainAction = audio_adc_ns.class_("SetMicGainAction", automation.Action)
|
||||
|
||||
|
||||
SET_MIC_GAIN_ACTION_SCHEMA = cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(AudioAdc),
|
||||
cv.Required(CONF_MIC_GAIN): cv.templatable(cv.decibel),
|
||||
},
|
||||
key=CONF_MIC_GAIN,
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"audio_adc.set_mic_gain", SetMicGainAction, SET_MIC_GAIN_ACTION_SCHEMA
|
||||
)
|
||||
async def audio_adc_set_mic_gain_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
template_ = await cg.templatable(config.get(CONF_MIC_GAIN), args, float)
|
||||
cg.add(var.set_mic_gain(template_))
|
||||
|
||||
return var
|
||||
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
cg.add_define("USE_AUDIO_ADC")
|
||||
cg.add_global(audio_adc_ns.using)
|
17
esphome/components/audio_adc/audio_adc.h
Normal file
17
esphome/components/audio_adc/audio_adc.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace audio_adc {
|
||||
|
||||
class AudioAdc {
|
||||
public:
|
||||
virtual bool set_mic_gain(float mic_gain) = 0;
|
||||
|
||||
virtual float mic_gain() = 0;
|
||||
};
|
||||
|
||||
} // namespace audio_adc
|
||||
} // namespace esphome
|
23
esphome/components/audio_adc/automation.h
Normal file
23
esphome/components/audio_adc/automation.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "audio_adc.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace audio_adc {
|
||||
|
||||
template<typename... Ts> class SetMicGainAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit SetMicGainAction(AudioAdc *audio_adc) : audio_adc_(audio_adc) {}
|
||||
|
||||
TEMPLATABLE_VALUE(float, mic_gain)
|
||||
|
||||
void play(Ts... x) override { this->audio_adc_->set_mic_gain(this->mic_gain_.value(x...)); }
|
||||
|
||||
protected:
|
||||
AudioAdc *audio_adc_;
|
||||
};
|
||||
|
||||
} // namespace audio_adc
|
||||
} // namespace esphome
|
@ -1,67 +0,0 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_BITS_PER_SAMPLE, CONF_ID, CONF_MIC_GAIN, CONF_SAMPLE_RATE
|
||||
|
||||
CODEOWNERS = ["@kahrendt"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
es7210_ns = cg.esphome_ns.namespace("es7210")
|
||||
ES7210 = es7210_ns.class_("ES7210", cg.Component, i2c.I2CDevice)
|
||||
|
||||
|
||||
es7210_bits_per_sample = es7210_ns.enum("ES7210BitsPerSample")
|
||||
ES7210_BITS_PER_SAMPLE_ENUM = {
|
||||
16: es7210_bits_per_sample.ES7210_BITS_PER_SAMPLE_16,
|
||||
24: es7210_bits_per_sample.ES7210_BITS_PER_SAMPLE_24,
|
||||
32: es7210_bits_per_sample.ES7210_BITS_PER_SAMPLE_32,
|
||||
}
|
||||
|
||||
|
||||
es7210_mic_gain = es7210_ns.enum("ES7210MicGain")
|
||||
ES7210_MIC_GAIN_ENUM = {
|
||||
"0DB": es7210_mic_gain.ES7210_MIC_GAIN_0DB,
|
||||
"3DB": es7210_mic_gain.ES7210_MIC_GAIN_3DB,
|
||||
"6DB": es7210_mic_gain.ES7210_MIC_GAIN_6DB,
|
||||
"9DB": es7210_mic_gain.ES7210_MIC_GAIN_9DB,
|
||||
"12DB": es7210_mic_gain.ES7210_MIC_GAIN_12DB,
|
||||
"15DB": es7210_mic_gain.ES7210_MIC_GAIN_15DB,
|
||||
"18DB": es7210_mic_gain.ES7210_MIC_GAIN_18DB,
|
||||
"21DB": es7210_mic_gain.ES7210_MIC_GAIN_21DB,
|
||||
"24DB": es7210_mic_gain.ES7210_MIC_GAIN_24DB,
|
||||
"27DB": es7210_mic_gain.ES7210_MIC_GAIN_27DB,
|
||||
"30DB": es7210_mic_gain.ES7210_MIC_GAIN_30DB,
|
||||
"33DB": es7210_mic_gain.ES7210_MIC_GAIN_33DB,
|
||||
"34.5DB": es7210_mic_gain.ES7210_MIC_GAIN_34_5DB,
|
||||
"36DB": es7210_mic_gain.ES7210_MIC_GAIN_36DB,
|
||||
"37.5DB": es7210_mic_gain.ES7210_MIC_GAIN_37_5DB,
|
||||
}
|
||||
|
||||
_validate_bits = cv.float_with_unit("bits", "bit")
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ES7210),
|
||||
cv.Optional(CONF_BITS_PER_SAMPLE, default="16bit"): cv.All(
|
||||
_validate_bits, cv.enum(ES7210_BITS_PER_SAMPLE_ENUM)
|
||||
),
|
||||
cv.Optional(CONF_MIC_GAIN, default="24DB"): cv.enum(
|
||||
ES7210_MIC_GAIN_ENUM, upper=True
|
||||
),
|
||||
cv.Optional(CONF_SAMPLE_RATE, default=16000): cv.int_range(min=1),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
|
||||
cg.add(var.set_mic_gain(config[CONF_MIC_GAIN]))
|
||||
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
51
esphome/components/es7210/audio_adc.py
Normal file
51
esphome/components/es7210/audio_adc.py
Normal file
@ -0,0 +1,51 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
from esphome.components.audio_adc import AudioAdc
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_BITS_PER_SAMPLE, CONF_ID, CONF_MIC_GAIN, CONF_SAMPLE_RATE
|
||||
|
||||
CODEOWNERS = ["@kahrendt"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
es7210_ns = cg.esphome_ns.namespace("es7210")
|
||||
ES7210 = es7210_ns.class_("ES7210", AudioAdc, cg.Component, i2c.I2CDevice)
|
||||
|
||||
|
||||
es7210_bits_per_sample = es7210_ns.enum("ES7210BitsPerSample")
|
||||
ES7210_BITS_PER_SAMPLE_ENUM = {
|
||||
16: es7210_bits_per_sample.ES7210_BITS_PER_SAMPLE_16,
|
||||
24: es7210_bits_per_sample.ES7210_BITS_PER_SAMPLE_24,
|
||||
32: es7210_bits_per_sample.ES7210_BITS_PER_SAMPLE_32,
|
||||
}
|
||||
|
||||
|
||||
ES7210_MIC_GAINS = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 34.5, 36, 37.5]
|
||||
|
||||
_validate_bits = cv.float_with_unit("bits", "bit")
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ES7210),
|
||||
cv.Optional(CONF_BITS_PER_SAMPLE, default="16bit"): cv.All(
|
||||
_validate_bits, cv.enum(ES7210_BITS_PER_SAMPLE_ENUM)
|
||||
),
|
||||
cv.Optional(CONF_MIC_GAIN, default="24db"): cv.All(
|
||||
cv.decibel, cv.one_of(*ES7210_MIC_GAINS)
|
||||
),
|
||||
cv.Optional(CONF_SAMPLE_RATE, default=16000): cv.int_range(min=1),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
|
||||
cg.add(var.set_mic_gain(config[CONF_MIC_GAIN]))
|
||||
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
@ -25,12 +25,12 @@ static const size_t MCLK_DIV_FRE = 256;
|
||||
}
|
||||
|
||||
void ES7210::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ES7210 ADC:");
|
||||
ESP_LOGCONFIG(TAG, "ES7210 audio ADC:");
|
||||
ESP_LOGCONFIG(TAG, " Bits Per Sample: %" PRIu8, this->bits_per_sample_);
|
||||
ESP_LOGCONFIG(TAG, " Sample Rate: %" PRIu32, this->sample_rate_);
|
||||
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGCONFIG(TAG, " Failed to initialize!");
|
||||
ESP_LOGE(TAG, " Failed to initialize");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -84,6 +84,16 @@ void ES7210::setup() {
|
||||
// Enable device
|
||||
ES7210_ERROR_FAILED(this->write_byte(ES7210_RESET_REG00, 0x71));
|
||||
ES7210_ERROR_FAILED(this->write_byte(ES7210_RESET_REG00, 0x41));
|
||||
|
||||
this->setup_complete_ = true;
|
||||
}
|
||||
|
||||
bool ES7210::set_mic_gain(float mic_gain) {
|
||||
this->mic_gain_ = clamp<float>(mic_gain, ES7210_MIC_GAIN_MIN, ES7210_MIC_GAIN_MAX);
|
||||
if (this->setup_complete_) {
|
||||
return this->configure_mic_gain_();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES7210::configure_sample_rate_() {
|
||||
@ -122,9 +132,11 @@ bool ES7210::configure_sample_rate_() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES7210::configure_mic_gain_() {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43 + i, 0x10, 0x00);
|
||||
auto regv = this->es7210_gain_reg_value_(this->mic_gain_);
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43 + i, 0x10, 0x00));
|
||||
}
|
||||
ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC12_POWER_REG4B, 0xff));
|
||||
ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC34_POWER_REG4C, 0xff));
|
||||
@ -133,29 +145,44 @@ bool ES7210::configure_mic_gain_() {
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
|
||||
ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC12_POWER_REG4B, 0x00));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43, 0x10, 0x10));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43, 0x0f, this->mic_gain_));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC1_GAIN_REG43, 0x0f, regv));
|
||||
|
||||
// Configure mic 2
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
|
||||
ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC12_POWER_REG4B, 0x00));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC2_GAIN_REG44, 0x10, 0x10));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC2_GAIN_REG44, 0x0f, this->mic_gain_));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC2_GAIN_REG44, 0x0f, regv));
|
||||
|
||||
// Configure mic 3
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
|
||||
ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC34_POWER_REG4C, 0x00));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC3_GAIN_REG45, 0x10, 0x10));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC3_GAIN_REG45, 0x0f, this->mic_gain_));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC3_GAIN_REG45, 0x0f, regv));
|
||||
|
||||
// Configure mic 4
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00));
|
||||
ES7210_ERROR_CHECK(this->write_byte(ES7210_MIC34_POWER_REG4C, 0x00));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC4_GAIN_REG46, 0x10, 0x10));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC4_GAIN_REG46, 0x0f, this->mic_gain_));
|
||||
ES7210_ERROR_CHECK(this->es7210_update_reg_bit_(ES7210_MIC4_GAIN_REG46, 0x0f, regv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t ES7210::es7210_gain_reg_value_(float mic_gain) {
|
||||
// reg: 12 - 34.5dB, 13 - 36dB, 14 - 37.5dB
|
||||
mic_gain += 0.5;
|
||||
if (mic_gain <= 33.0) {
|
||||
return (uint8_t) mic_gain / 3;
|
||||
}
|
||||
if (mic_gain < 36.0) {
|
||||
return 12;
|
||||
}
|
||||
if (mic_gain < 37.0) {
|
||||
return 13;
|
||||
}
|
||||
return 14;
|
||||
}
|
||||
|
||||
bool ES7210::configure_i2s_format_() {
|
||||
// Configure bits per sample
|
||||
uint8_t reg_val = 0;
|
||||
|
@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/audio_adc/audio_adc.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
#include "es7210_const.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es7210 {
|
||||
|
||||
@ -14,25 +17,7 @@ enum ES7210BitsPerSample : uint8_t {
|
||||
ES7210_BITS_PER_SAMPLE_32 = 32,
|
||||
};
|
||||
|
||||
enum ES7210MicGain : uint8_t {
|
||||
ES7210_MIC_GAIN_0DB = 0,
|
||||
ES7210_MIC_GAIN_3DB,
|
||||
ES7210_MIC_GAIN_6DB,
|
||||
ES7210_MIC_GAIN_9DB,
|
||||
ES7210_MIC_GAIN_12DB,
|
||||
ES7210_MIC_GAIN_15DB,
|
||||
ES7210_MIC_GAIN_18DB,
|
||||
ES7210_MIC_GAIN_21DB,
|
||||
ES7210_MIC_GAIN_24DB,
|
||||
ES7210_MIC_GAIN_27DB,
|
||||
ES7210_MIC_GAIN_30DB,
|
||||
ES7210_MIC_GAIN_33DB,
|
||||
ES7210_MIC_GAIN_34_5DB,
|
||||
ES7210_MIC_GAIN_36DB,
|
||||
ES7210_MIC_GAIN_37_5DB,
|
||||
};
|
||||
|
||||
class ES7210 : public Component, public i2c::I2CDevice {
|
||||
class ES7210 : public audio_adc::AudioAdc, public Component, public i2c::I2CDevice {
|
||||
/* Class for configuring an ES7210 ADC for microphone input.
|
||||
* Based on code from:
|
||||
* - https://github.com/espressif/esp-bsp/ (accessed 20241219)
|
||||
@ -44,9 +29,11 @@ class ES7210 : public Component, public i2c::I2CDevice {
|
||||
void dump_config() override;
|
||||
|
||||
void set_bits_per_sample(ES7210BitsPerSample bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
|
||||
void set_mic_gain(ES7210MicGain mic_gain) { this->mic_gain_ = mic_gain; }
|
||||
bool set_mic_gain(float mic_gain) override;
|
||||
void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
|
||||
|
||||
float mic_gain() override { return this->mic_gain_; };
|
||||
|
||||
protected:
|
||||
/// @brief Updates an I2C registry address by modifying the current state
|
||||
/// @param reg_addr I2C register address
|
||||
@ -55,14 +42,20 @@ class ES7210 : public Component, public i2c::I2CDevice {
|
||||
/// @return True if successful, false otherwise
|
||||
bool es7210_update_reg_bit_(uint8_t reg_addr, uint8_t update_bits, uint8_t data);
|
||||
|
||||
/// @brief Convert floating point mic gain value to register value
|
||||
/// @param mic_gain Gain value to convert
|
||||
/// @return Corresponding register value for specified gain
|
||||
uint8_t es7210_gain_reg_value_(float mic_gain);
|
||||
|
||||
bool configure_i2s_format_();
|
||||
bool configure_mic_gain_();
|
||||
bool configure_sample_rate_();
|
||||
|
||||
bool setup_complete_{false};
|
||||
bool enable_tdm_{false}; // TDM is unsupported in ESPHome as of version 2024.12
|
||||
ES7210MicGain mic_gain_;
|
||||
ES7210BitsPerSample bits_per_sample_;
|
||||
uint32_t sample_rate_;
|
||||
float mic_gain_{0};
|
||||
ES7210BitsPerSample bits_per_sample_{ES7210_BITS_PER_SAMPLE_16};
|
||||
uint32_t sample_rate_{0};
|
||||
};
|
||||
|
||||
} // namespace es7210
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "es7210.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace es7210 {
|
||||
@ -42,7 +42,7 @@ static const uint8_t ES7210_MIC12_POWER_REG4B = 0x4B; /* MICBias & ADC & PGA Pow
|
||||
static const uint8_t ES7210_MIC34_POWER_REG4C = 0x4C;
|
||||
|
||||
/*
|
||||
* Clock coefficient structer
|
||||
* Clock coefficient structure
|
||||
*/
|
||||
struct ES7210Coefficient {
|
||||
uint32_t mclk; // mclk frequency
|
||||
@ -122,5 +122,8 @@ static const ES7210Coefficient ES7210_COEFFICIENTS[] = {
|
||||
{19200000, 96000, 0x01, 0x05, 0x00, 0x01, 0x28, 0x00, 0x00, 0xc8},
|
||||
};
|
||||
|
||||
static const float ES7210_MIC_GAIN_MIN = 0.0;
|
||||
static const float ES7210_MIC_GAIN_MAX = 37.5;
|
||||
|
||||
} // namespace es7210
|
||||
} // namespace esphome
|
||||
|
0
esphome/components/es8156/__init__.py
Normal file
0
esphome/components/es8156/__init__.py
Normal file
27
esphome/components/es8156/audio_dac.py
Normal file
27
esphome/components/es8156/audio_dac.py
Normal file
@ -0,0 +1,27 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
from esphome.components.audio_dac import AudioDac
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
CODEOWNERS = ["@kbx81"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
es8156_ns = cg.esphome_ns.namespace("es8156")
|
||||
ES8156 = es8156_ns.class_("ES8156", AudioDac, cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ES8156),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x08))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
87
esphome/components/es8156/es8156.cpp
Normal file
87
esphome/components/es8156/es8156.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "es8156.h"
|
||||
#include "es8156_const.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace es8156 {
|
||||
|
||||
static const char *const TAG = "es8156";
|
||||
|
||||
// Mark the component as failed; use only in setup
|
||||
#define ES8156_ERROR_FAILED(func) \
|
||||
if (!(func)) { \
|
||||
this->mark_failed(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
void ES8156::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ES8156...");
|
||||
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG02_SCLK_MODE, 0x04));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG20_ANALOG_SYS1, 0x2A));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG21_ANALOG_SYS2, 0x3C));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG22_ANALOG_SYS3, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG24_ANALOG_LP, 0x07));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG23_ANALOG_SYS4, 0x00));
|
||||
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0A_TIME_CONTROL1, 0x01));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0B_TIME_CONTROL2, 0x01));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG11_DAC_SDP, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG19_EQ_CONTROL1, 0x20));
|
||||
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0D_P2S_CONTROL, 0x14));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG09_MISC_CONTROL2, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG18_MISC_CONTROL3, 0x00));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG08_CLOCK_ON_OFF, 0x3F));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG00_RESET, 0x02));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG00_RESET, 0x03));
|
||||
ES8156_ERROR_FAILED(this->write_byte(ES8156_REG25_ANALOG_SYS5, 0x20));
|
||||
}
|
||||
|
||||
void ES8156::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ES8156 Audio Codec:");
|
||||
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGCONFIG(TAG, " Failed to initialize");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool ES8156::set_volume(float volume) {
|
||||
volume = clamp(volume, 0.0f, 1.0f);
|
||||
uint8_t reg = remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 255);
|
||||
ESP_LOGV(TAG, "Setting ES8156_REG14_VOLUME_CONTROL to %u (volume: %f)", reg, volume);
|
||||
return this->write_byte(ES8156_REG14_VOLUME_CONTROL, reg);
|
||||
}
|
||||
|
||||
float ES8156::volume() {
|
||||
uint8_t reg;
|
||||
this->read_byte(ES8156_REG14_VOLUME_CONTROL, ®);
|
||||
return remap<float, uint8_t>(reg, 0, 255, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
bool ES8156::set_mute_state_(bool mute_state) {
|
||||
uint8_t reg13;
|
||||
|
||||
this->is_muted_ = mute_state;
|
||||
|
||||
if (!this->read_byte(ES8156_REG13_DAC_MUTE, ®13)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Read ES8156_REG13_DAC_MUTE: %u", reg13);
|
||||
|
||||
if (mute_state) {
|
||||
reg13 |= BIT(1) | BIT(2);
|
||||
} else {
|
||||
reg13 &= ~(BIT(1) | BIT(2));
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Setting ES8156_REG13_DAC_MUTE to %u (muted: %s)", reg13, YESNO(mute_state));
|
||||
return this->write_byte(ES8156_REG13_DAC_MUTE, reg13);
|
||||
}
|
||||
|
||||
} // namespace es8156
|
||||
} // namespace esphome
|
51
esphome/components/es8156/es8156.h
Normal file
51
esphome/components/es8156/es8156.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/audio_dac/audio_dac.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es8156 {
|
||||
|
||||
class ES8156 : public audio_dac::AudioDac, public Component, public i2c::I2CDevice {
|
||||
public:
|
||||
/////////////////////////
|
||||
// Component overrides //
|
||||
/////////////////////////
|
||||
|
||||
void setup() override;
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
void dump_config() override;
|
||||
|
||||
////////////////////////
|
||||
// AudioDac overrides //
|
||||
////////////////////////
|
||||
|
||||
/// @brief Writes the volume out to the DAC
|
||||
/// @param volume floating point between 0.0 and 1.0
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_volume(float volume) override;
|
||||
|
||||
/// @brief Gets the current volume out from the DAC
|
||||
/// @return floating point between 0.0 and 1.0
|
||||
float volume() override;
|
||||
|
||||
/// @brief Disables mute for audio out
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_mute_off() override { return this->set_mute_state_(false); }
|
||||
|
||||
/// @brief Enables mute for audio out
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_mute_on() override { return this->set_mute_state_(true); }
|
||||
|
||||
bool is_muted() override { return this->is_muted_; }
|
||||
|
||||
protected:
|
||||
/// @brief Mutes or unmutes the DAC audio out
|
||||
/// @param mute_state True to mute, false to unmute
|
||||
/// @return True if successful and false otherwise
|
||||
bool set_mute_state_(bool mute_state);
|
||||
};
|
||||
|
||||
} // namespace es8156
|
||||
} // namespace esphome
|
68
esphome/components/es8156/es8156_const.h
Normal file
68
esphome/components/es8156/es8156_const.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "es8156.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace es8156 {
|
||||
|
||||
/* ES8156 register addresses */
|
||||
/*
|
||||
* RESET Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG00_RESET = 0x00;
|
||||
/*
|
||||
* Clock Managerment
|
||||
*/
|
||||
static const uint8_t ES8156_REG01_MAINCLOCK_CTL = 0x01;
|
||||
static const uint8_t ES8156_REG02_SCLK_MODE = 0x02;
|
||||
static const uint8_t ES8156_REG03_LRCLK_DIV_H = 0x03;
|
||||
static const uint8_t ES8156_REG04_LRCLK_DIV_L = 0x04;
|
||||
static const uint8_t ES8156_REG05_SCLK_DIV = 0x05;
|
||||
static const uint8_t ES8156_REG06_NFS_CONFIG = 0x06;
|
||||
static const uint8_t ES8156_REG07_MISC_CONTROL1 = 0x07;
|
||||
static const uint8_t ES8156_REG08_CLOCK_ON_OFF = 0x08;
|
||||
static const uint8_t ES8156_REG09_MISC_CONTROL2 = 0x09;
|
||||
static const uint8_t ES8156_REG0A_TIME_CONTROL1 = 0x0a;
|
||||
static const uint8_t ES8156_REG0B_TIME_CONTROL2 = 0x0b;
|
||||
/*
|
||||
* System Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG0C_CHIP_STATUS = 0x0c;
|
||||
static const uint8_t ES8156_REG0D_P2S_CONTROL = 0x0d;
|
||||
static const uint8_t ES8156_REG10_DAC_OSR_COUNTER = 0x10;
|
||||
/*
|
||||
* SDP Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG11_DAC_SDP = 0x11;
|
||||
static const uint8_t ES8156_REG12_AUTOMUTE_SET = 0x12;
|
||||
static const uint8_t ES8156_REG13_DAC_MUTE = 0x13;
|
||||
static const uint8_t ES8156_REG14_VOLUME_CONTROL = 0x14;
|
||||
|
||||
/*
|
||||
* ALC Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG15_ALC_CONFIG1 = 0x15;
|
||||
static const uint8_t ES8156_REG16_ALC_CONFIG2 = 0x16;
|
||||
static const uint8_t ES8156_REG17_ALC_CONFIG3 = 0x17;
|
||||
static const uint8_t ES8156_REG18_MISC_CONTROL3 = 0x18;
|
||||
static const uint8_t ES8156_REG19_EQ_CONTROL1 = 0x19;
|
||||
static const uint8_t ES8156_REG1A_EQ_CONTROL2 = 0x1a;
|
||||
/*
|
||||
* Analog System Control
|
||||
*/
|
||||
static const uint8_t ES8156_REG20_ANALOG_SYS1 = 0x20;
|
||||
static const uint8_t ES8156_REG21_ANALOG_SYS2 = 0x21;
|
||||
static const uint8_t ES8156_REG22_ANALOG_SYS3 = 0x22;
|
||||
static const uint8_t ES8156_REG23_ANALOG_SYS4 = 0x23;
|
||||
static const uint8_t ES8156_REG24_ANALOG_LP = 0x24;
|
||||
static const uint8_t ES8156_REG25_ANALOG_SYS5 = 0x25;
|
||||
/*
|
||||
* Chip Information
|
||||
*/
|
||||
static const uint8_t ES8156_REGFC_I2C_PAGESEL = 0xFC;
|
||||
static const uint8_t ES8156_REGFD_CHIPID1 = 0xFD;
|
||||
static const uint8_t ES8156_REGFE_CHIPID0 = 0xFE;
|
||||
static const uint8_t ES8156_REGFF_CHIP_VERSION = 0xFF;
|
||||
|
||||
} // namespace es8156
|
||||
} // namespace esphome
|
@ -52,7 +52,12 @@ void ESP32TouchComponent::setup() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
touch_pad_set_measurement_clock_cycles(this->meas_cycle_);
|
||||
touch_pad_set_measurement_interval(this->sleep_cycle_);
|
||||
#else
|
||||
touch_pad_set_meas_time(this->sleep_cycle_, this->meas_cycle_);
|
||||
#endif
|
||||
touch_pad_set_voltage(this->high_voltage_reference_, this->low_voltage_reference_, this->voltage_attenuation_);
|
||||
|
||||
for (auto *child : this->children_) {
|
||||
|
@ -282,7 +282,7 @@ IMAGE_TYPE = {
|
||||
|
||||
TransparencyType = image_ns.enum("TransparencyType")
|
||||
|
||||
CONF_USE_TRANSPARENCY = "use_transparency"
|
||||
CONF_TRANSPARENCY = "transparency"
|
||||
|
||||
# If the MDI file cannot be downloaded within this time, abort.
|
||||
IMAGE_DOWNLOAD_TIMEOUT = 30 # seconds
|
||||
@ -417,7 +417,7 @@ def validate_type(image_types):
|
||||
|
||||
def validate_settings(value):
|
||||
type = value[CONF_TYPE]
|
||||
transparency = value[CONF_USE_TRANSPARENCY].lower()
|
||||
transparency = value[CONF_TRANSPARENCY].lower()
|
||||
allow_config = IMAGE_TYPE[type].allow_config
|
||||
if transparency not in allow_config:
|
||||
raise cv.Invalid(
|
||||
@ -458,9 +458,7 @@ BASE_SCHEMA = cv.Schema(
|
||||
IMAGE_SCHEMA = BASE_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_TYPE): validate_type(IMAGE_TYPE),
|
||||
cv.Optional(
|
||||
CONF_USE_TRANSPARENCY, default=CONF_OPAQUE
|
||||
): validate_transparency(),
|
||||
cv.Optional(CONF_TRANSPARENCY, default=CONF_OPAQUE): validate_transparency(),
|
||||
}
|
||||
)
|
||||
|
||||
@ -476,7 +474,7 @@ def typed_image_schema(image_type):
|
||||
BASE_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_USE_TRANSPARENCY, default=t
|
||||
CONF_TRANSPARENCY, default=t
|
||||
): validate_transparency((t,)),
|
||||
cv.Optional(CONF_TYPE, default=image_type): validate_type(
|
||||
(image_type,)
|
||||
@ -494,7 +492,7 @@ def typed_image_schema(image_type):
|
||||
BASE_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_USE_TRANSPARENCY, default=CONF_OPAQUE
|
||||
CONF_TRANSPARENCY, default=CONF_OPAQUE
|
||||
): validate_transparency(),
|
||||
cv.Optional(CONF_TYPE, default=image_type): validate_type(
|
||||
(image_type,)
|
||||
@ -556,7 +554,7 @@ async def write_image(config, all_frames=False):
|
||||
else Image.Dither.FLOYDSTEINBERG
|
||||
)
|
||||
type = config[CONF_TYPE]
|
||||
transparency = config[CONF_USE_TRANSPARENCY]
|
||||
transparency = config[CONF_TRANSPARENCY]
|
||||
invert_alpha = config[CONF_INVERT_ALPHA]
|
||||
frame_count = 1
|
||||
if all_frames:
|
||||
|
@ -5,7 +5,7 @@ import esphome.codegen as cg
|
||||
from esphome.components.http_request import CONF_HTTP_REQUEST_ID, HttpRequestComponent
|
||||
from esphome.components.image import (
|
||||
CONF_INVERT_ALPHA,
|
||||
CONF_USE_TRANSPARENCY,
|
||||
CONF_TRANSPARENCY,
|
||||
IMAGE_SCHEMA,
|
||||
Image_,
|
||||
get_image_type_enum,
|
||||
@ -168,7 +168,7 @@ async def to_code(config):
|
||||
|
||||
url = config[CONF_URL]
|
||||
width, height = config.get(CONF_RESIZE, (0, 0))
|
||||
transparent = get_transparency_enum(config[CONF_USE_TRANSPARENCY])
|
||||
transparent = get_transparency_enum(config[CONF_TRANSPARENCY])
|
||||
|
||||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
|
@ -100,7 +100,7 @@ class DownloadBuffer {
|
||||
void reset() { this->unread_ = 0; }
|
||||
|
||||
protected:
|
||||
ExternalRAMAllocator<uint8_t> allocator_;
|
||||
RAMAllocator<uint8_t> allocator_{};
|
||||
uint8_t *buffer_;
|
||||
size_t size_;
|
||||
/** Total number of downloaded bytes not yet read. */
|
||||
|
@ -83,8 +83,7 @@ class OnlineImage : public PollingComponent,
|
||||
protected:
|
||||
bool validate_url_(const std::string &url);
|
||||
|
||||
using Allocator = ExternalRAMAllocator<uint8_t>;
|
||||
Allocator allocator_{Allocator::Flags::ALLOW_FAILURE};
|
||||
RAMAllocator<uint8_t> allocator_{};
|
||||
|
||||
uint32_t get_buffer_size_() const { return get_buffer_size_(this->buffer_width_, this->buffer_height_); }
|
||||
int get_buffer_size_(int width, int height) const { return (this->get_bpp() * width + 7u) / 8u * height; }
|
||||
|
@ -11,7 +11,7 @@ CONFIG_SCHEMA = text_sensor.text_sensor_schema(
|
||||
UptimeTextSensor,
|
||||
icon=ICON_TIMER,
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
).extend(cv.polling_component_schema("30s"))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
|
@ -9,34 +9,51 @@ namespace uptime {
|
||||
|
||||
static const char *const TAG = "uptime.sensor";
|
||||
|
||||
void UptimeTextSensor::setup() { this->last_ms_ = millis(); }
|
||||
void UptimeTextSensor::setup() {
|
||||
this->last_ms_ = millis();
|
||||
if (this->last_ms_ < 60 * 1000)
|
||||
this->last_ms_ = 0;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void UptimeTextSensor::update() {
|
||||
const auto now = millis();
|
||||
auto now = millis();
|
||||
// get whole seconds since last update. Note that even if the millis count has overflowed between updates,
|
||||
// the difference will still be correct due to the way twos-complement arithmetic works.
|
||||
const uint32_t delta = (now - this->last_ms_) / 1000;
|
||||
if (delta == 0)
|
||||
return;
|
||||
// set last_ms_ to the last second boundary
|
||||
this->last_ms_ = now - (now % 1000);
|
||||
uint32_t delta = now - this->last_ms_;
|
||||
this->last_ms_ = now - delta % 1000; // save remainder for next update
|
||||
delta /= 1000;
|
||||
this->uptime_ += delta;
|
||||
auto uptime = this->uptime_;
|
||||
unsigned days = uptime / (24 * 3600);
|
||||
unsigned seconds = uptime % (24 * 3600);
|
||||
unsigned hours = seconds / 3600;
|
||||
seconds %= 3600;
|
||||
unsigned minutes = seconds / 60;
|
||||
seconds %= 60;
|
||||
if (days != 0) {
|
||||
this->publish_state(str_sprintf("%dd%dh%dm%ds", days, hours, minutes, seconds));
|
||||
} else if (hours != 0) {
|
||||
this->publish_state(str_sprintf("%dh%dm%ds", hours, minutes, seconds));
|
||||
} else if (minutes != 0) {
|
||||
this->publish_state(str_sprintf("%dm%ds", minutes, seconds));
|
||||
} else {
|
||||
this->publish_state(str_sprintf("%ds", seconds));
|
||||
unsigned interval = this->get_update_interval() / 1000;
|
||||
std::string buffer{};
|
||||
// display from the largest unit that corresponds to the update interval, drop larger units that are zero.
|
||||
while (true) { // enable use of break for early exit
|
||||
unsigned remainder = uptime % 60;
|
||||
uptime /= 60;
|
||||
if (interval < 30) {
|
||||
buffer.insert(0, str_sprintf("%us", remainder));
|
||||
if (uptime == 0)
|
||||
break;
|
||||
}
|
||||
remainder = uptime % 60;
|
||||
uptime /= 60;
|
||||
if (interval < 1800) {
|
||||
buffer.insert(0, str_sprintf("%um", remainder));
|
||||
if (uptime == 0)
|
||||
break;
|
||||
}
|
||||
remainder = uptime % 24;
|
||||
uptime /= 24;
|
||||
if (interval < 12 * 3600) {
|
||||
buffer.insert(0, str_sprintf("%uh", remainder));
|
||||
if (uptime == 0)
|
||||
break;
|
||||
}
|
||||
buffer.insert(0, str_sprintf("%ud", (unsigned) uptime));
|
||||
break;
|
||||
}
|
||||
this->publish_state(buffer);
|
||||
}
|
||||
|
||||
float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
|
@ -17,8 +17,8 @@ class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent
|
||||
float get_setup_priority() const override;
|
||||
|
||||
protected:
|
||||
uint64_t uptime_{0};
|
||||
uint64_t last_ms_{0};
|
||||
uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
|
||||
uint32_t last_ms_{0};
|
||||
};
|
||||
|
||||
} // namespace uptime
|
||||
|
@ -72,7 +72,8 @@ void WaveshareEPaper2P13InV3::write_buffer_(uint8_t cmd, int top, int bottom) {
|
||||
this->set_window_(top, bottom);
|
||||
this->command(cmd);
|
||||
this->start_data_();
|
||||
auto width_bytes = this->get_width_internal() / 8;
|
||||
|
||||
auto width_bytes = this->get_width_controller() / 8;
|
||||
this->write_array(this->buffer_ + top * width_bytes, (bottom - top) * width_bytes);
|
||||
this->end_data_();
|
||||
}
|
||||
@ -162,7 +163,8 @@ void WaveshareEPaper2P13InV3::display() {
|
||||
}
|
||||
}
|
||||
|
||||
int WaveshareEPaper2P13InV3::get_width_internal() { return 128; }
|
||||
int WaveshareEPaper2P13InV3::get_width_controller() { return 128; }
|
||||
int WaveshareEPaper2P13InV3::get_width_internal() { return 122; }
|
||||
|
||||
int WaveshareEPaper2P13InV3::get_height_internal() { return 250; }
|
||||
|
||||
|
@ -811,6 +811,7 @@ class WaveshareEPaper2P13InV3 : public WaveshareEPaper {
|
||||
void initialize() override;
|
||||
|
||||
protected:
|
||||
int get_width_controller() override;
|
||||
int get_width_internal() override;
|
||||
int get_height_internal() override;
|
||||
uint32_t idle_timeout_() override;
|
||||
|
@ -1,21 +1,16 @@
|
||||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ARDUINO_VERSION,
|
||||
CONF_AREA,
|
||||
CONF_BOARD,
|
||||
CONF_BOARD_FLASH_MODE,
|
||||
CONF_BUILD_PATH,
|
||||
CONF_COMMENT,
|
||||
CONF_COMPILE_PROCESS_LIMIT,
|
||||
CONF_ESPHOME,
|
||||
CONF_FRAMEWORK,
|
||||
CONF_FRIENDLY_NAME,
|
||||
CONF_INCLUDES,
|
||||
CONF_LIBRARIES,
|
||||
@ -30,12 +25,9 @@ from esphome.const import (
|
||||
CONF_PLATFORMIO_OPTIONS,
|
||||
CONF_PRIORITY,
|
||||
CONF_PROJECT,
|
||||
CONF_SOURCE,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_TYPE,
|
||||
CONF_VERSION,
|
||||
KEY_CORE,
|
||||
PLATFORM_ESP8266,
|
||||
TARGET_PLATFORMS,
|
||||
__version__ as ESPHOME_VERSION,
|
||||
)
|
||||
@ -44,7 +36,6 @@ from esphome.helpers import copy_file_if_changed, get_str_env, walk_files
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
BUILD_FLASH_MODES = ["qio", "qout", "dio", "dout"]
|
||||
StartupTrigger = cg.esphome_ns.class_(
|
||||
"StartupTrigger", cg.Component, automation.Trigger.template()
|
||||
)
|
||||
@ -58,8 +49,6 @@ ProjectUpdateTrigger = cg.esphome_ns.class_(
|
||||
"ProjectUpdateTrigger", cg.Component, automation.Trigger.template(cg.std_string)
|
||||
)
|
||||
|
||||
VERSION_REGEX = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+(?:[ab]\d+)?$")
|
||||
|
||||
|
||||
VALID_INCLUDE_EXTS = {".h", ".hpp", ".tcc", ".ino", ".cpp", ".c"}
|
||||
|
||||
@ -111,7 +100,6 @@ else:
|
||||
_compile_process_limit_default = cv.UNDEFINED
|
||||
|
||||
|
||||
CONF_ESP8266_RESTORE_FROM_FLASH = "esp8266_restore_from_flash"
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
@ -175,14 +163,9 @@ PRELOAD_CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.valid_name,
|
||||
cv.Optional(CONF_BUILD_PATH): cv.string,
|
||||
# Compat options, these were moved to target-platform specific sections
|
||||
# but we'll keep these around for a long time because every config would
|
||||
# be impacted
|
||||
cv.Optional(CONF_PLATFORM): cv.one_of(*TARGET_PLATFORMS, lower=True),
|
||||
cv.Optional(CONF_BOARD): cv.string_strict,
|
||||
cv.Optional(CONF_ESP8266_RESTORE_FROM_FLASH): cv.valid,
|
||||
cv.Optional(CONF_BOARD_FLASH_MODE): cv.valid,
|
||||
cv.Optional(CONF_ARDUINO_VERSION): cv.valid,
|
||||
cv.Optional(CONF_PLATFORM): cv.invalid(
|
||||
"Please remove the `platform` key from the [esphome] block and use the correct platform component. This style of configuration has now been removed."
|
||||
),
|
||||
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
|
||||
cv.version_number, cv.validate_esphome_version
|
||||
),
|
||||
@ -204,62 +187,20 @@ def preload_core_config(config, result):
|
||||
conf[CONF_BUILD_PATH] = os.path.join(build_path, CORE.name)
|
||||
CORE.build_path = CORE.relative_internal_path(conf[CONF_BUILD_PATH])
|
||||
|
||||
has_oldstyle = CONF_PLATFORM in conf
|
||||
newstyle_found = [key for key in TARGET_PLATFORMS if key in config]
|
||||
oldstyle_opts = [
|
||||
CONF_ESP8266_RESTORE_FROM_FLASH,
|
||||
CONF_BOARD_FLASH_MODE,
|
||||
CONF_ARDUINO_VERSION,
|
||||
CONF_BOARD,
|
||||
]
|
||||
target_platforms = [key for key in TARGET_PLATFORMS if key in config]
|
||||
|
||||
if not has_oldstyle and not newstyle_found:
|
||||
if not target_platforms:
|
||||
raise cv.Invalid(
|
||||
"Platform missing. You must include one of the available platform keys: "
|
||||
+ ", ".join(TARGET_PLATFORMS),
|
||||
[CONF_ESPHOME],
|
||||
)
|
||||
if has_oldstyle and newstyle_found:
|
||||
if len(target_platforms) > 1:
|
||||
raise cv.Invalid(
|
||||
f"Please remove the `platform` key from the [esphome] block. You're already using the new style with the [{conf[CONF_PLATFORM]}] block",
|
||||
[CONF_ESPHOME, CONF_PLATFORM],
|
||||
)
|
||||
if len(newstyle_found) > 1:
|
||||
raise cv.Invalid(
|
||||
f"Found multiple target platform blocks: {', '.join(newstyle_found)}. Only one is allowed.",
|
||||
[newstyle_found[0]],
|
||||
)
|
||||
if newstyle_found:
|
||||
# Convert to newstyle
|
||||
for key in oldstyle_opts:
|
||||
if key in conf:
|
||||
raise cv.Invalid(
|
||||
f"Please move {key} to the [{newstyle_found[0]}] block.",
|
||||
[CONF_ESPHOME, key],
|
||||
f"Found multiple target platform blocks: {', '.join(target_platforms)}. Only one is allowed.",
|
||||
[target_platforms[0]],
|
||||
)
|
||||
|
||||
if has_oldstyle:
|
||||
plat = conf.pop(CONF_PLATFORM)
|
||||
plat_conf = {}
|
||||
if CONF_ESP8266_RESTORE_FROM_FLASH in conf:
|
||||
plat_conf["restore_from_flash"] = conf.pop(CONF_ESP8266_RESTORE_FROM_FLASH)
|
||||
if CONF_BOARD_FLASH_MODE in conf:
|
||||
plat_conf[CONF_BOARD_FLASH_MODE] = conf.pop(CONF_BOARD_FLASH_MODE)
|
||||
if CONF_ARDUINO_VERSION in conf:
|
||||
plat_conf[CONF_FRAMEWORK] = {}
|
||||
if plat != PLATFORM_ESP8266:
|
||||
plat_conf[CONF_FRAMEWORK][CONF_TYPE] = "arduino"
|
||||
|
||||
try:
|
||||
if conf[CONF_ARDUINO_VERSION] not in ("recommended", "latest", "dev"):
|
||||
cv.Version.parse(conf[CONF_ARDUINO_VERSION])
|
||||
plat_conf[CONF_FRAMEWORK][CONF_VERSION] = conf.pop(CONF_ARDUINO_VERSION)
|
||||
except ValueError:
|
||||
plat_conf[CONF_FRAMEWORK][CONF_SOURCE] = conf.pop(CONF_ARDUINO_VERSION)
|
||||
if CONF_BOARD in conf:
|
||||
plat_conf[CONF_BOARD] = conf.pop(CONF_BOARD)
|
||||
# Insert generated target platform config to main config
|
||||
config[plat] = plat_conf
|
||||
config[CONF_ESPHOME] = conf
|
||||
|
||||
|
||||
|
@ -120,7 +120,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP_IDF
|
||||
#define USE_ESP_IDF_VERSION_CODE VERSION_CODE(4, 4, 2)
|
||||
#define USE_ESP_IDF_VERSION_CODE VERSION_CODE(5, 1, 5)
|
||||
#endif
|
||||
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP8266
|
||||
|
||||
esp8266:
|
||||
board: d1_mini_lite
|
||||
|
||||
binary_sensor:
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP8266
|
||||
|
||||
esp8266:
|
||||
board: d1_mini_lite
|
||||
|
||||
wifi:
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP32
|
||||
|
||||
esp32:
|
||||
board: nodemcu-32s
|
||||
|
||||
deep_sleep:
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP32
|
||||
|
||||
esp32:
|
||||
board: nodemcu-32s
|
||||
|
||||
deep_sleep:
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP8266
|
||||
|
||||
esp8266:
|
||||
board: d1_mini_lite
|
||||
|
||||
sensor:
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP8266
|
||||
|
||||
esp8266:
|
||||
board: d1_mini_lite
|
||||
|
||||
text_sensor:
|
||||
|
@ -2,12 +2,12 @@ animation:
|
||||
- id: rgb565_animation
|
||||
file: $component_dir/anim.gif
|
||||
type: RGB565
|
||||
use_transparency: opaque
|
||||
transparency: opaque
|
||||
resize: 50x50
|
||||
- id: rgb_animation
|
||||
file: $component_dir/anim.apng
|
||||
type: RGB
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
resize: 50x50
|
||||
- id: grayscale_animation
|
||||
file: $component_dir/anim.apng
|
||||
|
@ -1,6 +1,16 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- audio_adc.set_mic_gain: 0db
|
||||
- audio_adc.set_mic_gain: !lambda 'return 4;'
|
||||
|
||||
i2c:
|
||||
- id: i2c_aic3204
|
||||
scl: ${scl_pin}
|
||||
sda: ${sda_pin}
|
||||
|
||||
es7210:
|
||||
audio_adc:
|
||||
- platform: es7210
|
||||
id: es7210_adc
|
||||
bits_per_sample: 16bit
|
||||
sample_rate: 16000
|
||||
|
15
tests/components/es8156/common.yaml
Normal file
15
tests/components/es8156/common.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- audio_dac.mute_off:
|
||||
- audio_dac.mute_on:
|
||||
- audio_dac.set_volume:
|
||||
volume: 50%
|
||||
|
||||
i2c:
|
||||
- id: i2c_es8156
|
||||
scl: ${scl_pin}
|
||||
sda: ${sda_pin}
|
||||
|
||||
audio_dac:
|
||||
- platform: es8156
|
5
tests/components/es8156/test.esp32-ard.yaml
Normal file
5
tests/components/es8156/test.esp32-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp32-c3-ard.yaml
Normal file
5
tests/components/es8156/test.esp32-c3-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp32-c3-idf.yaml
Normal file
5
tests/components/es8156/test.esp32-c3-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp32-idf.yaml
Normal file
5
tests/components/es8156/test.esp32-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/es8156/test.esp8266-ard.yaml
Normal file
5
tests/components/es8156/test.esp8266-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
@ -6,54 +6,54 @@ image:
|
||||
- id: transparent_transparent_image
|
||||
file: ../../pnglogo.png
|
||||
type: BINARY
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
|
||||
- id: rgba_image
|
||||
file: ../../pnglogo.png
|
||||
type: RGB
|
||||
use_transparency: alpha_channel
|
||||
transparency: alpha_channel
|
||||
resize: 50x50
|
||||
- id: rgb24_image
|
||||
file: ../../pnglogo.png
|
||||
type: RGB
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
- id: rgb_image
|
||||
file: ../../pnglogo.png
|
||||
type: RGB
|
||||
use_transparency: opaque
|
||||
transparency: opaque
|
||||
|
||||
- id: rgb565_image
|
||||
file: ../../pnglogo.png
|
||||
type: RGB565
|
||||
use_transparency: opaque
|
||||
transparency: opaque
|
||||
- id: rgb565_ck_image
|
||||
file: ../../pnglogo.png
|
||||
type: RGB565
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
- id: rgb565_alpha_image
|
||||
file: ../../pnglogo.png
|
||||
type: RGB565
|
||||
use_transparency: alpha_channel
|
||||
transparency: alpha_channel
|
||||
|
||||
- id: grayscale_alpha_image
|
||||
file: ../../pnglogo.png
|
||||
type: grayscale
|
||||
use_transparency: alpha_channel
|
||||
transparency: alpha_channel
|
||||
resize: 50x50
|
||||
- id: grayscale_ck_image
|
||||
file: ../../pnglogo.png
|
||||
type: grayscale
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
- id: grayscale_image
|
||||
file: ../../pnglogo.png
|
||||
type: grayscale
|
||||
use_transparency: opaque
|
||||
transparency: opaque
|
||||
|
||||
- id: web_svg_image
|
||||
file: https://raw.githubusercontent.com/esphome/esphome-docs/a62d7ab193c1a464ed791670170c7d518189109b/images/logo.svg
|
||||
resize: 256x48
|
||||
type: BINARY
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
- id: web_tiff_image
|
||||
file: https://upload.wikimedia.org/wikipedia/commons/b/b6/SIPI_Jelly_Beans_4.1.07.tiff
|
||||
type: RGB
|
||||
|
@ -12,7 +12,7 @@ image:
|
||||
dither: FloydSteinberg
|
||||
- id: transparent_transparent_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
rgb:
|
||||
alpha_channel:
|
||||
- id: rgba_image
|
||||
@ -28,21 +28,21 @@ image:
|
||||
rgb565:
|
||||
- id: rgb565_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: opaque
|
||||
transparency: opaque
|
||||
- id: rgb565_ck_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
- id: rgb565_alpha_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: alpha_channel
|
||||
transparency: alpha_channel
|
||||
grayscale:
|
||||
- id: grayscale_alpha_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: alpha_channel
|
||||
transparency: alpha_channel
|
||||
resize: 50x50
|
||||
- id: grayscale_ck_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
- id: grayscale_image
|
||||
file: ../../pnglogo.png
|
||||
use_transparency: opaque
|
||||
transparency: opaque
|
||||
|
@ -14,18 +14,18 @@ online_image:
|
||||
- id: online_binary_transparent_image
|
||||
url: http://www.libpng.org/pub/png/img_png/pnglogo-blk-tiny.png
|
||||
type: BINARY
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
format: png
|
||||
- id: online_rgba_image
|
||||
url: http://www.libpng.org/pub/png/img_png/pnglogo-blk-tiny.png
|
||||
format: PNG
|
||||
type: RGB
|
||||
use_transparency: alpha_channel
|
||||
transparency: alpha_channel
|
||||
- id: online_rgb24_image
|
||||
url: http://www.libpng.org/pub/png/img_png/pnglogo-blk-tiny.png
|
||||
format: PNG
|
||||
type: RGB
|
||||
use_transparency: chroma_key
|
||||
transparency: chroma_key
|
||||
|
||||
# Check the set_url action
|
||||
esphome:
|
||||
|
@ -12,7 +12,7 @@ esphome:
|
||||
# not overwritten by vars in the !include above
|
||||
name: ${name}
|
||||
name_add_mac_suffix: true
|
||||
platform: esp8266
|
||||
board: !include {file: includes/scalar.yaml, vars: {var1: nodemcu}}
|
||||
|
||||
libraries: !include {file: includes/list.yaml, vars: {var1: Wire}}
|
||||
|
||||
esp8266:
|
||||
board: !include {file: includes/scalar.yaml, vars: {var1: nodemcu}}
|
||||
|
@ -12,7 +12,7 @@ esphome:
|
||||
# not overwritten by vars in the !include above
|
||||
name: ${name}
|
||||
name_add_mac_suffix: true
|
||||
platform: esp8266
|
||||
board: !include {file: includes/scalar.yaml, vars: {var1: nodemcu}}
|
||||
|
||||
libraries: !include {file: includes/list.yaml, vars: {var1: Wire}}
|
||||
|
||||
esp8266:
|
||||
board: !include {file: includes/scalar.yaml, vars: {var1: nodemcu}}
|
||||
|
@ -10,7 +10,7 @@ def test_include_with_vars(fixture_path):
|
||||
substitutions.do_substitution_pass(actual, None)
|
||||
assert actual["esphome"]["name"] == "original"
|
||||
assert actual["esphome"]["libraries"][0] == "Wire"
|
||||
assert actual["esphome"]["board"] == "nodemcu"
|
||||
assert actual["esp8266"]["board"] == "nodemcu"
|
||||
assert actual["wifi"]["ssid"] == "my_custom_ssid"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user