mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 01:08:03 +01:00
commit
55e36ab982
22 changed files with 157 additions and 68 deletions
|
@ -29,7 +29,8 @@ RUN \
|
||||||
curl=7.74.0-1.3+deb11u7 \
|
curl=7.74.0-1.3+deb11u7 \
|
||||||
openssh-client=1:8.4p1-5+deb11u1 \
|
openssh-client=1:8.4p1-5+deb11u1 \
|
||||||
python3-cffi=1.14.5-1 \
|
python3-cffi=1.14.5-1 \
|
||||||
libcairo2=1.16.0-5; \
|
libcairo2=1.16.0-5 \
|
||||||
|
patch=2.7.6-7; \
|
||||||
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
|
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
build-essential=12.9 \
|
build-essential=12.9 \
|
||||||
|
|
|
@ -80,8 +80,6 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
||||||
TEMPLATABLE_VALUE(std::string, url)
|
TEMPLATABLE_VALUE(std::string, url)
|
||||||
TEMPLATABLE_VALUE(const char *, method)
|
TEMPLATABLE_VALUE(const char *, method)
|
||||||
TEMPLATABLE_VALUE(std::string, body)
|
TEMPLATABLE_VALUE(std::string, body)
|
||||||
TEMPLATABLE_VALUE(const char *, useragent)
|
|
||||||
TEMPLATABLE_VALUE(uint16_t, timeout)
|
|
||||||
|
|
||||||
void add_header(const char *key, TemplatableValue<const char *, Ts...> value) { this->headers_.insert({key, value}); }
|
void add_header(const char *key, TemplatableValue<const char *, Ts...> value) { this->headers_.insert({key, value}); }
|
||||||
|
|
||||||
|
@ -105,13 +103,6 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
||||||
auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_func_, this, x..., std::placeholders::_1);
|
auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_func_, this, x..., std::placeholders::_1);
|
||||||
this->parent_->set_body(json::build_json(f));
|
this->parent_->set_body(json::build_json(f));
|
||||||
}
|
}
|
||||||
if (this->useragent_.has_value()) {
|
|
||||||
this->parent_->set_useragent(this->useragent_.value(x...));
|
|
||||||
}
|
|
||||||
if (this->timeout_.has_value()) {
|
|
||||||
this->parent_->set_timeout(this->timeout_.value(x...));
|
|
||||||
}
|
|
||||||
if (!this->headers_.empty()) {
|
|
||||||
std::list<Header> headers;
|
std::list<Header> headers;
|
||||||
for (const auto &item : this->headers_) {
|
for (const auto &item : this->headers_) {
|
||||||
auto val = item.second;
|
auto val = item.second;
|
||||||
|
@ -121,9 +112,9 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
||||||
headers.push_back(header);
|
headers.push_back(header);
|
||||||
}
|
}
|
||||||
this->parent_->set_headers(headers);
|
this->parent_->set_headers(headers);
|
||||||
}
|
|
||||||
this->parent_->send(this->response_triggers_);
|
this->parent_->send(this->response_triggers_);
|
||||||
this->parent_->close();
|
this->parent_->close();
|
||||||
|
this->parent_->set_body("");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -21,6 +21,7 @@ CONF_COLUMNS = "columns"
|
||||||
CONF_KEYS = "keys"
|
CONF_KEYS = "keys"
|
||||||
CONF_DEBOUNCE_TIME = "debounce_time"
|
CONF_DEBOUNCE_TIME = "debounce_time"
|
||||||
CONF_HAS_DIODES = "has_diodes"
|
CONF_HAS_DIODES = "has_diodes"
|
||||||
|
CONF_HAS_PULLDOWNS = "has_pulldowns"
|
||||||
|
|
||||||
|
|
||||||
def check_keys(obj):
|
def check_keys(obj):
|
||||||
|
@ -45,6 +46,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_KEYS): cv.string,
|
cv.Optional(CONF_KEYS): cv.string,
|
||||||
cv.Optional(CONF_DEBOUNCE_TIME, default=1): cv.int_range(min=1, max=100),
|
cv.Optional(CONF_DEBOUNCE_TIME, default=1): cv.int_range(min=1, max=100),
|
||||||
cv.Optional(CONF_HAS_DIODES): cv.boolean,
|
cv.Optional(CONF_HAS_DIODES): cv.boolean,
|
||||||
|
cv.Optional(CONF_HAS_PULLDOWNS): cv.boolean,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
check_keys,
|
check_keys,
|
||||||
|
@ -69,3 +71,5 @@ async def to_code(config):
|
||||||
cg.add(var.set_debounce_time(config[CONF_DEBOUNCE_TIME]))
|
cg.add(var.set_debounce_time(config[CONF_DEBOUNCE_TIME]))
|
||||||
if CONF_HAS_DIODES in config:
|
if CONF_HAS_DIODES in config:
|
||||||
cg.add(var.set_has_diodes(config[CONF_HAS_DIODES]))
|
cg.add(var.set_has_diodes(config[CONF_HAS_DIODES]))
|
||||||
|
if CONF_HAS_PULLDOWNS in config:
|
||||||
|
cg.add(var.set_has_pulldowns(config[CONF_HAS_PULLDOWNS]))
|
||||||
|
|
|
@ -11,11 +11,16 @@ void MatrixKeypad::setup() {
|
||||||
if (!has_diodes_) {
|
if (!has_diodes_) {
|
||||||
pin->pin_mode(gpio::FLAG_INPUT);
|
pin->pin_mode(gpio::FLAG_INPUT);
|
||||||
} else {
|
} else {
|
||||||
pin->digital_write(true);
|
pin->digital_write(!has_pulldowns_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto *pin : this->columns_)
|
for (auto *pin : this->columns_) {
|
||||||
|
if (has_pulldowns_) {
|
||||||
|
pin->pin_mode(gpio::FLAG_INPUT);
|
||||||
|
} else {
|
||||||
pin->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
pin->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatrixKeypad::loop() {
|
void MatrixKeypad::loop() {
|
||||||
|
@ -28,9 +33,9 @@ void MatrixKeypad::loop() {
|
||||||
for (auto *row : this->rows_) {
|
for (auto *row : this->rows_) {
|
||||||
if (!has_diodes_)
|
if (!has_diodes_)
|
||||||
row->pin_mode(gpio::FLAG_OUTPUT);
|
row->pin_mode(gpio::FLAG_OUTPUT);
|
||||||
row->digital_write(false);
|
row->digital_write(has_pulldowns_);
|
||||||
for (auto *col : this->columns_) {
|
for (auto *col : this->columns_) {
|
||||||
if (!col->digital_read()) {
|
if (col->digital_read() == has_pulldowns_) {
|
||||||
if (key != -1) {
|
if (key != -1) {
|
||||||
error = true;
|
error = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,7 +44,7 @@ void MatrixKeypad::loop() {
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
row->digital_write(true);
|
row->digital_write(!has_pulldowns_);
|
||||||
if (!has_diodes_)
|
if (!has_diodes_)
|
||||||
row->pin_mode(gpio::FLAG_INPUT);
|
row->pin_mode(gpio::FLAG_INPUT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
||||||
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(int debounce_time) { debounce_time_ = debounce_time; };
|
||||||
void set_has_diodes(int has_diodes) { has_diodes_ = has_diodes; };
|
void set_has_diodes(int has_diodes) { has_diodes_ = has_diodes; };
|
||||||
|
void set_has_pulldowns(int has_pulldowns) { has_pulldowns_ = has_pulldowns; };
|
||||||
|
|
||||||
void register_listener(MatrixKeypadListener *listener);
|
void register_listener(MatrixKeypadListener *listener);
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
||||||
std::string keys_;
|
std::string keys_;
|
||||||
int debounce_time_ = 0;
|
int debounce_time_ = 0;
|
||||||
bool has_diodes_{false};
|
bool has_diodes_{false};
|
||||||
|
bool has_pulldowns_{false};
|
||||||
int pressed_key_ = -1;
|
int pressed_key_ = -1;
|
||||||
|
|
||||||
std::vector<MatrixKeypadListener *> listeners_{};
|
std::vector<MatrixKeypadListener *> listeners_{};
|
||||||
|
|
|
@ -35,7 +35,7 @@ from esphome.components.climate import (
|
||||||
)
|
)
|
||||||
|
|
||||||
CODEOWNERS = ["@dudanov"]
|
CODEOWNERS = ["@dudanov"]
|
||||||
DEPENDENCIES = ["climate", "uart", "wifi"]
|
DEPENDENCIES = ["climate", "uart"]
|
||||||
AUTO_LOAD = ["sensor"]
|
AUTO_LOAD = ["sensor"]
|
||||||
CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
|
CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
|
||||||
CONF_POWER_USAGE = "power_usage"
|
CONF_POWER_USAGE = "power_usage"
|
||||||
|
|
|
@ -71,7 +71,8 @@ bool MopekaStdCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
|
||||||
const auto *mopeka_data = (const mopeka_std_package *) manu_data.data.data();
|
const auto *mopeka_data = (const mopeka_std_package *) manu_data.data.data();
|
||||||
|
|
||||||
const u_int8_t hardware_id = mopeka_data->data_1 & 0xCF;
|
const u_int8_t hardware_id = mopeka_data->data_1 & 0xCF;
|
||||||
if (static_cast<SensorType>(hardware_id) != STANDARD && static_cast<SensorType>(hardware_id) != XL) {
|
if (static_cast<SensorType>(hardware_id) != STANDARD && static_cast<SensorType>(hardware_id) != XL &&
|
||||||
|
static_cast<SensorType>(hardware_id) != ETRAILER) {
|
||||||
ESP_LOGE(TAG, "[%s] Unsupported Sensor Type (0x%X)", device.address_str().c_str(), hardware_id);
|
ESP_LOGE(TAG, "[%s] Unsupported Sensor Type (0x%X)", device.address_str().c_str(), hardware_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace mopeka_std_check {
|
||||||
enum SensorType {
|
enum SensorType {
|
||||||
STANDARD = 0x02,
|
STANDARD = 0x02,
|
||||||
XL = 0x03,
|
XL = 0x03,
|
||||||
|
ETRAILER = 0x46,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 4 values in one struct so it aligns to 8 byte. One `mopeka_std_values` is 40 bit long.
|
// 4 values in one struct so it aligns to 8 byte. One `mopeka_std_values` is 40 bit long.
|
||||||
|
|
|
@ -11,6 +11,9 @@ void PulseMeterSensor::setup() {
|
||||||
this->pin_->setup();
|
this->pin_->setup();
|
||||||
this->isr_pin_ = pin_->to_isr();
|
this->isr_pin_ = pin_->to_isr();
|
||||||
|
|
||||||
|
// Set the last processed edge to now for the first timeout
|
||||||
|
this->last_processed_edge_us_ = micros();
|
||||||
|
|
||||||
if (this->filter_mode_ == FILTER_EDGE) {
|
if (this->filter_mode_ == FILTER_EDGE) {
|
||||||
this->pin_->attach_interrupt(PulseMeterSensor::edge_intr, this, gpio::INTERRUPT_RISING_EDGE);
|
this->pin_->attach_interrupt(PulseMeterSensor::edge_intr, this, gpio::INTERRUPT_RISING_EDGE);
|
||||||
} else if (this->filter_mode_ == FILTER_PULSE) {
|
} else if (this->filter_mode_ == FILTER_PULSE) {
|
||||||
|
@ -38,12 +41,16 @@ void PulseMeterSensor::loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to detect at least two edges to have a valid pulse width
|
// We need to detect at least two edges to have a valid pulse width
|
||||||
if (!this->initialized_) {
|
switch (this->meter_state_) {
|
||||||
this->initialized_ = true;
|
case MeterState::INITIAL:
|
||||||
} else {
|
case MeterState::TIMED_OUT: {
|
||||||
|
this->meter_state_ = MeterState::RUNNING;
|
||||||
|
} break;
|
||||||
|
case MeterState::RUNNING: {
|
||||||
uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_;
|
uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_;
|
||||||
float pulse_width_us = delta_us / float(this->get_->count_);
|
float pulse_width_us = delta_us / float(this->get_->count_);
|
||||||
this->publish_state((60.0f * 1000000.0f) / pulse_width_us);
|
this->publish_state((60.0f * 1000000.0f) / pulse_width_us);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->last_processed_edge_us_ = this->get_->last_detected_edge_us_;
|
this->last_processed_edge_us_ = this->get_->last_detected_edge_us_;
|
||||||
|
@ -53,11 +60,19 @@ void PulseMeterSensor::loop() {
|
||||||
const uint32_t now = micros();
|
const uint32_t now = micros();
|
||||||
const uint32_t time_since_valid_edge_us = now - this->last_processed_edge_us_;
|
const uint32_t time_since_valid_edge_us = now - this->last_processed_edge_us_;
|
||||||
|
|
||||||
if (this->initialized_ && time_since_valid_edge_us > this->timeout_us_) {
|
switch (this->meter_state_) {
|
||||||
|
// Running and initial states can timeout
|
||||||
|
case MeterState::INITIAL:
|
||||||
|
case MeterState::RUNNING: {
|
||||||
|
if (time_since_valid_edge_us > this->timeout_us_) {
|
||||||
|
this->meter_state_ = MeterState::TIMED_OUT;
|
||||||
ESP_LOGD(TAG, "No pulse detected for %us, assuming 0 pulses/min", time_since_valid_edge_us / 1000000);
|
ESP_LOGD(TAG, "No pulse detected for %us, assuming 0 pulses/min", time_since_valid_edge_us / 1000000);
|
||||||
this->initialized_ = false;
|
|
||||||
this->publish_state(0.0f);
|
this->publish_state(0.0f);
|
||||||
}
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ class PulseMeterSensor : public sensor::Sensor, public Component {
|
||||||
InternalFilterMode filter_mode_{FILTER_EDGE};
|
InternalFilterMode filter_mode_{FILTER_EDGE};
|
||||||
|
|
||||||
// Variables used in the loop
|
// Variables used in the loop
|
||||||
bool initialized_ = false;
|
enum class MeterState { INITIAL, RUNNING, TIMED_OUT };
|
||||||
|
MeterState meter_state_ = MeterState::INITIAL;
|
||||||
uint32_t total_pulses_ = 0;
|
uint32_t total_pulses_ = 0;
|
||||||
uint32_t last_processed_edge_us_ = 0;
|
uint32_t last_processed_edge_us_ = 0;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ static const char *const TAG = "radon_eye_ble";
|
||||||
|
|
||||||
bool RadonEyeListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
|
bool RadonEyeListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
|
||||||
if (not device.get_name().empty()) {
|
if (not device.get_name().empty()) {
|
||||||
if (device.get_name().rfind("FR:R20:SN", 0) == 0) {
|
if (device.get_name().rfind("FR:R", 0) == 0) {
|
||||||
// This is an RD200, I think
|
// This is an RD200, I think
|
||||||
ESP_LOGD(TAG, "Found Radon Eye RD200 device Name: %s (MAC: %s)", device.get_name().c_str(),
|
ESP_LOGD(TAG, "Found Radon Eye RD200 device Name: %s (MAC: %s)", device.get_name().c_str(),
|
||||||
device.address_str().c_str());
|
device.address_str().c_str());
|
||||||
|
|
|
@ -57,6 +57,10 @@ KNOWN_FIRMWARE = {
|
||||||
"https://github.com/jamesturton/shelly-dimmer-stm32/releases/download/v51.6/shelly-dimmer-stm32_v51.6.bin",
|
"https://github.com/jamesturton/shelly-dimmer-stm32/releases/download/v51.6/shelly-dimmer-stm32_v51.6.bin",
|
||||||
"eda483e111c914723a33f5088f1397d5c0b19333db4a88dc965636b976c16c36",
|
"eda483e111c914723a33f5088f1397d5c0b19333db4a88dc965636b976c16c36",
|
||||||
),
|
),
|
||||||
|
"51.7": (
|
||||||
|
"https://github.com/jamesturton/shelly-dimmer-stm32/releases/download/v51.7/shelly-dimmer-stm32_v51.7.bin",
|
||||||
|
"7a20f1c967c469917368a79bc56498009045237080408cef7190743e08031889",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -986,6 +986,7 @@ void ThermostatClimate::change_preset_(climate::ClimatePreset preset) {
|
||||||
// Fire any preset changed trigger if defined
|
// Fire any preset changed trigger if defined
|
||||||
Trigger<> *trig = this->preset_change_trigger_;
|
Trigger<> *trig = this->preset_change_trigger_;
|
||||||
assert(trig != nullptr);
|
assert(trig != nullptr);
|
||||||
|
this->preset = preset;
|
||||||
trig->trigger();
|
trig->trigger();
|
||||||
|
|
||||||
this->refresh();
|
this->refresh();
|
||||||
|
@ -1010,6 +1011,7 @@ void ThermostatClimate::change_custom_preset_(const std::string &custom_preset)
|
||||||
// Fire any preset changed trigger if defined
|
// Fire any preset changed trigger if defined
|
||||||
Trigger<> *trig = this->preset_change_trigger_;
|
Trigger<> *trig = this->preset_change_trigger_;
|
||||||
assert(trig != nullptr);
|
assert(trig != nullptr);
|
||||||
|
this->custom_preset = custom_preset;
|
||||||
trig->trigger();
|
trig->trigger();
|
||||||
|
|
||||||
this->refresh();
|
this->refresh();
|
||||||
|
|
|
@ -1561,6 +1561,23 @@ void WaveshareEPaper7P5In::dump_config() {
|
||||||
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
bool WaveshareEPaper7P5InV2::wait_until_idle_() {
|
||||||
|
if (this->busy_pin_ == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t start = millis();
|
||||||
|
while (this->busy_pin_->digital_read()) {
|
||||||
|
this->command(0x71);
|
||||||
|
if (millis() - start > this->idle_timeout_()) {
|
||||||
|
ESP_LOGE(TAG, "Timeout while displaying image!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
App.feed_wdt();
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
void WaveshareEPaper7P5InV2::initialize() {
|
void WaveshareEPaper7P5InV2::initialize() {
|
||||||
// COMMAND POWER SETTING
|
// COMMAND POWER SETTING
|
||||||
this->command(0x01);
|
this->command(0x01);
|
||||||
|
@ -1568,10 +1585,21 @@ void WaveshareEPaper7P5InV2::initialize() {
|
||||||
this->data(0x07);
|
this->data(0x07);
|
||||||
this->data(0x3f);
|
this->data(0x3f);
|
||||||
this->data(0x3f);
|
this->data(0x3f);
|
||||||
this->command(0x04);
|
|
||||||
|
// We don't want the display to be powered at this point
|
||||||
|
|
||||||
delay(100); // NOLINT
|
delay(100); // NOLINT
|
||||||
this->wait_until_idle_();
|
this->wait_until_idle_();
|
||||||
|
|
||||||
|
// COMMAND VCOM AND DATA INTERVAL SETTING
|
||||||
|
this->command(0x50);
|
||||||
|
this->data(0x10);
|
||||||
|
this->data(0x07);
|
||||||
|
|
||||||
|
// COMMAND TCON SETTING
|
||||||
|
this->command(0x60);
|
||||||
|
this->data(0x22);
|
||||||
|
|
||||||
// COMMAND PANEL SETTING
|
// COMMAND PANEL SETTING
|
||||||
this->command(0x00);
|
this->command(0x00);
|
||||||
this->data(0x1F);
|
this->data(0x1F);
|
||||||
|
@ -1582,19 +1610,30 @@ void WaveshareEPaper7P5InV2::initialize() {
|
||||||
this->data(0x20);
|
this->data(0x20);
|
||||||
this->data(0x01);
|
this->data(0x01);
|
||||||
this->data(0xE0);
|
this->data(0xE0);
|
||||||
// COMMAND ...?
|
|
||||||
|
// COMMAND DUAL SPI MM_EN, DUSPI_EN
|
||||||
this->command(0x15);
|
this->command(0x15);
|
||||||
this->data(0x00);
|
this->data(0x00);
|
||||||
// COMMAND VCOM AND DATA INTERVAL SETTING
|
|
||||||
this->command(0x50);
|
// COMMAND POWER DRIVER HAT DOWN
|
||||||
this->data(0x10);
|
// This command will turn off booster, controller, source driver, gate driver, VCOM, and
|
||||||
this->data(0x07);
|
// temperature sensor, but register data will be kept until VDD turned OFF or Deep Sleep Mode.
|
||||||
// COMMAND TCON SETTING
|
// Source/Gate/Border/VCOM will be released to floating.
|
||||||
this->command(0x60);
|
this->command(0x02);
|
||||||
this->data(0x22);
|
|
||||||
}
|
}
|
||||||
void HOT WaveshareEPaper7P5InV2::display() {
|
void HOT WaveshareEPaper7P5InV2::display() {
|
||||||
uint32_t buf_len = this->get_buffer_length_();
|
uint32_t buf_len = this->get_buffer_length_();
|
||||||
|
|
||||||
|
// COMMAND POWER ON
|
||||||
|
ESP_LOGI(TAG, "Power on the display and hat");
|
||||||
|
|
||||||
|
// This command will turn on booster, controller, regulators, and temperature sensor will be
|
||||||
|
// activated for one-time sensing before enabling booster. When all voltages are ready, the
|
||||||
|
// BUSY_N signal will return to high.
|
||||||
|
this->command(0x04);
|
||||||
|
delay(200); // NOLINT
|
||||||
|
this->wait_until_idle_();
|
||||||
|
|
||||||
// COMMAND DATA START TRANSMISSION NEW DATA
|
// COMMAND DATA START TRANSMISSION NEW DATA
|
||||||
this->command(0x13);
|
this->command(0x13);
|
||||||
delay(2);
|
delay(2);
|
||||||
|
@ -1602,14 +1641,23 @@ void HOT WaveshareEPaper7P5InV2::display() {
|
||||||
this->data(~(this->buffer_[i]));
|
this->data(~(this->buffer_[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay(100); // NOLINT
|
||||||
|
this->wait_until_idle_();
|
||||||
|
|
||||||
// COMMAND DISPLAY REFRESH
|
// COMMAND DISPLAY REFRESH
|
||||||
this->command(0x12);
|
this->command(0x12);
|
||||||
delay(100); // NOLINT
|
delay(100); // NOLINT
|
||||||
this->wait_until_idle_();
|
this->wait_until_idle_();
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "Before command(0x02) (>> power off)");
|
||||||
|
this->command(0x02);
|
||||||
|
this->wait_until_idle_();
|
||||||
|
ESP_LOGV(TAG, "After command(0x02) (>> power off)");
|
||||||
}
|
}
|
||||||
|
|
||||||
int WaveshareEPaper7P5InV2::get_width_internal() { return 800; }
|
int WaveshareEPaper7P5InV2::get_width_internal() { return 800; }
|
||||||
int WaveshareEPaper7P5InV2::get_height_internal() { return 480; }
|
int WaveshareEPaper7P5InV2::get_height_internal() { return 480; }
|
||||||
|
uint32_t WaveshareEPaper7P5InV2::idle_timeout_() { return 10000; }
|
||||||
void WaveshareEPaper7P5InV2::dump_config() {
|
void WaveshareEPaper7P5InV2::dump_config() {
|
||||||
LOG_DISPLAY("", "Waveshare E-Paper", this);
|
LOG_DISPLAY("", "Waveshare E-Paper", this);
|
||||||
ESP_LOGCONFIG(TAG, " Model: 7.5inV2rev2");
|
ESP_LOGCONFIG(TAG, " Model: 7.5inV2rev2");
|
||||||
|
|
|
@ -472,6 +472,8 @@ class WaveshareEPaper7P5InBC : public WaveshareEPaper {
|
||||||
|
|
||||||
class WaveshareEPaper7P5InV2 : public WaveshareEPaper {
|
class WaveshareEPaper7P5InV2 : public WaveshareEPaper {
|
||||||
public:
|
public:
|
||||||
|
bool wait_until_idle_();
|
||||||
|
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
|
|
||||||
void display() override;
|
void display() override;
|
||||||
|
@ -491,6 +493,8 @@ class WaveshareEPaper7P5InV2 : public WaveshareEPaper {
|
||||||
int get_width_internal() override;
|
int get_width_internal() override;
|
||||||
|
|
||||||
int get_height_internal() override;
|
int get_height_internal() override;
|
||||||
|
|
||||||
|
uint32_t idle_timeout_() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaveshareEPaper7P5InV2alt : public WaveshareEPaper7P5InV2 {
|
class WaveshareEPaper7P5InV2alt : public WaveshareEPaper7P5InV2 {
|
||||||
|
|
|
@ -59,7 +59,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(WebServer),
|
cv.GenerateID(): cv.declare_id(WebServer),
|
||||||
cv.Optional(CONF_PORT, default=80): cv.port,
|
cv.Optional(CONF_PORT, default=80): cv.port,
|
||||||
cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2),
|
cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2, int=True),
|
||||||
cv.Optional(CONF_CSS_URL): cv.string,
|
cv.Optional(CONF_CSS_URL): cv.string,
|
||||||
cv.Optional(CONF_CSS_INCLUDE): cv.file_,
|
cv.Optional(CONF_CSS_INCLUDE): cv.file_,
|
||||||
cv.Optional(CONF_JS_URL): cv.string,
|
cv.Optional(CONF_JS_URL): cv.string,
|
||||||
|
|
|
@ -98,6 +98,7 @@ bool WiFiComponent::wifi_apply_power_save_() {
|
||||||
power_save = NONE_SLEEP_T;
|
power_save = NONE_SLEEP_T;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
wifi_fpm_auto_sleep_set_in_null_mode(1);
|
||||||
return wifi_set_sleep_type(power_save);
|
return wifi_set_sleep_type(power_save);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2023.9.0b1"
|
__version__ = "2023.9.0b2"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||||
|
|
|
@ -57,7 +57,7 @@ class SimpleRegistry(dict):
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def safe_print(message=""):
|
def safe_print(message="", end="\n"):
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
|
|
||||||
if CORE.dashboard:
|
if CORE.dashboard:
|
||||||
|
@ -67,20 +67,26 @@ def safe_print(message=""):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print(message)
|
print(message, end=end)
|
||||||
return
|
return
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print(message.encode("utf-8", "backslashreplace"))
|
print(message.encode("utf-8", "backslashreplace"), end=end)
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
try:
|
try:
|
||||||
print(message.encode("ascii", "backslashreplace"))
|
print(message.encode("ascii", "backslashreplace"), end=end)
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
print("Cannot print line because of invalid locale!")
|
print("Cannot print line because of invalid locale!")
|
||||||
|
|
||||||
|
|
||||||
|
def safe_input(prompt=""):
|
||||||
|
if prompt:
|
||||||
|
safe_print(prompt, end="")
|
||||||
|
return input()
|
||||||
|
|
||||||
|
|
||||||
def shlex_quote(s):
|
def shlex_quote(s):
|
||||||
if not s:
|
if not s:
|
||||||
return "''"
|
return "''"
|
||||||
|
|
|
@ -11,7 +11,7 @@ from esphome.core import CORE
|
||||||
from esphome.helpers import get_bool_env, write_file
|
from esphome.helpers import get_bool_env, write_file
|
||||||
from esphome.log import Fore, color
|
from esphome.log import Fore, color
|
||||||
from esphome.storage_json import StorageJSON, ext_storage_path
|
from esphome.storage_json import StorageJSON, ext_storage_path
|
||||||
from esphome.util import safe_print
|
from esphome.util import safe_input, safe_print
|
||||||
|
|
||||||
CORE_BIG = r""" _____ ____ _____ ______
|
CORE_BIG = r""" _____ ____ _____ ______
|
||||||
/ ____/ __ \| __ \| ____|
|
/ ____/ __ \| __ \| ____|
|
||||||
|
@ -252,7 +252,7 @@ def safe_print_step(step, big):
|
||||||
def default_input(text, default):
|
def default_input(text, default):
|
||||||
safe_print()
|
safe_print()
|
||||||
safe_print(f"Press ENTER for default ({default})")
|
safe_print(f"Press ENTER for default ({default})")
|
||||||
return input(text.format(default)) or default
|
return safe_input(text.format(default)) or default
|
||||||
|
|
||||||
|
|
||||||
# From https://stackoverflow.com/a/518232/8924614
|
# From https://stackoverflow.com/a/518232/8924614
|
||||||
|
@ -306,7 +306,7 @@ def wizard(path):
|
||||||
)
|
)
|
||||||
safe_print()
|
safe_print()
|
||||||
sleep(1)
|
sleep(1)
|
||||||
name = input(color(Fore.BOLD_WHITE, "(name): "))
|
name = safe_input(color(Fore.BOLD_WHITE, "(name): "))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
@ -343,7 +343,9 @@ def wizard(path):
|
||||||
while True:
|
while True:
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
safe_print()
|
safe_print()
|
||||||
platform = input(color(Fore.BOLD_WHITE, f"({'/'.join(wizard_platforms)}): "))
|
platform = safe_input(
|
||||||
|
color(Fore.BOLD_WHITE, f"({'/'.join(wizard_platforms)}): ")
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
platform = vol.All(vol.Upper, vol.Any(*wizard_platforms))(platform.upper())
|
platform = vol.All(vol.Upper, vol.Any(*wizard_platforms))(platform.upper())
|
||||||
break
|
break
|
||||||
|
@ -397,7 +399,7 @@ def wizard(path):
|
||||||
boards.append(board_id)
|
boards.append(board_id)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
board = input(color(Fore.BOLD_WHITE, "(board): "))
|
board = safe_input(color(Fore.BOLD_WHITE, "(board): "))
|
||||||
try:
|
try:
|
||||||
board = vol.All(vol.Lower, vol.Any(*boards))(board)
|
board = vol.All(vol.Lower, vol.Any(*boards))(board)
|
||||||
break
|
break
|
||||||
|
@ -423,7 +425,7 @@ def wizard(path):
|
||||||
sleep(1.5)
|
sleep(1.5)
|
||||||
safe_print(f"For example \"{color(Fore.BOLD_WHITE, 'Abraham Linksys')}\".")
|
safe_print(f"For example \"{color(Fore.BOLD_WHITE, 'Abraham Linksys')}\".")
|
||||||
while True:
|
while True:
|
||||||
ssid = input(color(Fore.BOLD_WHITE, "(ssid): "))
|
ssid = safe_input(color(Fore.BOLD_WHITE, "(ssid): "))
|
||||||
try:
|
try:
|
||||||
ssid = cv.ssid(ssid)
|
ssid = cv.ssid(ssid)
|
||||||
break
|
break
|
||||||
|
@ -449,7 +451,7 @@ def wizard(path):
|
||||||
safe_print()
|
safe_print()
|
||||||
safe_print(f"For example \"{color(Fore.BOLD_WHITE, 'PASSWORD42')}\"")
|
safe_print(f"For example \"{color(Fore.BOLD_WHITE, 'PASSWORD42')}\"")
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
psk = input(color(Fore.BOLD_WHITE, "(PSK): "))
|
psk = safe_input(color(Fore.BOLD_WHITE, "(PSK): "))
|
||||||
safe_print(
|
safe_print(
|
||||||
"Perfect! WiFi is now set up (you can create static IPs and so on later)."
|
"Perfect! WiFi is now set up (you can create static IPs and so on later)."
|
||||||
)
|
)
|
||||||
|
@ -466,7 +468,7 @@ def wizard(path):
|
||||||
safe_print()
|
safe_print()
|
||||||
sleep(0.25)
|
sleep(0.25)
|
||||||
safe_print("Press ENTER for no password")
|
safe_print("Press ENTER for no password")
|
||||||
password = input(color(Fore.BOLD_WHITE, "(password): "))
|
password = safe_input(color(Fore.BOLD_WHITE, "(password): "))
|
||||||
|
|
||||||
if not wizard_write(
|
if not wizard_write(
|
||||||
path=path,
|
path=path,
|
||||||
|
|
|
@ -667,6 +667,7 @@ matrix_keypad:
|
||||||
- pin: 17
|
- pin: 17
|
||||||
- pin: 16
|
- pin: 16
|
||||||
keys: "1234"
|
keys: "1234"
|
||||||
|
has_pulldowns: true
|
||||||
|
|
||||||
key_collector:
|
key_collector:
|
||||||
- id: reader
|
- id: reader
|
||||||
|
|
|
@ -319,7 +319,7 @@ def test_wizard_accepts_default_answers_esp8266(tmpdir, monkeypatch, wizard_answ
|
||||||
config_file = tmpdir.join("test.yaml")
|
config_file = tmpdir.join("test.yaml")
|
||||||
input_mock = MagicMock(side_effect=wizard_answers)
|
input_mock = MagicMock(side_effect=wizard_answers)
|
||||||
monkeypatch.setattr("builtins.input", input_mock)
|
monkeypatch.setattr("builtins.input", input_mock)
|
||||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0)
|
||||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ def test_wizard_accepts_default_answers_esp32(tmpdir, monkeypatch, wizard_answer
|
||||||
config_file = tmpdir.join("test.yaml")
|
config_file = tmpdir.join("test.yaml")
|
||||||
input_mock = MagicMock(side_effect=wizard_answers)
|
input_mock = MagicMock(side_effect=wizard_answers)
|
||||||
monkeypatch.setattr("builtins.input", input_mock)
|
monkeypatch.setattr("builtins.input", input_mock)
|
||||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0)
|
||||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ def test_wizard_offers_better_node_name(tmpdir, monkeypatch, wizard_answers):
|
||||||
config_file = tmpdir.join("test.yaml")
|
config_file = tmpdir.join("test.yaml")
|
||||||
input_mock = MagicMock(side_effect=wizard_answers)
|
input_mock = MagicMock(side_effect=wizard_answers)
|
||||||
monkeypatch.setattr("builtins.input", input_mock)
|
monkeypatch.setattr("builtins.input", input_mock)
|
||||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0)
|
||||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ def test_wizard_requires_correct_platform(tmpdir, monkeypatch, wizard_answers):
|
||||||
config_file = tmpdir.join("test.yaml")
|
config_file = tmpdir.join("test.yaml")
|
||||||
input_mock = MagicMock(side_effect=wizard_answers)
|
input_mock = MagicMock(side_effect=wizard_answers)
|
||||||
monkeypatch.setattr("builtins.input", input_mock)
|
monkeypatch.setattr("builtins.input", input_mock)
|
||||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0)
|
||||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ def test_wizard_requires_correct_board(tmpdir, monkeypatch, wizard_answers):
|
||||||
config_file = tmpdir.join("test.yaml")
|
config_file = tmpdir.join("test.yaml")
|
||||||
input_mock = MagicMock(side_effect=wizard_answers)
|
input_mock = MagicMock(side_effect=wizard_answers)
|
||||||
monkeypatch.setattr("builtins.input", input_mock)
|
monkeypatch.setattr("builtins.input", input_mock)
|
||||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0)
|
||||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ def test_wizard_requires_valid_ssid(tmpdir, monkeypatch, wizard_answers):
|
||||||
config_file = tmpdir.join("test.yaml")
|
config_file = tmpdir.join("test.yaml")
|
||||||
input_mock = MagicMock(side_effect=wizard_answers)
|
input_mock = MagicMock(side_effect=wizard_answers)
|
||||||
monkeypatch.setattr("builtins.input", input_mock)
|
monkeypatch.setattr("builtins.input", input_mock)
|
||||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0)
|
||||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue