mirror of
https://github.com/esphome/esphome.git
synced 2025-10-07 20:33:47 +01:00
Merge remote-tracking branch 'upstream/dev' into integration
This commit is contained in:
@@ -1 +1 @@
|
|||||||
bc4001761441a1f0d32971287398739b2b1c45435440425f5ed5aacf1c1f8c2b
|
499db61c1aa55b98b6629df603a56a1ba7aff5a9a7c781a5c1552a9dcd186c08
|
||||||
|
@@ -256,6 +256,7 @@ esphome/components/libretiny_pwm/* @kuba2k2
|
|||||||
esphome/components/light/* @esphome/core
|
esphome/components/light/* @esphome/core
|
||||||
esphome/components/lightwaverf/* @max246
|
esphome/components/lightwaverf/* @max246
|
||||||
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
|
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
|
||||||
|
esphome/components/lm75b/* @beormund
|
||||||
esphome/components/ln882x/* @lamauny
|
esphome/components/ln882x/* @lamauny
|
||||||
esphome/components/lock/* @esphome/core
|
esphome/components/lock/* @esphome/core
|
||||||
esphome/components/logger/* @esphome/core
|
esphome/components/logger/* @esphome/core
|
||||||
|
@@ -26,12 +26,12 @@ uint32_t Animation::get_animation_frame_count() const { return this->animation_f
|
|||||||
int Animation::get_current_frame() const { return this->current_frame_; }
|
int Animation::get_current_frame() const { return this->current_frame_; }
|
||||||
void Animation::next_frame() {
|
void Animation::next_frame() {
|
||||||
this->current_frame_++;
|
this->current_frame_++;
|
||||||
if (loop_count_ && this->current_frame_ == loop_end_frame_ &&
|
if (loop_count_ && static_cast<uint32_t>(this->current_frame_) == loop_end_frame_ &&
|
||||||
(this->loop_current_iteration_ < loop_count_ || loop_count_ < 0)) {
|
(this->loop_current_iteration_ < loop_count_ || loop_count_ < 0)) {
|
||||||
this->current_frame_ = loop_start_frame_;
|
this->current_frame_ = loop_start_frame_;
|
||||||
this->loop_current_iteration_++;
|
this->loop_current_iteration_++;
|
||||||
}
|
}
|
||||||
if (this->current_frame_ >= animation_frame_count_) {
|
if (static_cast<uint32_t>(this->current_frame_) >= animation_frame_count_) {
|
||||||
this->loop_current_iteration_ = 1;
|
this->loop_current_iteration_ = 1;
|
||||||
this->current_frame_ = 0;
|
this->current_frame_ = 0;
|
||||||
}
|
}
|
||||||
|
@@ -1389,6 +1389,11 @@ void APIConnection::complete_authentication_() {
|
|||||||
this->send_time_request();
|
this->send_time_request();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_ZWAVE_PROXY
|
||||||
|
if (zwave_proxy::global_zwave_proxy != nullptr) {
|
||||||
|
zwave_proxy::global_zwave_proxy->api_connection_authenticated(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool APIConnection::send_hello_response(const HelloRequest &msg) {
|
bool APIConnection::send_hello_response(const HelloRequest &msg) {
|
||||||
|
@@ -57,7 +57,7 @@ const char *audio_file_type_to_string(AudioFileType file_type) {
|
|||||||
void scale_audio_samples(const int16_t *audio_samples, int16_t *output_buffer, int16_t scale_factor,
|
void scale_audio_samples(const int16_t *audio_samples, int16_t *output_buffer, int16_t scale_factor,
|
||||||
size_t samples_to_scale) {
|
size_t samples_to_scale) {
|
||||||
// Note the assembly dsps_mulc function has audio glitches if the input and output buffers are the same.
|
// Note the assembly dsps_mulc function has audio glitches if the input and output buffers are the same.
|
||||||
for (int i = 0; i < samples_to_scale; i++) {
|
for (size_t i = 0; i < samples_to_scale; i++) {
|
||||||
int32_t acc = (int32_t) audio_samples[i] * (int32_t) scale_factor;
|
int32_t acc = (int32_t) audio_samples[i] * (int32_t) scale_factor;
|
||||||
output_buffer[i] = (int16_t) (acc >> 15);
|
output_buffer[i] = (int16_t) (acc >> 15);
|
||||||
}
|
}
|
||||||
|
@@ -97,10 +97,10 @@ void BL0906::handle_actions_() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ActionCallbackFuncPtr ptr_func = nullptr;
|
ActionCallbackFuncPtr ptr_func = nullptr;
|
||||||
for (int i = 0; i < this->action_queue_.size(); i++) {
|
for (size_t i = 0; i < this->action_queue_.size(); i++) {
|
||||||
ptr_func = this->action_queue_[i];
|
ptr_func = this->action_queue_[i];
|
||||||
if (ptr_func) {
|
if (ptr_func) {
|
||||||
ESP_LOGI(TAG, "HandleActionCallback[%d]", i);
|
ESP_LOGI(TAG, "HandleActionCallback[%zu]", i);
|
||||||
(this->*ptr_func)();
|
(this->*ptr_func)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -51,7 +51,7 @@ void BL0942::loop() {
|
|||||||
if (!avail) {
|
if (!avail) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (avail < sizeof(buffer)) {
|
if (static_cast<size_t>(avail) < sizeof(buffer)) {
|
||||||
if (!this->rx_start_) {
|
if (!this->rx_start_) {
|
||||||
this->rx_start_ = millis();
|
this->rx_start_ = millis();
|
||||||
} else if (millis() > this->rx_start_ + PKT_TIMEOUT_MS) {
|
} else if (millis() > this->rx_start_ + PKT_TIMEOUT_MS) {
|
||||||
@@ -148,7 +148,7 @@ void BL0942::setup() {
|
|||||||
|
|
||||||
this->write_reg_(BL0942_REG_USR_WRPROT, 0);
|
this->write_reg_(BL0942_REG_USR_WRPROT, 0);
|
||||||
|
|
||||||
if (this->read_reg_(BL0942_REG_MODE) != mode)
|
if (static_cast<uint32_t>(this->read_reg_(BL0942_REG_MODE)) != mode)
|
||||||
this->status_set_warning(LOG_STR("BL0942 setup failed!"));
|
this->status_set_warning(LOG_STR("BL0942 setup failed!"));
|
||||||
|
|
||||||
this->flush();
|
this->flush();
|
||||||
|
@@ -13,7 +13,7 @@ static const uint8_t C_M1106_CMD_SET_CO2_CALIB_RESPONSE[4] = {0x16, 0x01, 0x03,
|
|||||||
|
|
||||||
uint8_t cm1106_checksum(const uint8_t *response, size_t len) {
|
uint8_t cm1106_checksum(const uint8_t *response, size_t len) {
|
||||||
uint8_t crc = 0;
|
uint8_t crc = 0;
|
||||||
for (int i = 0; i < len - 1; i++) {
|
for (size_t i = 0; i < len - 1; i++) {
|
||||||
crc -= response[i];
|
crc -= response[i];
|
||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
|
@@ -26,7 +26,7 @@ void DaikinArcClimate::transmit_query_() {
|
|||||||
uint8_t remote_header[8] = {0x11, 0xDA, 0x27, 0x00, 0x84, 0x87, 0x20, 0x00};
|
uint8_t remote_header[8] = {0x11, 0xDA, 0x27, 0x00, 0x84, 0x87, 0x20, 0x00};
|
||||||
|
|
||||||
// Calculate checksum
|
// Calculate checksum
|
||||||
for (int i = 0; i < sizeof(remote_header) - 1; i++) {
|
for (size_t i = 0; i < sizeof(remote_header) - 1; i++) {
|
||||||
remote_header[sizeof(remote_header) - 1] += remote_header[i];
|
remote_header[sizeof(remote_header) - 1] += remote_header[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ void DaikinArcClimate::transmit_state() {
|
|||||||
remote_state[9] = fan_speed & 0xff;
|
remote_state[9] = fan_speed & 0xff;
|
||||||
|
|
||||||
// Calculate checksum
|
// Calculate checksum
|
||||||
for (int i = 0; i < sizeof(remote_header) - 1; i++) {
|
for (size_t i = 0; i < sizeof(remote_header) - 1; i++) {
|
||||||
remote_header[sizeof(remote_header) - 1] += remote_header[i];
|
remote_header[sizeof(remote_header) - 1] += remote_header[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
|
|||||||
bool valid_daikin_frame = false;
|
bool valid_daikin_frame = false;
|
||||||
if (data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
|
if (data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
|
||||||
valid_daikin_frame = true;
|
valid_daikin_frame = true;
|
||||||
int bytes_count = data.size() / 2 / 8;
|
size_t bytes_count = data.size() / 2 / 8;
|
||||||
std::unique_ptr<char[]> buf(new char[bytes_count * 3 + 1]);
|
std::unique_ptr<char[]> buf(new char[bytes_count * 3 + 1]);
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
for (size_t i = 0; i < bytes_count; i++) {
|
for (size_t i = 0; i < bytes_count; i++) {
|
||||||
@@ -370,7 +370,7 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
|
|||||||
if (!valid_daikin_frame) {
|
if (!valid_daikin_frame) {
|
||||||
char sbuf[16 * 10 + 1];
|
char sbuf[16 * 10 + 1];
|
||||||
sbuf[0] = '\0';
|
sbuf[0] = '\0';
|
||||||
for (size_t j = 0; j < data.size(); j++) {
|
for (size_t j = 0; j < static_cast<size_t>(data.size()); j++) {
|
||||||
if ((j - 2) % 16 == 0) {
|
if ((j - 2) % 16 == 0) {
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
ESP_LOGD(TAG, "DATA %04x: %s", (j - 16 > 0xffff ? 0 : j - 16), sbuf);
|
ESP_LOGD(TAG, "DATA %04x: %s", (j - 16 > 0xffff ? 0 : j - 16), sbuf);
|
||||||
@@ -380,19 +380,26 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
|
|||||||
char type_ch = ' ';
|
char type_ch = ' ';
|
||||||
// debug_tolerance = 25%
|
// debug_tolerance = 25%
|
||||||
|
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK)) <= data[j] &&
|
||||||
|
data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK)))
|
||||||
type_ch = 'P';
|
type_ch = 'P';
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE)) <= -data[j] &&
|
||||||
|
-data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE)))
|
||||||
type_ch = 'a';
|
type_ch = 'a';
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK)) <= data[j] &&
|
||||||
|
data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK)))
|
||||||
type_ch = 'H';
|
type_ch = 'H';
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE)) <= -data[j] &&
|
||||||
|
-data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE)))
|
||||||
type_ch = 'h';
|
type_ch = 'h';
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK)) <= data[j] &&
|
||||||
|
data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK)))
|
||||||
type_ch = 'B';
|
type_ch = 'B';
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE)) <= -data[j] &&
|
||||||
|
-data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE)))
|
||||||
type_ch = '1';
|
type_ch = '1';
|
||||||
if (DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE))
|
if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE)) <= -data[j] &&
|
||||||
|
-data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE)))
|
||||||
type_ch = '0';
|
type_ch = '0';
|
||||||
|
|
||||||
if (abs(data[j]) > 100000) {
|
if (abs(data[j]) > 100000) {
|
||||||
@@ -400,7 +407,7 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
|
|||||||
} else {
|
} else {
|
||||||
sprintf(sbuf, "%s%-5d[%c] ", sbuf, (int) (round(data[j] / 10.) * 10), type_ch);
|
sprintf(sbuf, "%s%-5d[%c] ", sbuf, (int) (round(data[j] / 10.) * 10), type_ch);
|
||||||
}
|
}
|
||||||
if (j == data.size() - 1) {
|
if (j + 1 == static_cast<size_t>(data.size())) {
|
||||||
ESP_LOGD(TAG, "DATA %04x: %s", (j - 8 > 0xffff ? 0 : j - 8), sbuf);
|
ESP_LOGD(TAG, "DATA %04x: %s", (j - 8 > 0xffff ? 0 : j - 8), sbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,12 +97,12 @@ bool ES7210::set_mic_gain(float mic_gain) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ES7210::configure_sample_rate_() {
|
bool ES7210::configure_sample_rate_() {
|
||||||
int mclk_fre = this->sample_rate_ * MCLK_DIV_FRE;
|
uint32_t mclk_fre = this->sample_rate_ * MCLK_DIV_FRE;
|
||||||
int coeff = -1;
|
int coeff = -1;
|
||||||
|
|
||||||
for (int i = 0; i < (sizeof(ES7210_COEFFICIENTS) / sizeof(ES7210_COEFFICIENTS[0])); ++i) {
|
for (size_t i = 0; i < (sizeof(ES7210_COEFFICIENTS) / sizeof(ES7210_COEFFICIENTS[0])); ++i) {
|
||||||
if (ES7210_COEFFICIENTS[i].lrclk == this->sample_rate_ && ES7210_COEFFICIENTS[i].mclk == mclk_fre)
|
if (ES7210_COEFFICIENTS[i].lrclk == this->sample_rate_ && ES7210_COEFFICIENTS[i].mclk == mclk_fre)
|
||||||
coeff = i;
|
coeff = static_cast<int>(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coeff >= 0) {
|
if (coeff >= 0) {
|
||||||
|
@@ -156,7 +156,7 @@ void BLEAdvertising::loop() {
|
|||||||
if (now - this->last_advertisement_time_ > this->advertising_cycle_time_) {
|
if (now - this->last_advertisement_time_ > this->advertising_cycle_time_) {
|
||||||
this->stop();
|
this->stop();
|
||||||
this->current_adv_index_ += 1;
|
this->current_adv_index_ += 1;
|
||||||
if (this->current_adv_index_ >= this->raw_advertisements_callbacks_.size()) {
|
if (static_cast<size_t>(this->current_adv_index_) >= this->raw_advertisements_callbacks_.size()) {
|
||||||
this->current_adv_index_ = -1;
|
this->current_adv_index_ = -1;
|
||||||
}
|
}
|
||||||
this->start();
|
this->start();
|
||||||
|
@@ -68,7 +68,7 @@ static bool get_bitrate(canbus::CanSpeed bitrate, twai_timing_config_t *t_config
|
|||||||
|
|
||||||
bool ESP32Can::setup_internal() {
|
bool ESP32Can::setup_internal() {
|
||||||
static int next_twai_ctrl_num = 0;
|
static int next_twai_ctrl_num = 0;
|
||||||
if (next_twai_ctrl_num >= SOC_TWAI_CONTROLLER_NUM) {
|
if (static_cast<unsigned>(next_twai_ctrl_num) >= SOC_TWAI_CONTROLLER_NUM) {
|
||||||
ESP_LOGW(TAG, "Maximum number of esp32_can components created already");
|
ESP_LOGW(TAG, "Maximum number of esp32_can components created already");
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return false;
|
return false;
|
||||||
|
@@ -35,7 +35,7 @@ static size_t IRAM_ATTR HOT encoder_callback(const void *data, size_t size, size
|
|||||||
if (symbols_free < RMT_SYMBOLS_PER_BYTE) {
|
if (symbols_free < RMT_SYMBOLS_PER_BYTE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (int32_t i = 0; i < RMT_SYMBOLS_PER_BYTE; i++) {
|
for (size_t i = 0; i < RMT_SYMBOLS_PER_BYTE; i++) {
|
||||||
if (bytes[index] & (1 << (7 - i))) {
|
if (bytes[index] & (1 << (7 - i))) {
|
||||||
symbols[i] = params->bit1;
|
symbols[i] = params->bit1;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -80,7 +80,7 @@ void FingerprintGrowComponent::setup() {
|
|||||||
delay(20); // This delay guarantees the sensor will in fact be powered power.
|
delay(20); // This delay guarantees the sensor will in fact be powered power.
|
||||||
|
|
||||||
if (this->check_password_()) {
|
if (this->check_password_()) {
|
||||||
if (this->new_password_ != -1) {
|
if (this->new_password_ != std::numeric_limits<uint32_t>::max()) {
|
||||||
if (this->set_password_())
|
if (this->set_password_())
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
#include "esphome/components/uart/uart.h"
|
#include "esphome/components/uart/uart.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
@@ -177,7 +178,7 @@ class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevic
|
|||||||
uint8_t address_[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t address_[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
uint16_t capacity_ = 64;
|
uint16_t capacity_ = 64;
|
||||||
uint32_t password_ = 0x0;
|
uint32_t password_ = 0x0;
|
||||||
uint32_t new_password_ = -1;
|
uint32_t new_password_ = std::numeric_limits<uint32_t>::max();
|
||||||
GPIOPin *sensing_pin_{nullptr};
|
GPIOPin *sensing_pin_{nullptr};
|
||||||
GPIOPin *sensor_power_pin_{nullptr};
|
GPIOPin *sensor_power_pin_{nullptr};
|
||||||
uint8_t enrollment_image_ = 0;
|
uint8_t enrollment_image_ = 0;
|
||||||
|
@@ -116,7 +116,7 @@ void GraphicalDisplayMenu::draw_menu_internal_(display::Display *display, const
|
|||||||
int number_items_fit_to_screen = 0;
|
int number_items_fit_to_screen = 0;
|
||||||
const int max_item_index = this->displayed_item_->items_size() - 1;
|
const int max_item_index = this->displayed_item_->items_size() - 1;
|
||||||
|
|
||||||
for (size_t i = 0; i <= max_item_index; i++) {
|
for (size_t i = 0; max_item_index >= 0 && i <= static_cast<size_t>(max_item_index); i++) {
|
||||||
const auto *item = this->displayed_item_->get_item(i);
|
const auto *item = this->displayed_item_->get_item(i);
|
||||||
const bool selected = i == this->cursor_index_;
|
const bool selected = i == this->cursor_index_;
|
||||||
const display::Rect item_dimensions = this->measure_item(display, item, bounds, selected);
|
const display::Rect item_dimensions = this->measure_item(display, item, bounds, selected);
|
||||||
@@ -174,7 +174,8 @@ void GraphicalDisplayMenu::draw_menu_internal_(display::Display *display, const
|
|||||||
|
|
||||||
display->filled_rectangle(bounds->x, bounds->y, max_width, total_height, this->background_color_);
|
display->filled_rectangle(bounds->x, bounds->y, max_width, total_height, this->background_color_);
|
||||||
auto y_offset = bounds->y;
|
auto y_offset = bounds->y;
|
||||||
for (size_t i = first_item_index; i <= last_item_index; i++) {
|
for (size_t i = static_cast<size_t>(first_item_index);
|
||||||
|
last_item_index >= 0 && i <= static_cast<size_t>(last_item_index); i++) {
|
||||||
const auto *item = this->displayed_item_->get_item(i);
|
const auto *item = this->displayed_item_->get_item(i);
|
||||||
const bool selected = i == this->cursor_index_;
|
const bool selected = i == this->cursor_index_;
|
||||||
display::Rect dimensions = menu_dimensions[i];
|
display::Rect dimensions = menu_dimensions[i];
|
||||||
|
@@ -377,7 +377,7 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|||||||
this_speaker->current_stream_info_.get_bits_per_sample() <= 16) {
|
this_speaker->current_stream_info_.get_bits_per_sample() <= 16) {
|
||||||
size_t len = bytes_read / sizeof(int16_t);
|
size_t len = bytes_read / sizeof(int16_t);
|
||||||
int16_t *tmp_buf = (int16_t *) new_data;
|
int16_t *tmp_buf = (int16_t *) new_data;
|
||||||
for (int i = 0; i < len; i += 2) {
|
for (size_t i = 0; i < len; i += 2) {
|
||||||
int16_t tmp = tmp_buf[i];
|
int16_t tmp = tmp_buf[i];
|
||||||
tmp_buf[i] = tmp_buf[i + 1];
|
tmp_buf[i] = tmp_buf[i + 1];
|
||||||
tmp_buf[i + 1] = tmp;
|
tmp_buf[i + 1] = tmp;
|
||||||
|
@@ -325,7 +325,7 @@ void ILI9XXXDisplay::draw_pixels_at(int x_start, int y_start, int w, int h, cons
|
|||||||
// we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother
|
// we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother
|
||||||
this->write_array(ptr, w * h * 2);
|
this->write_array(ptr, w * h * 2);
|
||||||
} else {
|
} else {
|
||||||
for (size_t y = 0; y != h; y++) {
|
for (size_t y = 0; y != static_cast<size_t>(h); y++) {
|
||||||
this->write_array(ptr + (y + y_offset) * stride + x_offset, w * 2);
|
this->write_array(ptr + (y + y_offset) * stride + x_offset, w * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,7 +349,7 @@ void ILI9XXXDisplay::draw_pixels_at(int x_start, int y_start, int w, int h, cons
|
|||||||
App.feed_wdt();
|
App.feed_wdt();
|
||||||
}
|
}
|
||||||
// end of line? Skip to the next.
|
// end of line? Skip to the next.
|
||||||
if (++pixel == w) {
|
if (++pixel == static_cast<size_t>(w)) {
|
||||||
pixel = 0;
|
pixel = 0;
|
||||||
ptr += (x_pad + x_offset) * 2;
|
ptr += (x_pad + x_offset) * 2;
|
||||||
}
|
}
|
||||||
|
@@ -19,15 +19,19 @@ std::string build_json(const json_build_t &f) {
|
|||||||
|
|
||||||
bool parse_json(const std::string &data, const json_parse_t &f) {
|
bool parse_json(const std::string &data, const json_parse_t &f) {
|
||||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
JsonDocument doc = parse_json(data);
|
JsonDocument doc = parse_json(reinterpret_cast<const uint8_t *>(data.c_str()), data.size());
|
||||||
if (doc.overflowed() || doc.isNull())
|
if (doc.overflowed() || doc.isNull())
|
||||||
return false;
|
return false;
|
||||||
return f(doc.as<JsonObject>());
|
return f(doc.as<JsonObject>());
|
||||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument parse_json(const std::string &data) {
|
JsonDocument parse_json(const uint8_t *data, size_t len) {
|
||||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
|
if (data == nullptr || len == 0) {
|
||||||
|
ESP_LOGE(TAG, "No data to parse");
|
||||||
|
return JsonObject(); // return unbound object
|
||||||
|
}
|
||||||
#ifdef USE_PSRAM
|
#ifdef USE_PSRAM
|
||||||
auto doc_allocator = SpiRamAllocator();
|
auto doc_allocator = SpiRamAllocator();
|
||||||
JsonDocument json_document(&doc_allocator);
|
JsonDocument json_document(&doc_allocator);
|
||||||
@@ -38,7 +42,7 @@ JsonDocument parse_json(const std::string &data) {
|
|||||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||||
return JsonObject(); // return unbound object
|
return JsonObject(); // return unbound object
|
||||||
}
|
}
|
||||||
DeserializationError err = deserializeJson(json_document, data);
|
DeserializationError err = deserializeJson(json_document, data, len);
|
||||||
|
|
||||||
if (err == DeserializationError::Ok) {
|
if (err == DeserializationError::Ok) {
|
||||||
return json_document;
|
return json_document;
|
||||||
|
@@ -50,8 +50,13 @@ std::string build_json(const json_build_t &f);
|
|||||||
|
|
||||||
/// Parse a JSON string and run the provided json parse function if it's valid.
|
/// Parse a JSON string and run the provided json parse function if it's valid.
|
||||||
bool parse_json(const std::string &data, const json_parse_t &f);
|
bool parse_json(const std::string &data, const json_parse_t &f);
|
||||||
|
|
||||||
/// Parse a JSON string and return the root JsonDocument (or an unbound object on error)
|
/// Parse a JSON string and return the root JsonDocument (or an unbound object on error)
|
||||||
JsonDocument parse_json(const std::string &data);
|
JsonDocument parse_json(const uint8_t *data, size_t len);
|
||||||
|
/// Parse a JSON string and return the root JsonDocument (or an unbound object on error)
|
||||||
|
inline JsonDocument parse_json(const std::string &data) {
|
||||||
|
return parse_json(reinterpret_cast<const uint8_t *>(data.c_str()), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
/// Builder class for creating JSON documents without lambdas
|
/// Builder class for creating JSON documents without lambdas
|
||||||
class JsonBuilder {
|
class JsonBuilder {
|
||||||
|
@@ -22,7 +22,7 @@ void KamstrupKMPComponent::dump_config() {
|
|||||||
LOG_SENSOR(" ", "Flow", this->flow_sensor_);
|
LOG_SENSOR(" ", "Flow", this->flow_sensor_);
|
||||||
LOG_SENSOR(" ", "Volume", this->volume_sensor_);
|
LOG_SENSOR(" ", "Volume", this->volume_sensor_);
|
||||||
|
|
||||||
for (int i = 0; i < this->custom_sensors_.size(); i++) {
|
for (size_t i = 0; i < this->custom_sensors_.size(); i++) {
|
||||||
LOG_SENSOR(" ", "Custom Sensor", this->custom_sensors_[i]);
|
LOG_SENSOR(" ", "Custom Sensor", this->custom_sensors_[i]);
|
||||||
ESP_LOGCONFIG(TAG, " Command: 0x%04X", this->custom_commands_[i]);
|
ESP_LOGCONFIG(TAG, " Command: 0x%04X", this->custom_commands_[i]);
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ void KamstrupKMPComponent::set_sensor_value_(uint16_t command, float value, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Custom sensors
|
// Custom sensors
|
||||||
for (int i = 0; i < this->custom_commands_.size(); i++) {
|
for (size_t i = 0; i < this->custom_commands_.size(); i++) {
|
||||||
if (command == this->custom_commands_[i]) {
|
if (command == this->custom_commands_[i]) {
|
||||||
this->custom_sensors_[i]->publish_state(value);
|
this->custom_sensors_[i]->publish_state(value);
|
||||||
}
|
}
|
||||||
|
@@ -13,8 +13,8 @@ class KeyCollector : public Component {
|
|||||||
void loop() override;
|
void loop() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void set_provider(key_provider::KeyProvider *provider);
|
void set_provider(key_provider::KeyProvider *provider);
|
||||||
void set_min_length(int min_length) { this->min_length_ = min_length; };
|
void set_min_length(uint32_t min_length) { this->min_length_ = min_length; };
|
||||||
void set_max_length(int max_length) { this->max_length_ = max_length; };
|
void set_max_length(uint32_t max_length) { this->max_length_ = max_length; };
|
||||||
void set_start_keys(std::string start_keys) { this->start_keys_ = std::move(start_keys); };
|
void set_start_keys(std::string start_keys) { this->start_keys_ = std::move(start_keys); };
|
||||||
void set_end_keys(std::string end_keys) { this->end_keys_ = std::move(end_keys); };
|
void set_end_keys(std::string end_keys) { this->end_keys_ = std::move(end_keys); };
|
||||||
void set_end_key_required(bool end_key_required) { this->end_key_required_ = end_key_required; };
|
void set_end_key_required(bool end_key_required) { this->end_key_required_ = end_key_required; };
|
||||||
@@ -33,8 +33,8 @@ class KeyCollector : public Component {
|
|||||||
protected:
|
protected:
|
||||||
void key_pressed_(uint8_t key);
|
void key_pressed_(uint8_t key);
|
||||||
|
|
||||||
int min_length_{0};
|
uint32_t min_length_{0};
|
||||||
int max_length_{0};
|
uint32_t max_length_{0};
|
||||||
std::string start_keys_;
|
std::string start_keys_;
|
||||||
std::string end_keys_;
|
std::string end_keys_;
|
||||||
bool end_key_required_{false};
|
bool end_key_required_{false};
|
||||||
|
0
esphome/components/lm75b/__init__.py
Normal file
0
esphome/components/lm75b/__init__.py
Normal file
39
esphome/components/lm75b/lm75b.cpp
Normal file
39
esphome/components/lm75b/lm75b.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include "lm75b.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace lm75b {
|
||||||
|
|
||||||
|
static const char *const TAG = "lm75b";
|
||||||
|
|
||||||
|
void LM75BComponent::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "LM75B:");
|
||||||
|
LOG_I2C_DEVICE(this);
|
||||||
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGE(TAG, "Setting up LM75B failed!");
|
||||||
|
}
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
LOG_SENSOR(" ", "Temperature", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LM75BComponent::update() {
|
||||||
|
// Create a temporary buffer
|
||||||
|
uint8_t buff[2];
|
||||||
|
if (this->read_register(LM75B_REG_TEMPERATURE, buff, 2) != i2c::ERROR_OK) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Obtain combined 16-bit value
|
||||||
|
int16_t raw_temperature = (buff[0] << 8) | buff[1];
|
||||||
|
// Read the 11-bit raw temperature value
|
||||||
|
raw_temperature >>= 5;
|
||||||
|
// Publish the temperature in °C
|
||||||
|
this->publish_state(raw_temperature * 0.125);
|
||||||
|
if (this->status_has_warning()) {
|
||||||
|
this->status_clear_warning();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lm75b
|
||||||
|
} // namespace esphome
|
19
esphome/components/lm75b/lm75b.h
Normal file
19
esphome/components/lm75b/lm75b.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace lm75b {
|
||||||
|
|
||||||
|
static const uint8_t LM75B_REG_TEMPERATURE = 0x00;
|
||||||
|
|
||||||
|
class LM75BComponent : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor {
|
||||||
|
public:
|
||||||
|
void dump_config() override;
|
||||||
|
void update() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lm75b
|
||||||
|
} // namespace esphome
|
34
esphome/components/lm75b/sensor.py
Normal file
34
esphome/components/lm75b/sensor.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import i2c, sensor
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import (
|
||||||
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
UNIT_CELSIUS,
|
||||||
|
)
|
||||||
|
|
||||||
|
CODEOWNERS = ["@beormund"]
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
|
||||||
|
lm75b_ns = cg.esphome_ns.namespace("lm75b")
|
||||||
|
LM75BComponent = lm75b_ns.class_(
|
||||||
|
"LM75BComponent", cg.PollingComponent, i2c.I2CDevice, sensor.Sensor
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
sensor.sensor_schema(
|
||||||
|
LM75BComponent,
|
||||||
|
unit_of_measurement=UNIT_CELSIUS,
|
||||||
|
accuracy_decimals=3,
|
||||||
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
)
|
||||||
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
.extend(i2c.i2c_device_schema(0x48))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = await sensor.new_sensor(config)
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await i2c.register_i2c_device(var, config)
|
@@ -2,6 +2,7 @@
|
|||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using esphome::i2c::ErrorCode;
|
using esphome::i2c::ErrorCode;
|
||||||
|
|
||||||
@@ -28,30 +29,30 @@ bool operator!=(const GainTimePair &lhs, const GainTimePair &rhs) {
|
|||||||
|
|
||||||
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t idx = -1;
|
size_t idx = std::numeric_limits<size_t>::max();
|
||||||
while (idx == -1 && i < size) {
|
while (idx == std::numeric_limits<size_t>::max() && i < size) {
|
||||||
if (array[i] == val) {
|
if (array[i] == val) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (idx == -1 || i + 1 >= size)
|
if (idx == std::numeric_limits<size_t>::max() || i + 1 >= size)
|
||||||
return val;
|
return val;
|
||||||
return array[i + 1];
|
return array[i + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t size> T get_prev(const T (&array)[size], const T val) {
|
template<typename T, size_t size> T get_prev(const T (&array)[size], const T val) {
|
||||||
size_t i = size - 1;
|
size_t i = size - 1;
|
||||||
size_t idx = -1;
|
size_t idx = std::numeric_limits<size_t>::max();
|
||||||
while (idx == -1 && i > 0) {
|
while (idx == std::numeric_limits<size_t>::max() && i > 0) {
|
||||||
if (array[i] == val) {
|
if (array[i] == val) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
if (idx == -1 || i == 0)
|
if (idx == std::numeric_limits<size_t>::max() || i == 0)
|
||||||
return val;
|
return val;
|
||||||
return array[i - 1];
|
return array[i - 1];
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using esphome::i2c::ErrorCode;
|
using esphome::i2c::ErrorCode;
|
||||||
|
|
||||||
@@ -14,30 +15,30 @@ static const uint8_t MAX_TRIES = 5;
|
|||||||
|
|
||||||
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t idx = -1;
|
size_t idx = std::numeric_limits<size_t>::max();
|
||||||
while (idx == -1 && i < size) {
|
while (idx == std::numeric_limits<size_t>::max() && i < size) {
|
||||||
if (array[i] == val) {
|
if (array[i] == val) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (idx == -1 || i + 1 >= size)
|
if (idx == std::numeric_limits<size_t>::max() || i + 1 >= size)
|
||||||
return val;
|
return val;
|
||||||
return array[i + 1];
|
return array[i + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t size> T get_prev(const T (&array)[size], const T val) {
|
template<typename T, size_t size> T get_prev(const T (&array)[size], const T val) {
|
||||||
size_t i = size - 1;
|
size_t i = size - 1;
|
||||||
size_t idx = -1;
|
size_t idx = std::numeric_limits<size_t>::max();
|
||||||
while (idx == -1 && i > 0) {
|
while (idx == std::numeric_limits<size_t>::max() && i > 0) {
|
||||||
if (array[i] == val) {
|
if (array[i] == val) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
if (idx == -1 || i == 0)
|
if (idx == std::numeric_limits<size_t>::max() || i == 0)
|
||||||
return val;
|
return val;
|
||||||
return array[i - 1];
|
return array[i - 1];
|
||||||
}
|
}
|
||||||
|
@@ -29,9 +29,9 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
|||||||
void set_columns(std::vector<GPIOPin *> pins) { columns_ = std::move(pins); };
|
void set_columns(std::vector<GPIOPin *> pins) { columns_ = std::move(pins); };
|
||||||
void set_rows(std::vector<GPIOPin *> pins) { rows_ = std::move(pins); };
|
void set_rows(std::vector<GPIOPin *> pins) { rows_ = std::move(pins); };
|
||||||
void set_keys(std::string keys) { keys_ = std::move(keys); };
|
void set_keys(std::string keys) { keys_ = std::move(keys); };
|
||||||
void set_debounce_time(int debounce_time) { debounce_time_ = debounce_time; };
|
void set_debounce_time(uint32_t debounce_time) { debounce_time_ = debounce_time; };
|
||||||
void set_has_diodes(int has_diodes) { has_diodes_ = has_diodes; };
|
void set_has_diodes(bool has_diodes) { has_diodes_ = has_diodes; };
|
||||||
void set_has_pulldowns(int has_pulldowns) { has_pulldowns_ = has_pulldowns; };
|
void set_has_pulldowns(bool has_pulldowns) { has_pulldowns_ = has_pulldowns; };
|
||||||
|
|
||||||
void register_listener(MatrixKeypadListener *listener);
|
void register_listener(MatrixKeypadListener *listener);
|
||||||
void register_key_trigger(MatrixKeyTrigger *trig);
|
void register_key_trigger(MatrixKeyTrigger *trig);
|
||||||
@@ -40,7 +40,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
|||||||
std::vector<GPIOPin *> rows_;
|
std::vector<GPIOPin *> rows_;
|
||||||
std::vector<GPIOPin *> columns_;
|
std::vector<GPIOPin *> columns_;
|
||||||
std::string keys_;
|
std::string keys_;
|
||||||
int debounce_time_ = 0;
|
uint32_t debounce_time_ = 0;
|
||||||
bool has_diodes_{false};
|
bool has_diodes_{false};
|
||||||
bool has_pulldowns_{false};
|
bool has_pulldowns_{false};
|
||||||
int pressed_key_ = -1;
|
int pressed_key_ = -1;
|
||||||
|
@@ -90,7 +90,7 @@ void MAX7219Component::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->scroll_mode_ == ScrollMode::STOP) {
|
if (this->scroll_mode_ == ScrollMode::STOP) {
|
||||||
if (this->stepsleft_ + get_width_internal() == first_line_size + 1) {
|
if (static_cast<size_t>(this->stepsleft_ + get_width_internal()) == first_line_size + 1) {
|
||||||
if (millis_since_last_scroll < this->scroll_dwell_) {
|
if (millis_since_last_scroll < this->scroll_dwell_) {
|
||||||
ESP_LOGVV(TAG, "Dwell time at end of string in case of stop at end. Step %d, since last scroll %d, dwell %d.",
|
ESP_LOGVV(TAG, "Dwell time at end of string in case of stop at end. Step %d, since last scroll %d, dwell %d.",
|
||||||
this->stepsleft_, millis_since_last_scroll, this->scroll_dwell_);
|
this->stepsleft_, millis_since_last_scroll, this->scroll_dwell_);
|
||||||
|
@@ -343,11 +343,7 @@ class DriverChip:
|
|||||||
)
|
)
|
||||||
offset_height = native_height - height - offset_height
|
offset_height = native_height - height - offset_height
|
||||||
# Swap default dimensions if swap_xy is set, or if rotation is 90/270 and we are not using a buffer
|
# Swap default dimensions if swap_xy is set, or if rotation is 90/270 and we are not using a buffer
|
||||||
rotated = not requires_buffer(config) and config.get(CONF_ROTATION, 0) in (
|
if transform.get(CONF_SWAP_XY) is True:
|
||||||
90,
|
|
||||||
270,
|
|
||||||
)
|
|
||||||
if transform.get(CONF_SWAP_XY) is True or rotated:
|
|
||||||
width, height = height, width
|
width, height = height, width
|
||||||
offset_height, offset_width = offset_width, offset_height
|
offset_height, offset_width = offset_width, offset_height
|
||||||
return width, height, offset_width, offset_height
|
return width, height, offset_width, offset_height
|
||||||
|
@@ -380,25 +380,41 @@ def get_instance(config):
|
|||||||
bus_type = BusTypes[bus_type]
|
bus_type = BusTypes[bus_type]
|
||||||
buffer_type = cg.uint8 if color_depth == 8 else cg.uint16
|
buffer_type = cg.uint8 if color_depth == 8 else cg.uint16
|
||||||
frac = denominator(config)
|
frac = denominator(config)
|
||||||
rotation = DISPLAY_ROTATIONS[
|
rotation = (
|
||||||
0 if model.rotation_as_transform(config) else config.get(CONF_ROTATION, 0)
|
0 if model.rotation_as_transform(config) else config.get(CONF_ROTATION, 0)
|
||||||
]
|
)
|
||||||
templateargs = [
|
templateargs = [
|
||||||
buffer_type,
|
buffer_type,
|
||||||
bufferpixels,
|
bufferpixels,
|
||||||
config[CONF_BYTE_ORDER] == "big_endian",
|
config[CONF_BYTE_ORDER] == "big_endian",
|
||||||
display_pixel_mode,
|
display_pixel_mode,
|
||||||
bus_type,
|
bus_type,
|
||||||
|
]
|
||||||
|
# If a buffer is required, use MipiSpiBuffer, otherwise use MipiSpi
|
||||||
|
if requires_buffer(config):
|
||||||
|
templateargs.extend(
|
||||||
|
[
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
offset_width,
|
||||||
|
offset_height,
|
||||||
|
DISPLAY_ROTATIONS[rotation],
|
||||||
|
frac,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return MipiSpiBuffer, templateargs
|
||||||
|
# Swap height and width if the display is rotated 90 or 270 degrees in software
|
||||||
|
if rotation in (90, 270):
|
||||||
|
width, height = height, width
|
||||||
|
offset_width, offset_height = offset_height, offset_width
|
||||||
|
templateargs.extend(
|
||||||
|
[
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
offset_width,
|
offset_width,
|
||||||
offset_height,
|
offset_height,
|
||||||
]
|
]
|
||||||
# If a buffer is required, use MipiSpiBuffer, otherwise use MipiSpi
|
)
|
||||||
if requires_buffer(config):
|
|
||||||
templateargs.append(rotation)
|
|
||||||
templateargs.append(frac)
|
|
||||||
return MipiSpiBuffer, templateargs
|
|
||||||
return MipiSpi, templateargs
|
return MipiSpi, templateargs
|
||||||
|
|
||||||
|
|
||||||
|
@@ -572,7 +572,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Determine how many frames to mix
|
// Determine how many frames to mix
|
||||||
for (int i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
for (size_t i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
||||||
const uint32_t frames_available_in_buffer =
|
const uint32_t frames_available_in_buffer =
|
||||||
speakers_with_data[i]->get_audio_stream_info().bytes_to_frames(transfer_buffers_with_data[i]->available());
|
speakers_with_data[i]->get_audio_stream_info().bytes_to_frames(transfer_buffers_with_data[i]->available());
|
||||||
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
||||||
@@ -581,7 +581,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
audio::AudioStreamInfo primary_stream_info = speakers_with_data[0]->get_audio_stream_info();
|
audio::AudioStreamInfo primary_stream_info = speakers_with_data[0]->get_audio_stream_info();
|
||||||
|
|
||||||
// Mix two streams together
|
// Mix two streams together
|
||||||
for (int i = 1; i < transfer_buffers_with_data.size(); ++i) {
|
for (size_t i = 1; i < transfer_buffers_with_data.size(); ++i) {
|
||||||
mix_audio_samples(primary_buffer, primary_stream_info,
|
mix_audio_samples(primary_buffer, primary_stream_info,
|
||||||
reinterpret_cast<int16_t *>(transfer_buffers_with_data[i]->get_buffer_start()),
|
reinterpret_cast<int16_t *>(transfer_buffers_with_data[i]->get_buffer_start()),
|
||||||
speakers_with_data[i]->get_audio_stream_info(),
|
speakers_with_data[i]->get_audio_stream_info(),
|
||||||
@@ -596,7 +596,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update source transfer buffer lengths and add new audio durations to the source speaker pending playbacks
|
// Update source transfer buffer lengths and add new audio durations to the source speaker pending playbacks
|
||||||
for (int i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
for (size_t i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
||||||
transfer_buffers_with_data[i]->decrease_buffer_length(
|
transfer_buffers_with_data[i]->decrease_buffer_length(
|
||||||
speakers_with_data[i]->get_audio_stream_info().frames_to_bytes(frames_to_mix));
|
speakers_with_data[i]->get_audio_stream_info().frames_to_bytes(frames_to_mix));
|
||||||
speakers_with_data[i]->pending_playback_frames_ += frames_to_mix;
|
speakers_with_data[i]->pending_playback_frames_ += frames_to_mix;
|
||||||
|
@@ -218,7 +218,7 @@ void NAU7802Sensor::dump_config() {
|
|||||||
|
|
||||||
void NAU7802Sensor::write_value_(uint8_t start_reg, size_t size, int32_t value) {
|
void NAU7802Sensor::write_value_(uint8_t start_reg, size_t size, int32_t value) {
|
||||||
uint8_t data[4];
|
uint8_t data[4];
|
||||||
for (int i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
data[i] = 0xFF & (value >> (size - 1 - i) * 8);
|
data[i] = 0xFF & (value >> (size - 1 - i) * 8);
|
||||||
}
|
}
|
||||||
this->write_register(start_reg, data, size);
|
this->write_register(start_reg, data, size);
|
||||||
@@ -228,7 +228,7 @@ int32_t NAU7802Sensor::read_value_(uint8_t start_reg, size_t size) {
|
|||||||
uint8_t data[4];
|
uint8_t data[4];
|
||||||
this->read_register(start_reg, data, size);
|
this->read_register(start_reg, data, size);
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
for (int i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
result |= data[i] << (size - 1 - i) * 8;
|
result |= data[i] << (size - 1 - i) * 8;
|
||||||
}
|
}
|
||||||
// extend sign bit
|
// extend sign bit
|
||||||
|
@@ -77,7 +77,7 @@ bool Nextion::check_connect_() {
|
|||||||
this->recv_ret_string_(response, 0, false);
|
this->recv_ret_string_(response, 0, false);
|
||||||
if (!response.empty() && response[0] == 0x1A) {
|
if (!response.empty() && response[0] == 0x1A) {
|
||||||
// Swallow invalid variable name responses that may be caused by the above commands
|
// Swallow invalid variable name responses that may be caused by the above commands
|
||||||
ESP_LOGD(TAG, "0x1A error ignored (setup)");
|
ESP_LOGV(TAG, "0x1A error ignored (setup)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (response.empty() || response.find("comok") == std::string::npos) {
|
if (response.empty() || response.find("comok") == std::string::npos) {
|
||||||
@@ -334,7 +334,7 @@ void Nextion::loop() {
|
|||||||
this->started_ms_ = App.get_loop_component_start_time();
|
this->started_ms_ = App.get_loop_component_start_time();
|
||||||
|
|
||||||
if (this->started_ms_ + this->startup_override_ms_ < App.get_loop_component_start_time()) {
|
if (this->started_ms_ + this->startup_override_ms_ < App.get_loop_component_start_time()) {
|
||||||
ESP_LOGD(TAG, "Manual ready set");
|
ESP_LOGV(TAG, "Manual ready set");
|
||||||
this->connection_state_.nextion_reports_is_setup_ = true;
|
this->connection_state_.nextion_reports_is_setup_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -544,7 +544,7 @@ void Nextion::process_nextion_commands_() {
|
|||||||
uint8_t page_id = to_process[0];
|
uint8_t page_id = to_process[0];
|
||||||
uint8_t component_id = to_process[1];
|
uint8_t component_id = to_process[1];
|
||||||
uint8_t touch_event = to_process[2]; // 0 -> release, 1 -> press
|
uint8_t touch_event = to_process[2]; // 0 -> release, 1 -> press
|
||||||
ESP_LOGD(TAG, "Touch %s: page %u comp %u", touch_event ? "PRESS" : "RELEASE", page_id, component_id);
|
ESP_LOGV(TAG, "Touch %s: page %u comp %u", touch_event ? "PRESS" : "RELEASE", page_id, component_id);
|
||||||
for (auto *touch : this->touch_) {
|
for (auto *touch : this->touch_) {
|
||||||
touch->process_touch(page_id, component_id, touch_event != 0);
|
touch->process_touch(page_id, component_id, touch_event != 0);
|
||||||
}
|
}
|
||||||
@@ -559,7 +559,7 @@ void Nextion::process_nextion_commands_() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t page_id = to_process[0];
|
uint8_t page_id = to_process[0];
|
||||||
ESP_LOGD(TAG, "New page: %u", page_id);
|
ESP_LOGV(TAG, "New page: %u", page_id);
|
||||||
this->page_callback_.call(page_id);
|
this->page_callback_.call(page_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -577,7 +577,7 @@ void Nextion::process_nextion_commands_() {
|
|||||||
const uint16_t x = (uint16_t(to_process[0]) << 8) | to_process[1];
|
const uint16_t x = (uint16_t(to_process[0]) << 8) | to_process[1];
|
||||||
const uint16_t y = (uint16_t(to_process[2]) << 8) | to_process[3];
|
const uint16_t y = (uint16_t(to_process[2]) << 8) | to_process[3];
|
||||||
const uint8_t touch_event = to_process[4]; // 0 -> release, 1 -> press
|
const uint8_t touch_event = to_process[4]; // 0 -> release, 1 -> press
|
||||||
ESP_LOGD(TAG, "Touch %s at %u,%u", touch_event ? "PRESS" : "RELEASE", x, y);
|
ESP_LOGV(TAG, "Touch %s at %u,%u", touch_event ? "PRESS" : "RELEASE", x, y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ void Nextion::process_nextion_commands_() {
|
|||||||
}
|
}
|
||||||
case 0x88: // system successful start up
|
case 0x88: // system successful start up
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "System start: %zu", to_process_length);
|
ESP_LOGV(TAG, "System start: %zu", to_process_length);
|
||||||
this->connection_state_.nextion_reports_is_setup_ = true;
|
this->connection_state_.nextion_reports_is_setup_ = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -922,7 +922,7 @@ void Nextion::set_nextion_sensor_state(NextionQueueType queue_type, const std::s
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Nextion::set_nextion_text_state(const std::string &name, const std::string &state) {
|
void Nextion::set_nextion_text_state(const std::string &name, const std::string &state) {
|
||||||
ESP_LOGD(TAG, "State: %s='%s'", name.c_str(), state.c_str());
|
ESP_LOGV(TAG, "State: %s='%s'", name.c_str(), state.c_str());
|
||||||
|
|
||||||
for (auto *sensor : this->textsensortype_) {
|
for (auto *sensor : this->textsensortype_) {
|
||||||
if (name == sensor->get_variable_name()) {
|
if (name == sensor->get_variable_name()) {
|
||||||
@@ -933,7 +933,7 @@ void Nextion::set_nextion_text_state(const std::string &name, const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Nextion::all_components_send_state_(bool force_update) {
|
void Nextion::all_components_send_state_(bool force_update) {
|
||||||
ESP_LOGD(TAG, "Send states");
|
ESP_LOGV(TAG, "Send states");
|
||||||
for (auto *binarysensortype : this->binarysensortype_) {
|
for (auto *binarysensortype : this->binarysensortype_) {
|
||||||
if (force_update || binarysensortype->get_needs_to_send_update())
|
if (force_update || binarysensortype->get_needs_to_send_update())
|
||||||
binarysensortype->send_state_to_nextion();
|
binarysensortype->send_state_to_nextion();
|
||||||
|
@@ -117,7 +117,8 @@ int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) {
|
|||||||
this->paint_index_++;
|
this->paint_index_++;
|
||||||
this->current_index_ += 3;
|
this->current_index_ += 3;
|
||||||
index += 3;
|
index += 3;
|
||||||
if (x == this->width_ - 1 && this->padding_bytes_ > 0) {
|
size_t last_col = static_cast<size_t>(this->width_) - 1;
|
||||||
|
if (x == last_col && this->padding_bytes_ > 0) {
|
||||||
index += this->padding_bytes_;
|
index += this->padding_bytes_;
|
||||||
this->current_index_ += this->padding_bytes_;
|
this->current_index_ += this->padding_bytes_;
|
||||||
}
|
}
|
||||||
|
@@ -25,8 +25,10 @@ static int draw_callback(JPEGDRAW *jpeg) {
|
|||||||
// to avoid crashing.
|
// to avoid crashing.
|
||||||
App.feed_wdt();
|
App.feed_wdt();
|
||||||
size_t position = 0;
|
size_t position = 0;
|
||||||
for (size_t y = 0; y < jpeg->iHeight; y++) {
|
size_t height = static_cast<size_t>(jpeg->iHeight);
|
||||||
for (size_t x = 0; x < jpeg->iWidth; x++) {
|
size_t width = static_cast<size_t>(jpeg->iWidth);
|
||||||
|
for (size_t y = 0; y < height; y++) {
|
||||||
|
for (size_t x = 0; x < width; x++) {
|
||||||
auto rg = decode_value(jpeg->pPixels[position++]);
|
auto rg = decode_value(jpeg->pPixels[position++]);
|
||||||
auto ba = decode_value(jpeg->pPixels[position++]);
|
auto ba = decode_value(jpeg->pPixels[position++]);
|
||||||
Color color(rg[1], rg[0], ba[1], ba[0]);
|
Color color(rg[1], rg[0], ba[1], ba[0]);
|
||||||
|
@@ -104,7 +104,7 @@ float PIDController::weighted_average_(std::deque<float> &list, float new_value,
|
|||||||
list.push_front(new_value);
|
list.push_front(new_value);
|
||||||
|
|
||||||
// keep only 'samples' readings, by popping off the back of the list
|
// keep only 'samples' readings, by popping off the back of the list
|
||||||
while (list.size() > samples)
|
while (samples > 0 && list.size() > static_cast<size_t>(samples))
|
||||||
list.pop_back();
|
list.pop_back();
|
||||||
|
|
||||||
// calculate and return the average of all values in the list
|
// calculate and return the average of all values in the list
|
||||||
|
@@ -8,6 +8,7 @@ namespace esphome {
|
|||||||
namespace qmc5883l {
|
namespace qmc5883l {
|
||||||
|
|
||||||
static const char *const TAG = "qmc5883l";
|
static const char *const TAG = "qmc5883l";
|
||||||
|
|
||||||
static const uint8_t QMC5883L_ADDRESS = 0x0D;
|
static const uint8_t QMC5883L_ADDRESS = 0x0D;
|
||||||
|
|
||||||
static const uint8_t QMC5883L_REGISTER_DATA_X_LSB = 0x00;
|
static const uint8_t QMC5883L_REGISTER_DATA_X_LSB = 0x00;
|
||||||
@@ -32,6 +33,10 @@ void QMC5883LComponent::setup() {
|
|||||||
}
|
}
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
|
if (this->drdy_pin_) {
|
||||||
|
this->drdy_pin_->setup();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t control_1 = 0;
|
uint8_t control_1 = 0;
|
||||||
control_1 |= 0b01 << 0; // MODE (Mode) -> 0b00=standby, 0b01=continuous
|
control_1 |= 0b01 << 0; // MODE (Mode) -> 0b00=standby, 0b01=continuous
|
||||||
control_1 |= this->datarate_ << 2;
|
control_1 |= this->datarate_ << 2;
|
||||||
@@ -64,6 +69,7 @@ void QMC5883LComponent::setup() {
|
|||||||
high_freq_.start();
|
high_freq_.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMC5883LComponent::dump_config() {
|
void QMC5883LComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "QMC5883L:");
|
ESP_LOGCONFIG(TAG, "QMC5883L:");
|
||||||
LOG_I2C_DEVICE(this);
|
LOG_I2C_DEVICE(this);
|
||||||
@@ -77,11 +83,20 @@ void QMC5883LComponent::dump_config() {
|
|||||||
LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
|
LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
|
||||||
LOG_SENSOR(" ", "Heading", this->heading_sensor_);
|
LOG_SENSOR(" ", "Heading", this->heading_sensor_);
|
||||||
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
||||||
|
LOG_PIN(" DRDY Pin: ", this->drdy_pin_);
|
||||||
}
|
}
|
||||||
|
|
||||||
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
|
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
|
||||||
void QMC5883LComponent::update() {
|
void QMC5883LComponent::update() {
|
||||||
i2c::ErrorCode err;
|
i2c::ErrorCode err;
|
||||||
uint8_t status = false;
|
uint8_t status = false;
|
||||||
|
|
||||||
|
// If DRDY pin is configured and the data is not ready return.
|
||||||
|
if (this->drdy_pin_ && !this->drdy_pin_->digital_read()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Status byte gets cleared when data is read, so we have to read this first.
|
// 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
|
// 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.
|
// ROL_PNT in setup and reading 7 bytes starting at the status register.
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
#include "esphome/components/i2c/i2c.h"
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace qmc5883l {
|
namespace qmc5883l {
|
||||||
@@ -33,6 +34,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
|
|||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
|
void set_drdy_pin(GPIOPin *pin) { drdy_pin_ = pin; }
|
||||||
void set_datarate(QMC5883LDatarate datarate) { datarate_ = datarate; }
|
void set_datarate(QMC5883LDatarate datarate) { datarate_ = datarate; }
|
||||||
void set_range(QMC5883LRange range) { range_ = range; }
|
void set_range(QMC5883LRange range) { range_ = range; }
|
||||||
void set_oversampling(QMC5883LOversampling oversampling) { oversampling_ = oversampling; }
|
void set_oversampling(QMC5883LOversampling oversampling) { oversampling_ = oversampling; }
|
||||||
@@ -51,6 +53,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
|
|||||||
sensor::Sensor *z_sensor_{nullptr};
|
sensor::Sensor *z_sensor_{nullptr};
|
||||||
sensor::Sensor *heading_sensor_{nullptr};
|
sensor::Sensor *heading_sensor_{nullptr};
|
||||||
sensor::Sensor *temperature_sensor_{nullptr};
|
sensor::Sensor *temperature_sensor_{nullptr};
|
||||||
|
GPIOPin *drdy_pin_{nullptr};
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
COMMUNICATION_FAILED,
|
COMMUNICATION_FAILED,
|
||||||
|
@@ -1,8 +1,12 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from esphome import pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import i2c, sensor
|
from esphome.components import i2c, sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ADDRESS,
|
CONF_ADDRESS,
|
||||||
|
CONF_DATA_RATE,
|
||||||
CONF_FIELD_STRENGTH_X,
|
CONF_FIELD_STRENGTH_X,
|
||||||
CONF_FIELD_STRENGTH_Y,
|
CONF_FIELD_STRENGTH_Y,
|
||||||
CONF_FIELD_STRENGTH_Z,
|
CONF_FIELD_STRENGTH_Z,
|
||||||
@@ -21,6 +25,10 @@ from esphome.const import (
|
|||||||
UNIT_MICROTESLA,
|
UNIT_MICROTESLA,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF_DRDY_PIN = "drdy_pin"
|
||||||
|
|
||||||
DEPENDENCIES = ["i2c"]
|
DEPENDENCIES = ["i2c"]
|
||||||
|
|
||||||
qmc5883l_ns = cg.esphome_ns.namespace("qmc5883l")
|
qmc5883l_ns = cg.esphome_ns.namespace("qmc5883l")
|
||||||
@@ -52,6 +60,18 @@ QMC5883LOversamplings = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_config(config):
|
||||||
|
if (
|
||||||
|
config[CONF_UPDATE_INTERVAL].total_milliseconds < 15
|
||||||
|
and CONF_DRDY_PIN not in config
|
||||||
|
):
|
||||||
|
_LOGGER.warning(
|
||||||
|
"[qmc5883l] 'update_interval' is less than 15ms and 'drdy_pin' is "
|
||||||
|
"not configured, this may result in I2C errors"
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
def validate_enum(enum_values, units=None, int=True):
|
def validate_enum(enum_values, units=None, int=True):
|
||||||
_units = []
|
_units = []
|
||||||
if units is not None:
|
if units is not None:
|
||||||
@@ -88,7 +108,7 @@ temperature_schema = sensor.sensor_schema(
|
|||||||
state_class=STATE_CLASS_MEASUREMENT,
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(QMC5883LComponent),
|
cv.GenerateID(): cv.declare_id(QMC5883LComponent),
|
||||||
@@ -104,29 +124,25 @@ CONFIG_SCHEMA = (
|
|||||||
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
||||||
cv.Optional(CONF_HEADING): heading_schema,
|
cv.Optional(CONF_HEADING): heading_schema,
|
||||||
cv.Optional(CONF_TEMPERATURE): temperature_schema,
|
cv.Optional(CONF_TEMPERATURE): temperature_schema,
|
||||||
|
cv.Optional(CONF_DRDY_PIN): pins.gpio_input_pin_schema,
|
||||||
|
cv.Optional(CONF_DATA_RATE, default="200hz"): validate_enum(
|
||||||
|
QMC5883LDatarates, units=["hz", "Hz"]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s"))
|
.extend(cv.polling_component_schema("60s"))
|
||||||
.extend(i2c.i2c_device_schema(0x0D))
|
.extend(i2c.i2c_device_schema(0x0D)),
|
||||||
|
validate_config,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def auto_data_rate(config):
|
|
||||||
interval_sec = config[CONF_UPDATE_INTERVAL].total_milliseconds / 1000
|
|
||||||
interval_hz = 1.0 / interval_sec
|
|
||||||
for datarate in sorted(QMC5883LDatarates.keys()):
|
|
||||||
if float(datarate) >= interval_hz:
|
|
||||||
return QMC5883LDatarates[datarate]
|
|
||||||
return QMC5883LDatarates[200]
|
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
await i2c.register_i2c_device(var, config)
|
await i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
cg.add(var.set_oversampling(config[CONF_OVERSAMPLING]))
|
cg.add(var.set_oversampling(config[CONF_OVERSAMPLING]))
|
||||||
cg.add(var.set_datarate(auto_data_rate(config)))
|
cg.add(var.set_datarate(config[CONF_DATA_RATE]))
|
||||||
cg.add(var.set_range(config[CONF_RANGE]))
|
cg.add(var.set_range(config[CONF_RANGE]))
|
||||||
if CONF_FIELD_STRENGTH_X in config:
|
if CONF_FIELD_STRENGTH_X in config:
|
||||||
sens = await sensor.new_sensor(config[CONF_FIELD_STRENGTH_X])
|
sens = await sensor.new_sensor(config[CONF_FIELD_STRENGTH_X])
|
||||||
@@ -143,3 +159,6 @@ async def to_code(config):
|
|||||||
if CONF_TEMPERATURE in config:
|
if CONF_TEMPERATURE in config:
|
||||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||||
cg.add(var.set_temperature_sensor(sens))
|
cg.add(var.set_temperature_sensor(sens))
|
||||||
|
if CONF_DRDY_PIN in config:
|
||||||
|
pin = await cg.gpio_pin_expression(config[CONF_DRDY_PIN])
|
||||||
|
cg.add(var.set_drdy_pin(pin))
|
||||||
|
@@ -10,8 +10,8 @@ constexpr uint32_t BIT_MARK_US = 580; // 70us seems like a safe time delta for
|
|||||||
constexpr uint32_t BIT_ONE_SPACE_US = 1640;
|
constexpr uint32_t BIT_ONE_SPACE_US = 1640;
|
||||||
constexpr uint32_t BIT_ZERO_SPACE_US = 545;
|
constexpr uint32_t BIT_ZERO_SPACE_US = 545;
|
||||||
constexpr uint64_t HEADER = 0b011001001100010uL; // 15 bits
|
constexpr uint64_t HEADER = 0b011001001100010uL; // 15 bits
|
||||||
constexpr uint64_t HEADER_SIZE = 15;
|
constexpr size_t HEADER_SIZE = 15;
|
||||||
constexpr uint64_t CODE_SIZE = 17;
|
constexpr size_t CODE_SIZE = 17;
|
||||||
|
|
||||||
void GoboxProtocol::dump_timings_(const RawTimings &timings) const {
|
void GoboxProtocol::dump_timings_(const RawTimings &timings) const {
|
||||||
ESP_LOGD(TAG, "Gobox: size=%u", timings.size());
|
ESP_LOGD(TAG, "Gobox: size=%u", timings.size());
|
||||||
@@ -39,7 +39,7 @@ void GoboxProtocol::encode(RemoteTransmitData *dst, const GoboxData &data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
optional<GoboxData> GoboxProtocol::decode(RemoteReceiveData src) {
|
optional<GoboxData> GoboxProtocol::decode(RemoteReceiveData src) {
|
||||||
if (src.size() < ((HEADER_SIZE + CODE_SIZE) * 2 + 1)) {
|
if (static_cast<size_t>(src.size()) < ((HEADER_SIZE + CODE_SIZE) * 2 + 1)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ static const char *const TAG = "sonoff_d1";
|
|||||||
|
|
||||||
uint8_t SonoffD1Output::calc_checksum_(const uint8_t *cmd, const size_t len) {
|
uint8_t SonoffD1Output::calc_checksum_(const uint8_t *cmd, const size_t len) {
|
||||||
uint8_t crc = 0;
|
uint8_t crc = 0;
|
||||||
for (int i = 2; i < len - 1; i++) {
|
for (size_t i = 2; i < len - 1; i++) {
|
||||||
crc += cmd[i];
|
crc += cmd[i];
|
||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
|
@@ -50,8 +50,10 @@ void HOT I2CST7567::write_display_data() {
|
|||||||
|
|
||||||
static const size_t BLOCK_SIZE = 64;
|
static const size_t BLOCK_SIZE = 64;
|
||||||
for (uint8_t x = 0; x < (uint8_t) this->get_width_internal(); x += BLOCK_SIZE) {
|
for (uint8_t x = 0; x < (uint8_t) this->get_width_internal(); x += BLOCK_SIZE) {
|
||||||
|
size_t remaining = static_cast<size_t>(this->get_width_internal()) - x;
|
||||||
|
size_t chunk = remaining > BLOCK_SIZE ? BLOCK_SIZE : remaining;
|
||||||
this->write_register(esphome::st7567_base::ST7567_SET_START_LINE, &buffer_[y * this->get_width_internal() + x],
|
this->write_register(esphome::st7567_base::ST7567_SET_START_LINE, &buffer_[y * this->get_width_internal() + x],
|
||||||
this->get_width_internal() - x > BLOCK_SIZE ? BLOCK_SIZE : this->get_width_internal() - x);
|
chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -176,8 +176,9 @@ void ST7789V::write_display_data() {
|
|||||||
if (this->eightbitcolor_) {
|
if (this->eightbitcolor_) {
|
||||||
uint8_t temp_buffer[TEMP_BUFFER_SIZE];
|
uint8_t temp_buffer[TEMP_BUFFER_SIZE];
|
||||||
size_t temp_index = 0;
|
size_t temp_index = 0;
|
||||||
for (int line = 0; line < this->get_buffer_length_(); line = line + this->get_width_internal()) {
|
size_t width = static_cast<size_t>(this->get_width_internal());
|
||||||
for (int index = 0; index < this->get_width_internal(); ++index) {
|
for (size_t line = 0; line < this->get_buffer_length_(); line += width) {
|
||||||
|
for (size_t index = 0; index < width; ++index) {
|
||||||
auto color = display::ColorUtil::color_to_565(
|
auto color = display::ColorUtil::color_to_565(
|
||||||
display::ColorUtil::to_color(this->buffer_[index + line], display::ColorOrder::COLOR_ORDER_RGB,
|
display::ColorUtil::to_color(this->buffer_[index + line], display::ColorOrder::COLOR_ORDER_RGB,
|
||||||
display::ColorBitness::COLOR_BITNESS_332, true));
|
display::ColorBitness::COLOR_BITNESS_332, true));
|
||||||
|
@@ -151,7 +151,7 @@ void StatsdComponent::send_(std::string *out) {
|
|||||||
|
|
||||||
int n_bytes = this->sock_->sendto(out->c_str(), out->length(), 0, reinterpret_cast<sockaddr *>(&this->destination_),
|
int n_bytes = this->sock_->sendto(out->c_str(), out->length(), 0, reinterpret_cast<sockaddr *>(&this->destination_),
|
||||||
sizeof(this->destination_));
|
sizeof(this->destination_));
|
||||||
if (n_bytes != out->length()) {
|
if (n_bytes != static_cast<int>(out->length())) {
|
||||||
ESP_LOGE(TAG, "Failed to send UDP packed (%d of %d)", n_bytes, out->length());
|
ESP_LOGE(TAG, "Failed to send UDP packed (%d of %d)", n_bytes, out->length());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -50,7 +50,7 @@ void TuyaSelect::dump_config() {
|
|||||||
" Options are:",
|
" Options are:",
|
||||||
this->select_id_, this->is_int_ ? "int" : "enum");
|
this->select_id_, this->is_int_ ? "int" : "enum");
|
||||||
auto options = this->traits.get_options();
|
auto options = this->traits.get_options();
|
||||||
for (auto i = 0; i < this->mappings_.size(); i++) {
|
for (size_t i = 0; i < this->mappings_.size(); i++) {
|
||||||
ESP_LOGCONFIG(TAG, " %i: %s", this->mappings_.at(i), options.at(i).c_str());
|
ESP_LOGCONFIG(TAG, " %i: %s", this->mappings_.at(i), options.at(i).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -334,9 +334,9 @@ void WiFiComponent::set_sta(const WiFiAP &ap) {
|
|||||||
}
|
}
|
||||||
void WiFiComponent::clear_sta() { this->sta_.clear(); }
|
void WiFiComponent::clear_sta() { this->sta_.clear(); }
|
||||||
void WiFiComponent::save_wifi_sta(const std::string &ssid, const std::string &password) {
|
void WiFiComponent::save_wifi_sta(const std::string &ssid, const std::string &password) {
|
||||||
SavedWifiSettings save{}; // zero-initialized
|
SavedWifiSettings save{}; // zero-initialized - all bytes set to \0, guaranteeing null termination
|
||||||
strncpy(save.ssid, ssid.c_str(), sizeof(save.ssid) - 1);
|
strncpy(save.ssid, ssid.c_str(), sizeof(save.ssid) - 1); // max 32 chars, byte 32 remains \0
|
||||||
strncpy(save.password, password.c_str(), sizeof(save.password) - 1);
|
strncpy(save.password, password.c_str(), sizeof(save.password) - 1); // max 64 chars, byte 64 remains \0
|
||||||
this->pref_.save(&save);
|
this->pref_.save(&save);
|
||||||
// ensure it's written immediately
|
// ensure it's written immediately
|
||||||
global_preferences->sync();
|
global_preferences->sync();
|
||||||
|
@@ -101,15 +101,7 @@ void ZWaveProxy::process_uart_() {
|
|||||||
// Store the 4-byte Home ID, which starts at offset 4, and notify connected clients if it changed
|
// Store the 4-byte Home ID, which starts at offset 4, and notify connected clients if it changed
|
||||||
// The frame parser has already validated the checksum and ensured all bytes are present
|
// The frame parser has already validated the checksum and ensured all bytes are present
|
||||||
if (this->set_home_id(&this->buffer_[4])) {
|
if (this->set_home_id(&this->buffer_[4])) {
|
||||||
api::ZWaveProxyRequest msg;
|
this->send_homeid_changed_msg_();
|
||||||
msg.type = api::enums::ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE;
|
|
||||||
msg.data = this->home_id_.data();
|
|
||||||
msg.data_len = this->home_id_.size();
|
|
||||||
if (api::global_api_server != nullptr) {
|
|
||||||
// We could add code to manage a second subscription type, but, since this message is
|
|
||||||
// very infrequent and small, we simply send it to all clients
|
|
||||||
api::global_api_server->on_zwave_proxy_request(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "Sending to client: %s", YESNO(this->api_connection_ != nullptr));
|
ESP_LOGV(TAG, "Sending to client: %s", YESNO(this->api_connection_ != nullptr));
|
||||||
@@ -135,6 +127,13 @@ void ZWaveProxy::dump_config() {
|
|||||||
format_hex_pretty(this->home_id_.data(), this->home_id_.size(), ':', false).c_str());
|
format_hex_pretty(this->home_id_.data(), this->home_id_.size(), ':', false).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZWaveProxy::api_connection_authenticated(api::APIConnection *conn) {
|
||||||
|
if (this->home_id_ready_) {
|
||||||
|
// If a client just authenticated & HomeID is ready, send the current HomeID
|
||||||
|
this->send_homeid_changed_msg_(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ZWaveProxy::zwave_proxy_request(api::APIConnection *api_connection, api::enums::ZWaveProxyRequestType type) {
|
void ZWaveProxy::zwave_proxy_request(api::APIConnection *api_connection, api::enums::ZWaveProxyRequestType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case api::enums::ZWAVE_PROXY_REQUEST_TYPE_SUBSCRIBE:
|
case api::enums::ZWAVE_PROXY_REQUEST_TYPE_SUBSCRIBE:
|
||||||
@@ -178,6 +177,21 @@ void ZWaveProxy::send_frame(const uint8_t *data, size_t length) {
|
|||||||
this->write_array(data, length);
|
this->write_array(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZWaveProxy::send_homeid_changed_msg_(api::APIConnection *conn) {
|
||||||
|
api::ZWaveProxyRequest msg;
|
||||||
|
msg.type = api::enums::ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE;
|
||||||
|
msg.data = this->home_id_.data();
|
||||||
|
msg.data_len = this->home_id_.size();
|
||||||
|
if (conn != nullptr) {
|
||||||
|
// Send to specific connection
|
||||||
|
conn->send_message(msg, api::ZWaveProxyRequest::MESSAGE_TYPE);
|
||||||
|
} else if (api::global_api_server != nullptr) {
|
||||||
|
// We could add code to manage a second subscription type, but, since this message is
|
||||||
|
// very infrequent and small, we simply send it to all clients
|
||||||
|
api::global_api_server->on_zwave_proxy_request(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ZWaveProxy::send_simple_command_(const uint8_t command_id) {
|
void ZWaveProxy::send_simple_command_(const uint8_t command_id) {
|
||||||
// Send a simple Z-Wave command with no parameters
|
// Send a simple Z-Wave command with no parameters
|
||||||
// Frame format: [SOF][LENGTH][TYPE][CMD][CHECKSUM]
|
// Frame format: [SOF][LENGTH][TYPE][CMD][CHECKSUM]
|
||||||
|
@@ -49,6 +49,7 @@ class ZWaveProxy : public uart::UARTDevice, public Component {
|
|||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
bool can_proceed() override;
|
bool can_proceed() override;
|
||||||
|
|
||||||
|
void api_connection_authenticated(api::APIConnection *conn);
|
||||||
void zwave_proxy_request(api::APIConnection *api_connection, api::enums::ZWaveProxyRequestType type);
|
void zwave_proxy_request(api::APIConnection *api_connection, api::enums::ZWaveProxyRequestType type);
|
||||||
api::APIConnection *get_api_connection() { return this->api_connection_; }
|
api::APIConnection *get_api_connection() { return this->api_connection_; }
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@ class ZWaveProxy : public uart::UARTDevice, public Component {
|
|||||||
void send_frame(const uint8_t *data, size_t length);
|
void send_frame(const uint8_t *data, size_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void send_homeid_changed_msg_(api::APIConnection *conn = nullptr);
|
||||||
void send_simple_command_(uint8_t command_id);
|
void send_simple_command_(uint8_t command_id);
|
||||||
bool parse_byte_(uint8_t byte); // Returns true if frame parsing was completed (a frame is ready in the buffer)
|
bool parse_byte_(uint8_t byte); // Returns true if frame parsing was completed (a frame is ready in the buffer)
|
||||||
void parse_start_(uint8_t byte);
|
void parse_start_(uint8_t byte);
|
||||||
|
@@ -22,8 +22,6 @@ uv pip install -e ".[dev,test]" --config-settings editable_mode=compat
|
|||||||
|
|
||||||
pre-commit install
|
pre-commit install
|
||||||
|
|
||||||
script/platformio_install_deps.py platformio.ini --libraries --tools --platforms
|
|
||||||
|
|
||||||
mkdir -p .temp
|
mkdir -p .temp
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
@@ -19,8 +19,6 @@ pip3 install -e ".[dev,test]" --config-settings editable_mode=compat
|
|||||||
|
|
||||||
pre-commit install
|
pre-commit install
|
||||||
|
|
||||||
python script/platformio_install_deps.py platformio.ini --libraries --tools --platforms
|
|
||||||
|
|
||||||
echo .
|
echo .
|
||||||
echo .
|
echo .
|
||||||
echo Virtual environment created. Run 'venv/Scripts/activate' to use it.
|
echo Virtual environment created. Run 'venv/Scripts/activate' to use it.
|
||||||
|
9
tests/components/lm75b/common.yaml
Normal file
9
tests/components/lm75b/common.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
i2c:
|
||||||
|
- id: i2c_lm75b
|
||||||
|
scl: ${scl_pin}
|
||||||
|
sda: ${sda_pin}
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: lm75b
|
||||||
|
name: LM75B Temperature
|
||||||
|
update_interval: 30s
|
5
tests/components/lm75b/test.esp32-ard.yaml
Normal file
5
tests/components/lm75b/test.esp32-ard.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
scl_pin: GPIO15
|
||||||
|
sda_pin: GPIO13
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/lm75b/test.esp32-c3-ard.yaml
Normal file
5
tests/components/lm75b/test.esp32-c3-ard.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
scl_pin: GPIO5
|
||||||
|
sda_pin: GPIO4
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/lm75b/test.esp32-c3-idf.yaml
Normal file
5
tests/components/lm75b/test.esp32-c3-idf.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
scl_pin: GPIO5
|
||||||
|
sda_pin: GPIO4
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/lm75b/test.esp32-idf.yaml
Normal file
5
tests/components/lm75b/test.esp32-idf.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
scl_pin: GPIO15
|
||||||
|
sda_pin: GPIO13
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/lm75b/test.esp8266-ard.yaml
Normal file
5
tests/components/lm75b/test.esp8266-ard.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
scl_pin: GPIO5
|
||||||
|
sda_pin: GPIO4
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/lm75b/test.rp2040-ard.yaml
Normal file
5
tests/components/lm75b/test.rp2040-ard.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
scl_pin: GPIO5
|
||||||
|
sda_pin: GPIO4
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
@@ -17,5 +17,7 @@ sensor:
|
|||||||
temperature:
|
temperature:
|
||||||
name: QMC5883L Temperature
|
name: QMC5883L Temperature
|
||||||
range: 800uT
|
range: 800uT
|
||||||
|
data_rate: 200Hz
|
||||||
oversampling: 256x
|
oversampling: 256x
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
|
drdy_pin: ${drdy_pin}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO16
|
scl_pin: GPIO16
|
||||||
sda_pin: GPIO17
|
sda_pin: GPIO17
|
||||||
|
drdy_pin: GPIO18
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO6
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO6
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO16
|
scl_pin: GPIO16
|
||||||
sda_pin: GPIO17
|
sda_pin: GPIO17
|
||||||
|
drdy_pin: GPIO18
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO2
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO2
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
Reference in New Issue
Block a user