mirror of
https://github.com/esphome/esphome.git
synced 2024-11-29 12:55:46 +01:00
Merge branch 'dev' into optolink
This commit is contained in:
commit
c13d14fcde
@ -155,6 +155,7 @@ esphome/components/iaqcore/* @yozik04
|
|||||||
esphome/components/ili9xxx/* @clydebarrow @nielsnl68
|
esphome/components/ili9xxx/* @clydebarrow @nielsnl68
|
||||||
esphome/components/improv_base/* @esphome/core
|
esphome/components/improv_base/* @esphome/core
|
||||||
esphome/components/improv_serial/* @esphome/core
|
esphome/components/improv_serial/* @esphome/core
|
||||||
|
esphome/components/ina226/* @Sergio303 @latonita
|
||||||
esphome/components/ina260/* @mreditor97
|
esphome/components/ina260/* @mreditor97
|
||||||
esphome/components/inkbird_ibsth1_mini/* @fkirill
|
esphome/components/inkbird_ibsth1_mini/* @fkirill
|
||||||
esphome/components/inkplate6/* @jesserockz
|
esphome/components/inkplate6/* @jesserockz
|
||||||
|
@ -11,6 +11,7 @@ MULTI_CONF = True
|
|||||||
CONF_BME680_BSEC_ID = "bme680_bsec_id"
|
CONF_BME680_BSEC_ID = "bme680_bsec_id"
|
||||||
CONF_TEMPERATURE_OFFSET = "temperature_offset"
|
CONF_TEMPERATURE_OFFSET = "temperature_offset"
|
||||||
CONF_IAQ_MODE = "iaq_mode"
|
CONF_IAQ_MODE = "iaq_mode"
|
||||||
|
CONF_SUPPLY_VOLTAGE = "supply_voltage"
|
||||||
CONF_SAMPLE_RATE = "sample_rate"
|
CONF_SAMPLE_RATE = "sample_rate"
|
||||||
CONF_STATE_SAVE_INTERVAL = "state_save_interval"
|
CONF_STATE_SAVE_INTERVAL = "state_save_interval"
|
||||||
|
|
||||||
@ -22,6 +23,12 @@ IAQ_MODE_OPTIONS = {
|
|||||||
"MOBILE": IAQMode.IAQ_MODE_MOBILE,
|
"MOBILE": IAQMode.IAQ_MODE_MOBILE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SupplyVoltage = bme680_bsec_ns.enum("SupplyVoltage")
|
||||||
|
SUPPLY_VOLTAGE_OPTIONS = {
|
||||||
|
"1.8V": SupplyVoltage.SUPPLY_VOLTAGE_1V8,
|
||||||
|
"3.3V": SupplyVoltage.SUPPLY_VOLTAGE_3V3,
|
||||||
|
}
|
||||||
|
|
||||||
SampleRate = bme680_bsec_ns.enum("SampleRate")
|
SampleRate = bme680_bsec_ns.enum("SampleRate")
|
||||||
SAMPLE_RATE_OPTIONS = {
|
SAMPLE_RATE_OPTIONS = {
|
||||||
"LP": SampleRate.SAMPLE_RATE_LP,
|
"LP": SampleRate.SAMPLE_RATE_LP,
|
||||||
@ -40,6 +47,9 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
cv.Optional(CONF_IAQ_MODE, default="STATIC"): cv.enum(
|
cv.Optional(CONF_IAQ_MODE, default="STATIC"): cv.enum(
|
||||||
IAQ_MODE_OPTIONS, upper=True
|
IAQ_MODE_OPTIONS, upper=True
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_SUPPLY_VOLTAGE, default="3.3V"): cv.enum(
|
||||||
|
SUPPLY_VOLTAGE_OPTIONS, upper=True
|
||||||
|
),
|
||||||
cv.Optional(CONF_SAMPLE_RATE, default="LP"): cv.enum(
|
cv.Optional(CONF_SAMPLE_RATE, default="LP"): cv.enum(
|
||||||
SAMPLE_RATE_OPTIONS, upper=True
|
SAMPLE_RATE_OPTIONS, upper=True
|
||||||
),
|
),
|
||||||
@ -67,6 +77,7 @@ async def to_code(config):
|
|||||||
cg.add(var.set_device_id(str(config[CONF_ID])))
|
cg.add(var.set_device_id(str(config[CONF_ID])))
|
||||||
cg.add(var.set_temperature_offset(config[CONF_TEMPERATURE_OFFSET]))
|
cg.add(var.set_temperature_offset(config[CONF_TEMPERATURE_OFFSET]))
|
||||||
cg.add(var.set_iaq_mode(config[CONF_IAQ_MODE]))
|
cg.add(var.set_iaq_mode(config[CONF_IAQ_MODE]))
|
||||||
|
cg.add(var.set_supply_voltage(config[CONF_SUPPLY_VOLTAGE]))
|
||||||
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
||||||
cg.add(
|
cg.add(
|
||||||
var.set_state_save_interval(config[CONF_STATE_SAVE_INTERVAL].total_milliseconds)
|
var.set_state_save_interval(config[CONF_STATE_SAVE_INTERVAL].total_milliseconds)
|
||||||
|
@ -52,17 +52,33 @@ void BME680BSECComponent::setup() {
|
|||||||
|
|
||||||
void BME680BSECComponent::set_config_() {
|
void BME680BSECComponent::set_config_() {
|
||||||
if (this->sample_rate_ == SAMPLE_RATE_ULP) {
|
if (this->sample_rate_ == SAMPLE_RATE_ULP) {
|
||||||
const uint8_t config[] = {
|
if (this->supply_voltage_ == SUPPLY_VOLTAGE_3V3) {
|
||||||
|
const uint8_t config[] = {
|
||||||
#include "config/generic_33v_300s_28d/bsec_iaq.txt"
|
#include "config/generic_33v_300s_28d/bsec_iaq.txt"
|
||||||
};
|
};
|
||||||
this->bsec_status_ =
|
this->bsec_status_ =
|
||||||
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
} else {
|
} else { // SUPPLY_VOLTAGE_1V8
|
||||||
const uint8_t config[] = {
|
const uint8_t config[] = {
|
||||||
|
#include "config/generic_18v_300s_28d/bsec_iaq.txt"
|
||||||
|
};
|
||||||
|
this->bsec_status_ =
|
||||||
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
|
}
|
||||||
|
} else { // SAMPLE_RATE_LP
|
||||||
|
if (this->supply_voltage_ == SUPPLY_VOLTAGE_3V3) {
|
||||||
|
const uint8_t config[] = {
|
||||||
#include "config/generic_33v_3s_28d/bsec_iaq.txt"
|
#include "config/generic_33v_3s_28d/bsec_iaq.txt"
|
||||||
};
|
};
|
||||||
this->bsec_status_ =
|
this->bsec_status_ =
|
||||||
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
|
} else { // SUPPLY_VOLTAGE_1V8
|
||||||
|
const uint8_t config[] = {
|
||||||
|
#include "config/generic_18v_3s_28d/bsec_iaq.txt"
|
||||||
|
};
|
||||||
|
this->bsec_status_ =
|
||||||
|
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +161,7 @@ void BME680BSECComponent::dump_config() {
|
|||||||
|
|
||||||
ESP_LOGCONFIG(TAG, " Temperature Offset: %.2f", this->temperature_offset_);
|
ESP_LOGCONFIG(TAG, " Temperature Offset: %.2f", this->temperature_offset_);
|
||||||
ESP_LOGCONFIG(TAG, " IAQ Mode: %s", this->iaq_mode_ == IAQ_MODE_STATIC ? "Static" : "Mobile");
|
ESP_LOGCONFIG(TAG, " IAQ Mode: %s", this->iaq_mode_ == IAQ_MODE_STATIC ? "Static" : "Mobile");
|
||||||
|
ESP_LOGCONFIG(TAG, " Supply Voltage: %sV", this->supply_voltage_ == SUPPLY_VOLTAGE_3V3 ? "3.3" : "1.8");
|
||||||
ESP_LOGCONFIG(TAG, " Sample Rate: %s", BME680_BSEC_SAMPLE_RATE_LOG(this->sample_rate_));
|
ESP_LOGCONFIG(TAG, " Sample Rate: %s", BME680_BSEC_SAMPLE_RATE_LOG(this->sample_rate_));
|
||||||
ESP_LOGCONFIG(TAG, " State Save Interval: %ims", this->state_save_interval_ms_);
|
ESP_LOGCONFIG(TAG, " State Save Interval: %ims", this->state_save_interval_ms_);
|
||||||
|
|
||||||
|
@ -21,6 +21,11 @@ enum IAQMode {
|
|||||||
IAQ_MODE_MOBILE = 1,
|
IAQ_MODE_MOBILE = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SupplyVoltage {
|
||||||
|
SUPPLY_VOLTAGE_3V3 = 0,
|
||||||
|
SUPPLY_VOLTAGE_1V8 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
enum SampleRate {
|
enum SampleRate {
|
||||||
SAMPLE_RATE_LP = 0,
|
SAMPLE_RATE_LP = 0,
|
||||||
SAMPLE_RATE_ULP = 1,
|
SAMPLE_RATE_ULP = 1,
|
||||||
@ -35,6 +40,7 @@ class BME680BSECComponent : public Component, public i2c::I2CDevice {
|
|||||||
void set_temperature_offset(float offset) { this->temperature_offset_ = offset; }
|
void set_temperature_offset(float offset) { this->temperature_offset_ = offset; }
|
||||||
void set_iaq_mode(IAQMode iaq_mode) { this->iaq_mode_ = iaq_mode; }
|
void set_iaq_mode(IAQMode iaq_mode) { this->iaq_mode_ = iaq_mode; }
|
||||||
void set_state_save_interval(uint32_t interval) { this->state_save_interval_ms_ = interval; }
|
void set_state_save_interval(uint32_t interval) { this->state_save_interval_ms_ = interval; }
|
||||||
|
void set_supply_voltage(SupplyVoltage supply_voltage) { this->supply_voltage_ = supply_voltage; }
|
||||||
|
|
||||||
void set_sample_rate(SampleRate sample_rate) { this->sample_rate_ = sample_rate; }
|
void set_sample_rate(SampleRate sample_rate) { this->sample_rate_ = sample_rate; }
|
||||||
void set_temperature_sample_rate(SampleRate sample_rate) { this->temperature_sample_rate_ = sample_rate; }
|
void set_temperature_sample_rate(SampleRate sample_rate) { this->temperature_sample_rate_ = sample_rate; }
|
||||||
@ -109,6 +115,7 @@ class BME680BSECComponent : public Component, public i2c::I2CDevice {
|
|||||||
std::string device_id_;
|
std::string device_id_;
|
||||||
float temperature_offset_{0};
|
float temperature_offset_{0};
|
||||||
IAQMode iaq_mode_{IAQ_MODE_STATIC};
|
IAQMode iaq_mode_{IAQ_MODE_STATIC};
|
||||||
|
SupplyVoltage supply_voltage_;
|
||||||
|
|
||||||
SampleRate sample_rate_{SAMPLE_RATE_LP}; // Core/gas sample rate
|
SampleRate sample_rate_{SAMPLE_RATE_LP}; // Core/gas sample rate
|
||||||
SampleRate temperature_sample_rate_{SAMPLE_RATE_DEFAULT};
|
SampleRate temperature_sample_rate_{SAMPLE_RATE_DEFAULT};
|
||||||
|
@ -168,10 +168,6 @@ bool IRAM_ATTR DallasTemperatureSensor::read_scratch_pad() {
|
|||||||
if (!wire->reset()) {
|
if (!wire->reset()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
InterruptLock lock;
|
|
||||||
|
|
||||||
wire->select(this->address_);
|
wire->select(this->address_);
|
||||||
wire->write8(DALLAS_COMMAND_READ_SCRATCH_PAD);
|
wire->write8(DALLAS_COMMAND_READ_SCRATCH_PAD);
|
||||||
|
@ -160,7 +160,7 @@ light::ESPColorView ESP32RMTLEDStripLightOutput::get_view_internal(int32_t index
|
|||||||
b = 0;
|
b = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint8_t multiplier = this->is_rgbw_ ? 4 : 3;
|
uint8_t multiplier = this->is_rgbw_ || this->is_wrgb_ ? 4 : 3;
|
||||||
uint8_t white = this->is_wrgb_ ? 0 : 3;
|
uint8_t white = this->is_wrgb_ ? 0 : 3;
|
||||||
|
|
||||||
return {this->buf_ + (index * multiplier) + r + this->is_wrgb_,
|
return {this->buf_ + (index * multiplier) + r + this->is_wrgb_,
|
||||||
|
@ -119,4 +119,4 @@ def to_code(config):
|
|||||||
cg.add_library("tonia/HeatpumpIR", "1.0.23")
|
cg.add_library("tonia/HeatpumpIR", "1.0.23")
|
||||||
|
|
||||||
if CORE.is_esp8266 or CORE.is_esp32:
|
if CORE.is_esp8266 or CORE.is_esp32:
|
||||||
cg.add_library("crankyoldgit/IRremoteESP8266", "2.7.12")
|
cg.add_library("crankyoldgit/IRremoteESP8266", "2.8.4")
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
CODEOWNERS = ["@Sergio303", "@latonita"]
|
@ -33,31 +33,37 @@ static const uint8_t INA226_REGISTER_POWER = 0x03;
|
|||||||
static const uint8_t INA226_REGISTER_CURRENT = 0x04;
|
static const uint8_t INA226_REGISTER_CURRENT = 0x04;
|
||||||
static const uint8_t INA226_REGISTER_CALIBRATION = 0x05;
|
static const uint8_t INA226_REGISTER_CALIBRATION = 0x05;
|
||||||
|
|
||||||
|
static const uint16_t INA226_ADC_TIMES[] = {140, 204, 332, 588, 1100, 2116, 4156, 8244};
|
||||||
|
static const uint16_t INA226_ADC_AVG_SAMPLES[] = {1, 4, 16, 64, 128, 256, 512, 1024};
|
||||||
|
|
||||||
void INA226Component::setup() {
|
void INA226Component::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up INA226...");
|
ESP_LOGCONFIG(TAG, "Setting up INA226...");
|
||||||
// Config Register
|
|
||||||
// 0bx000000000000000 << 15 RESET Bit (1 -> trigger reset)
|
ConfigurationRegister config;
|
||||||
if (!this->write_byte_16(INA226_REGISTER_CONFIG, 0x8000)) {
|
|
||||||
|
config.reset = 1;
|
||||||
|
if (!this->write_byte_16(INA226_REGISTER_CONFIG, config.raw)) {
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
uint16_t config = 0x0000;
|
config.raw = 0;
|
||||||
|
config.reserved = 0b100; // as per datasheet
|
||||||
|
|
||||||
// Averaging Mode AVG Bit Settings[11:9] (000 -> 1 sample, 001 -> 4 sample, 111 -> 1024 samples)
|
// Averaging Mode AVG Bit Settings[11:9] (000 -> 1 sample, 001 -> 4 sample, 111 -> 1024 samples)
|
||||||
config |= 0b0000001000000000;
|
config.avg_samples = this->adc_avg_samples_;
|
||||||
|
|
||||||
// Bus Voltage Conversion Time VBUSCT Bit Settings [8:6] (100 -> 1.1ms, 111 -> 8.244 ms)
|
// Bus Voltage Conversion Time VBUSCT Bit Settings [8:6] (100 -> 1.1ms, 111 -> 8.244 ms)
|
||||||
config |= 0b0000000100000000;
|
config.bus_voltage_conversion_time = this->adc_time_;
|
||||||
|
|
||||||
// Shunt Voltage Conversion Time VSHCT Bit Settings [5:3] (100 -> 1.1ms, 111 -> 8.244 ms)
|
// Shunt Voltage Conversion Time VSHCT Bit Settings [5:3] (100 -> 1.1ms, 111 -> 8.244 ms)
|
||||||
config |= 0b0000000000100000;
|
config.shunt_voltage_conversion_time = this->adc_time_;
|
||||||
|
|
||||||
// Mode Settings [2:0] Combinations (111 -> Shunt and Bus, Continuous)
|
// Mode Settings [2:0] Combinations (111 -> Shunt and Bus, Continuous)
|
||||||
config |= 0b0000000000000111;
|
config.mode = 0b111;
|
||||||
|
|
||||||
if (!this->write_byte_16(INA226_REGISTER_CONFIG, config)) {
|
if (!this->write_byte_16(INA226_REGISTER_CONFIG, config.raw)) {
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -87,6 +93,9 @@ void INA226Component::dump_config() {
|
|||||||
}
|
}
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG, " ADC Conversion Time: %d", INA226_ADC_TIMES[this->adc_time_ & 0b111]);
|
||||||
|
ESP_LOGCONFIG(TAG, " ADC Averaging Samples: %d", INA226_ADC_AVG_SAMPLES[this->adc_avg_samples_ & 0b111]);
|
||||||
|
|
||||||
LOG_SENSOR(" ", "Bus Voltage", this->bus_voltage_sensor_);
|
LOG_SENSOR(" ", "Bus Voltage", this->bus_voltage_sensor_);
|
||||||
LOG_SENSOR(" ", "Shunt Voltage", this->shunt_voltage_sensor_);
|
LOG_SENSOR(" ", "Shunt Voltage", this->shunt_voltage_sensor_);
|
||||||
LOG_SENSOR(" ", "Current", this->current_sensor_);
|
LOG_SENSOR(" ", "Current", this->current_sensor_);
|
||||||
@ -102,7 +111,9 @@ void INA226Component::update() {
|
|||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float bus_voltage_v = int16_t(raw_bus_voltage) * 0.00125f;
|
// Convert for 2's compliment and signed value (though always positive)
|
||||||
|
float bus_voltage_v = this->twos_complement_(raw_bus_voltage, 16);
|
||||||
|
bus_voltage_v *= 0.00125f;
|
||||||
this->bus_voltage_sensor_->publish_state(bus_voltage_v);
|
this->bus_voltage_sensor_->publish_state(bus_voltage_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +123,9 @@ void INA226Component::update() {
|
|||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float shunt_voltage_v = int16_t(raw_shunt_voltage) * 0.0000025f;
|
// Convert for 2's compliment and signed value
|
||||||
|
float shunt_voltage_v = this->twos_complement_(raw_shunt_voltage, 16);
|
||||||
|
shunt_voltage_v *= 0.0000025f;
|
||||||
this->shunt_voltage_sensor_->publish_state(shunt_voltage_v);
|
this->shunt_voltage_sensor_->publish_state(shunt_voltage_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +135,9 @@ void INA226Component::update() {
|
|||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float current_ma = int16_t(raw_current) * (this->calibration_lsb_ / 1000.0f);
|
// Convert for 2's compliment and signed value
|
||||||
|
float current_ma = this->twos_complement_(raw_current, 16);
|
||||||
|
current_ma *= (this->calibration_lsb_ / 1000.0f);
|
||||||
this->current_sensor_->publish_state(current_ma / 1000.0f);
|
this->current_sensor_->publish_state(current_ma / 1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,5 +154,12 @@ void INA226Component::update() {
|
|||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t INA226Component::twos_complement_(int32_t val, uint8_t bits) {
|
||||||
|
if (val & ((uint32_t) 1 << (bits - 1))) {
|
||||||
|
val -= (uint32_t) 1 << bits;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ina226
|
} // namespace ina226
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
@ -7,6 +7,40 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ina226 {
|
namespace ina226 {
|
||||||
|
|
||||||
|
enum AdcTime : uint16_t {
|
||||||
|
ADC_TIME_140US = 0,
|
||||||
|
ADC_TIME_204US = 1,
|
||||||
|
ADC_TIME_332US = 2,
|
||||||
|
ADC_TIME_588US = 3,
|
||||||
|
ADC_TIME_1100US = 4,
|
||||||
|
ADC_TIME_2116US = 5,
|
||||||
|
ADC_TIME_4156US = 6,
|
||||||
|
ADC_TIME_8244US = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AdcAvgSamples : uint16_t {
|
||||||
|
ADC_AVG_SAMPLES_1 = 0,
|
||||||
|
ADC_AVG_SAMPLES_4 = 1,
|
||||||
|
ADC_AVG_SAMPLES_16 = 2,
|
||||||
|
ADC_AVG_SAMPLES_64 = 3,
|
||||||
|
ADC_AVG_SAMPLES_128 = 4,
|
||||||
|
ADC_AVG_SAMPLES_256 = 5,
|
||||||
|
ADC_AVG_SAMPLES_512 = 6,
|
||||||
|
ADC_AVG_SAMPLES_1024 = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
union ConfigurationRegister {
|
||||||
|
uint16_t raw;
|
||||||
|
struct {
|
||||||
|
uint16_t mode : 3;
|
||||||
|
AdcTime shunt_voltage_conversion_time : 3;
|
||||||
|
AdcTime bus_voltage_conversion_time : 3;
|
||||||
|
AdcAvgSamples avg_samples : 3;
|
||||||
|
uint16_t reserved : 3;
|
||||||
|
uint16_t reset : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
};
|
||||||
|
|
||||||
class INA226Component : public PollingComponent, public i2c::I2CDevice {
|
class INA226Component : public PollingComponent, public i2c::I2CDevice {
|
||||||
public:
|
public:
|
||||||
void setup() override;
|
void setup() override;
|
||||||
@ -16,6 +50,9 @@ class INA226Component : public PollingComponent, public i2c::I2CDevice {
|
|||||||
|
|
||||||
void set_shunt_resistance_ohm(float shunt_resistance_ohm) { shunt_resistance_ohm_ = shunt_resistance_ohm; }
|
void set_shunt_resistance_ohm(float shunt_resistance_ohm) { shunt_resistance_ohm_ = shunt_resistance_ohm; }
|
||||||
void set_max_current_a(float max_current_a) { max_current_a_ = max_current_a; }
|
void set_max_current_a(float max_current_a) { max_current_a_ = max_current_a; }
|
||||||
|
void set_adc_time(AdcTime time) { adc_time_ = time; }
|
||||||
|
void set_adc_avg_samples(AdcAvgSamples samples) { adc_avg_samples_ = samples; }
|
||||||
|
|
||||||
void set_bus_voltage_sensor(sensor::Sensor *bus_voltage_sensor) { bus_voltage_sensor_ = bus_voltage_sensor; }
|
void set_bus_voltage_sensor(sensor::Sensor *bus_voltage_sensor) { bus_voltage_sensor_ = bus_voltage_sensor; }
|
||||||
void set_shunt_voltage_sensor(sensor::Sensor *shunt_voltage_sensor) { shunt_voltage_sensor_ = shunt_voltage_sensor; }
|
void set_shunt_voltage_sensor(sensor::Sensor *shunt_voltage_sensor) { shunt_voltage_sensor_ = shunt_voltage_sensor; }
|
||||||
void set_current_sensor(sensor::Sensor *current_sensor) { current_sensor_ = current_sensor; }
|
void set_current_sensor(sensor::Sensor *current_sensor) { current_sensor_ = current_sensor; }
|
||||||
@ -24,11 +61,15 @@ class INA226Component : public PollingComponent, public i2c::I2CDevice {
|
|||||||
protected:
|
protected:
|
||||||
float shunt_resistance_ohm_;
|
float shunt_resistance_ohm_;
|
||||||
float max_current_a_;
|
float max_current_a_;
|
||||||
|
AdcTime adc_time_{AdcTime::ADC_TIME_1100US};
|
||||||
|
AdcAvgSamples adc_avg_samples_{AdcAvgSamples::ADC_AVG_SAMPLES_4};
|
||||||
uint32_t calibration_lsb_;
|
uint32_t calibration_lsb_;
|
||||||
sensor::Sensor *bus_voltage_sensor_{nullptr};
|
sensor::Sensor *bus_voltage_sensor_{nullptr};
|
||||||
sensor::Sensor *shunt_voltage_sensor_{nullptr};
|
sensor::Sensor *shunt_voltage_sensor_{nullptr};
|
||||||
sensor::Sensor *current_sensor_{nullptr};
|
sensor::Sensor *current_sensor_{nullptr};
|
||||||
sensor::Sensor *power_sensor_{nullptr};
|
sensor::Sensor *power_sensor_{nullptr};
|
||||||
|
|
||||||
|
int32_t twos_complement_(int32_t val, uint8_t bits);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ina226
|
} // namespace ina226
|
||||||
|
@ -20,11 +20,44 @@ from esphome.const import (
|
|||||||
|
|
||||||
DEPENDENCIES = ["i2c"]
|
DEPENDENCIES = ["i2c"]
|
||||||
|
|
||||||
|
CONF_ADC_AVERAGING = "adc_averaging"
|
||||||
|
CONF_ADC_TIME = "adc_time"
|
||||||
|
|
||||||
ina226_ns = cg.esphome_ns.namespace("ina226")
|
ina226_ns = cg.esphome_ns.namespace("ina226")
|
||||||
INA226Component = ina226_ns.class_(
|
INA226Component = ina226_ns.class_(
|
||||||
"INA226Component", cg.PollingComponent, i2c.I2CDevice
|
"INA226Component", cg.PollingComponent, i2c.I2CDevice
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AdcTime = ina226_ns.enum("AdcTime")
|
||||||
|
ADC_TIMES = {
|
||||||
|
140: AdcTime.ADC_TIME_140US,
|
||||||
|
204: AdcTime.ADC_TIME_204US,
|
||||||
|
332: AdcTime.ADC_TIME_332US,
|
||||||
|
588: AdcTime.ADC_TIME_588US,
|
||||||
|
1100: AdcTime.ADC_TIME_1100US,
|
||||||
|
2116: AdcTime.ADC_TIME_2116US,
|
||||||
|
4156: AdcTime.ADC_TIME_4156US,
|
||||||
|
8244: AdcTime.ADC_TIME_8244US,
|
||||||
|
}
|
||||||
|
|
||||||
|
AdcAvgSamples = ina226_ns.enum("AdcAvgSamples")
|
||||||
|
ADC_AVG_SAMPLES = {
|
||||||
|
1: AdcAvgSamples.ADC_AVG_SAMPLES_1,
|
||||||
|
4: AdcAvgSamples.ADC_AVG_SAMPLES_4,
|
||||||
|
16: AdcAvgSamples.ADC_AVG_SAMPLES_16,
|
||||||
|
64: AdcAvgSamples.ADC_AVG_SAMPLES_64,
|
||||||
|
128: AdcAvgSamples.ADC_AVG_SAMPLES_128,
|
||||||
|
256: AdcAvgSamples.ADC_AVG_SAMPLES_256,
|
||||||
|
512: AdcAvgSamples.ADC_AVG_SAMPLES_512,
|
||||||
|
1024: AdcAvgSamples.ADC_AVG_SAMPLES_1024,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_adc_time(value):
|
||||||
|
value = cv.positive_time_period_microseconds(value).total_microseconds
|
||||||
|
return cv.enum(ADC_TIMES, int=True)(value)
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
@ -59,6 +92,10 @@ CONFIG_SCHEMA = (
|
|||||||
cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All(
|
cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All(
|
||||||
cv.current, cv.Range(min=0.0)
|
cv.current, cv.Range(min=0.0)
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_ADC_TIME, default="1100 us"): validate_adc_time,
|
||||||
|
cv.Optional(CONF_ADC_AVERAGING, default=4): cv.enum(
|
||||||
|
ADC_AVG_SAMPLES, int=True
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s"))
|
.extend(cv.polling_component_schema("60s"))
|
||||||
@ -72,8 +109,9 @@ async def to_code(config):
|
|||||||
await i2c.register_i2c_device(var, config)
|
await i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
cg.add(var.set_shunt_resistance_ohm(config[CONF_SHUNT_RESISTANCE]))
|
cg.add(var.set_shunt_resistance_ohm(config[CONF_SHUNT_RESISTANCE]))
|
||||||
|
|
||||||
cg.add(var.set_max_current_a(config[CONF_MAX_CURRENT]))
|
cg.add(var.set_max_current_a(config[CONF_MAX_CURRENT]))
|
||||||
|
cg.add(var.set_adc_time(config[CONF_ADC_TIME]))
|
||||||
|
cg.add(var.set_adc_avg_samples(config[CONF_ADC_AVERAGING]))
|
||||||
|
|
||||||
if CONF_BUS_VOLTAGE in config:
|
if CONF_BUS_VOLTAGE in config:
|
||||||
sens = await sensor.new_sensor(config[CONF_BUS_VOLTAGE])
|
sens = await sensor.new_sensor(config[CONF_BUS_VOLTAGE])
|
||||||
|
@ -103,6 +103,7 @@ KEY_AUTHOR = "author"
|
|||||||
KEY_WEBSITE = "website"
|
KEY_WEBSITE = "website"
|
||||||
KEY_VERSION = "version"
|
KEY_VERSION = "version"
|
||||||
KEY_MICRO = "micro"
|
KEY_MICRO = "micro"
|
||||||
|
KEY_MINIMUM_ESPHOME_VERSION = "minimum_esphome_version"
|
||||||
|
|
||||||
MANIFEST_SCHEMA_V1 = cv.Schema(
|
MANIFEST_SCHEMA_V1 = cv.Schema(
|
||||||
{
|
{
|
||||||
@ -116,6 +117,9 @@ MANIFEST_SCHEMA_V1 = cv.Schema(
|
|||||||
{
|
{
|
||||||
cv.Required(CONF_PROBABILITY_CUTOFF): cv.float_,
|
cv.Required(CONF_PROBABILITY_CUTOFF): cv.float_,
|
||||||
cv.Required(CONF_SLIDING_WINDOW_AVERAGE_SIZE): cv.positive_int,
|
cv.Required(CONF_SLIDING_WINDOW_AVERAGE_SIZE): cv.positive_int,
|
||||||
|
cv.Optional(KEY_MINIMUM_ESPHOME_VERSION): cv.All(
|
||||||
|
cv.version_number, cv.validate_esphome_version
|
||||||
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ static const uint8_t NBITS_ADDRESS = 16;
|
|||||||
static const uint8_t NBITS_CHANNEL = 5;
|
static const uint8_t NBITS_CHANNEL = 5;
|
||||||
static const uint8_t NBITS_COMMAND = 7;
|
static const uint8_t NBITS_COMMAND = 7;
|
||||||
static const uint8_t NDATABITS = NBITS_ADDRESS + NBITS_CHANNEL + NBITS_COMMAND;
|
static const uint8_t NDATABITS = NBITS_ADDRESS + NBITS_CHANNEL + NBITS_COMMAND;
|
||||||
static const uint8_t MIN_RX_SRC = (NDATABITS * 2 + NBITS_SYNC / 2);
|
static const uint8_t MIN_RX_SRC = (NDATABITS + NBITS_SYNC / 2);
|
||||||
|
|
||||||
static const uint8_t CMD_ON = 0x41;
|
static const uint8_t CMD_ON = 0x41;
|
||||||
static const uint8_t CMD_OFF = 0x02;
|
static const uint8_t CMD_OFF = 0x02;
|
||||||
@ -135,7 +135,7 @@ optional<DraytonData> DraytonProtocol::decode(RemoteReceiveData src) {
|
|||||||
.command = 0,
|
.command = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
while (src.size() - src.get_index() > MIN_RX_SRC) {
|
while (src.size() - src.get_index() >= MIN_RX_SRC) {
|
||||||
ESP_LOGVV(TAG,
|
ESP_LOGVV(TAG,
|
||||||
"Decode Drayton: %" PRId32 ", %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
"Decode Drayton: %" PRId32 ", %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
||||||
" %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
" %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
|
||||||
@ -150,7 +150,7 @@ optional<DraytonData> DraytonProtocol::decode(RemoteReceiveData src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for sync pulse, after. If sucessful index points to space of sync symbol
|
// Look for sync pulse, after. If sucessful index points to space of sync symbol
|
||||||
while (src.size() - src.get_index() >= NDATABITS) {
|
while (src.size() - src.get_index() >= MIN_RX_SRC) {
|
||||||
ESP_LOGVV(TAG, "Decode Drayton: sync search %d, %" PRId32 " %" PRId32, src.size() - src.get_index(), src.peek(),
|
ESP_LOGVV(TAG, "Decode Drayton: sync search %d, %" PRId32 " %" PRId32, src.size() - src.get_index(), src.peek(),
|
||||||
src.peek(1));
|
src.peek(1));
|
||||||
if (src.peek_mark(2 * BIT_TIME_US) &&
|
if (src.peek_mark(2 * BIT_TIME_US) &&
|
||||||
|
@ -36,14 +36,14 @@ bool XL9535Component::digital_read(uint8_t pin) {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = (port & (pin - 10)) != 0;
|
state = (port & (1 << (pin - 10))) != 0;
|
||||||
} else {
|
} else {
|
||||||
if (this->read_register(XL9535_INPUT_PORT_0_REGISTER, &port, 1) != i2c::ERROR_OK) {
|
if (this->read_register(XL9535_INPUT_PORT_0_REGISTER, &port, 1) != i2c::ERROR_OK) {
|
||||||
this->status_set_warning();
|
this->status_set_warning();
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = (port & pin) != 0;
|
state = (port & (1 << pin)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
|
@ -57,6 +57,7 @@ from esphome.const import (
|
|||||||
TYPE_GIT,
|
TYPE_GIT,
|
||||||
TYPE_LOCAL,
|
TYPE_LOCAL,
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS,
|
VALID_SUBSTITUTIONS_CHARACTERS,
|
||||||
|
__version__ as ESPHOME_VERSION,
|
||||||
)
|
)
|
||||||
from esphome.core import (
|
from esphome.core import (
|
||||||
CORE,
|
CORE,
|
||||||
@ -1895,6 +1896,16 @@ def version_number(value):
|
|||||||
raise Invalid("Not a valid version number") from e
|
raise Invalid("Not a valid version number") from e
|
||||||
|
|
||||||
|
|
||||||
|
def validate_esphome_version(value: str):
|
||||||
|
min_version = Version.parse(value)
|
||||||
|
current_version = Version.parse(ESPHOME_VERSION)
|
||||||
|
if current_version < min_version:
|
||||||
|
raise Invalid(
|
||||||
|
f"Your ESPHome version is too old. Please update to at least {min_version}"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def platformio_version_constraint(value):
|
def platformio_version_constraint(value):
|
||||||
# for documentation on valid version constraints:
|
# for documentation on valid version constraints:
|
||||||
# https://docs.platformio.org/en/latest/core/userguide/platforms/cmd_install.html#cmd-platform-install
|
# https://docs.platformio.org/en/latest/core/userguide/platforms/cmd_install.html#cmd-platform-install
|
||||||
|
@ -102,16 +102,6 @@ def valid_project_name(value: str):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def validate_version(value: str):
|
|
||||||
min_version = cv.Version.parse(value)
|
|
||||||
current_version = cv.Version.parse(ESPHOME_VERSION)
|
|
||||||
if current_version < min_version:
|
|
||||||
raise cv.Invalid(
|
|
||||||
f"Your ESPHome version is too old. Please update to at least {min_version}"
|
|
||||||
)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
|
if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
|
||||||
_compile_process_limit_default = min(
|
_compile_process_limit_default = min(
|
||||||
int(os.environ["ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT"]),
|
int(os.environ["ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT"]),
|
||||||
@ -164,7 +154,7 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
|
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
|
||||||
cv.version_number, validate_version
|
cv.version_number, cv.validate_esphome_version
|
||||||
),
|
),
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default
|
CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default
|
||||||
|
@ -51,10 +51,12 @@ BASE_CONFIG_FRIENDLY = """esphome:
|
|||||||
friendly_name: {friendly_name}
|
friendly_name: {friendly_name}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LOGGER_API_CONFIG = """
|
LOGGER_CONFIG = """
|
||||||
# Enable logging
|
# Enable logging
|
||||||
logger:
|
logger:
|
||||||
|
"""
|
||||||
|
|
||||||
|
API_CONFIG = """
|
||||||
# Enable Home Assistant API
|
# Enable Home Assistant API
|
||||||
api:
|
api:
|
||||||
"""
|
"""
|
||||||
@ -136,7 +138,12 @@ def wizard_file(**kwargs):
|
|||||||
|
|
||||||
config += HARDWARE_BASE_CONFIGS[kwargs["platform"]].format(**kwargs)
|
config += HARDWARE_BASE_CONFIGS[kwargs["platform"]].format(**kwargs)
|
||||||
|
|
||||||
config += LOGGER_API_CONFIG
|
config += LOGGER_CONFIG
|
||||||
|
|
||||||
|
if kwargs["board"] == "rpipico":
|
||||||
|
return config
|
||||||
|
|
||||||
|
config += API_CONFIG
|
||||||
|
|
||||||
# Configure API
|
# Configure API
|
||||||
if "password" in kwargs:
|
if "password" in kwargs:
|
||||||
|
@ -94,7 +94,7 @@ lib_deps =
|
|||||||
ESP8266HTTPClient ; http_request (Arduino built-in)
|
ESP8266HTTPClient ; http_request (Arduino built-in)
|
||||||
ESP8266mDNS ; mdns (Arduino built-in)
|
ESP8266mDNS ; mdns (Arduino built-in)
|
||||||
DNSServer ; captive_portal (Arduino built-in)
|
DNSServer ; captive_portal (Arduino built-in)
|
||||||
crankyoldgit/IRremoteESP8266@2.7.12 ; heatpumpir
|
crankyoldgit/IRremoteESP8266@~2.8.4 ; heatpumpir
|
||||||
build_flags =
|
build_flags =
|
||||||
${common:arduino.build_flags}
|
${common:arduino.build_flags}
|
||||||
-Wno-nonnull-compare
|
-Wno-nonnull-compare
|
||||||
@ -123,7 +123,7 @@ lib_deps =
|
|||||||
ESPmDNS ; mdns (Arduino built-in)
|
ESPmDNS ; mdns (Arduino built-in)
|
||||||
DNSServer ; captive_portal (Arduino built-in)
|
DNSServer ; captive_portal (Arduino built-in)
|
||||||
esphome/ESP32-audioI2S@2.0.7 ; i2s_audio
|
esphome/ESP32-audioI2S@2.0.7 ; i2s_audio
|
||||||
crankyoldgit/IRremoteESP8266@2.7.12 ; heatpumpir
|
crankyoldgit/IRremoteESP8266@~2.8.4 ; heatpumpir
|
||||||
droscy/esp_wireguard@0.3.2 ; wireguard
|
droscy/esp_wireguard@0.3.2 ; wireguard
|
||||||
build_flags =
|
build_flags =
|
||||||
${common:arduino.build_flags}
|
${common:arduino.build_flags}
|
||||||
|
@ -8,6 +8,6 @@ pre-commit
|
|||||||
pytest==7.4.4
|
pytest==7.4.4
|
||||||
pytest-cov==4.1.0
|
pytest-cov==4.1.0
|
||||||
pytest-mock==3.12.0
|
pytest-mock==3.12.0
|
||||||
pytest-asyncio==0.23.3
|
pytest-asyncio==0.23.5
|
||||||
asyncmock==0.4.2
|
asyncmock==0.4.2
|
||||||
hypothesis==6.92.1
|
hypothesis==6.92.1
|
||||||
|
Loading…
Reference in New Issue
Block a user