mirror of
https://github.com/esphome/esphome.git
synced 2025-11-15 06:15:47 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f27757039 | ||
|
|
532907219b | ||
|
|
eeaba74553 | ||
|
|
dd637582a4 | ||
|
|
b0d12aeea1 | ||
|
|
bdbd813455 | ||
|
|
a6fac2b175 | ||
|
|
5ce923ea90 | ||
|
|
29f0508dc2 | ||
|
|
3ffa59f0cd | ||
|
|
790d6ef94c | ||
|
|
7828f48b9a | ||
|
|
9fbb3659a6 | ||
|
|
fee446c28a | ||
|
|
1d56f0b035 | ||
|
|
341fddb9aa | ||
|
|
456824669f | ||
|
|
62f3039d82 | ||
|
|
be4c718859 | ||
|
|
c2f9ed7c59 | ||
|
|
bfac6607d1 | ||
|
|
e43dcded62 | ||
|
|
887081fd71 | ||
|
|
71ded24fce | ||
|
|
1e2a9e8348 | ||
|
|
64a3aa7092 | ||
|
|
fda8dd4ce3 | ||
|
|
1efabd27d8 | ||
|
|
caa651e55b |
@@ -60,6 +60,7 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
|
||||
auto chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
|
||||
if (chr == nullptr) {
|
||||
ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", this->get_name().c_str());
|
||||
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str());
|
||||
break;
|
||||
}
|
||||
this->char_handle_ = chr->handle;
|
||||
|
||||
@@ -312,8 +312,12 @@ void Climate::add_on_state_callback(std::function<void()> &&callback) {
|
||||
this->state_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
// Random 32bit value; If this changes existing restore preferences are invalidated
|
||||
static const uint32_t RESTORE_STATE_VERSION = 0x848EA6ADUL;
|
||||
|
||||
optional<ClimateDeviceRestoreState> Climate::restore_state_() {
|
||||
this->rtc_ = global_preferences.make_preference<ClimateDeviceRestoreState>(this->get_object_id_hash());
|
||||
this->rtc_ =
|
||||
global_preferences.make_preference<ClimateDeviceRestoreState>(this->get_object_id_hash() ^ RESTORE_STATE_VERSION);
|
||||
ClimateDeviceRestoreState recovered{};
|
||||
if (!this->rtc_.load(&recovered))
|
||||
return {};
|
||||
|
||||
@@ -120,6 +120,7 @@ class ClimateCall {
|
||||
};
|
||||
|
||||
/// Struct used to save the state of the climate device in restore memory.
|
||||
/// Make sure to update RESTORE_STATE_VERSION when changing the struct entries.
|
||||
struct ClimateDeviceRestoreState {
|
||||
ClimateMode mode;
|
||||
bool uses_custom_fan_mode{false};
|
||||
|
||||
@@ -31,7 +31,9 @@ DisplayPageShowPrevAction = display_ns.class_(
|
||||
DisplayIsDisplayingPageCondition = display_ns.class_(
|
||||
"DisplayIsDisplayingPageCondition", automation.Condition
|
||||
)
|
||||
DisplayOnPageChangeTrigger = display_ns.class_("DisplayOnPageChangeTrigger")
|
||||
DisplayOnPageChangeTrigger = display_ns.class_(
|
||||
"DisplayOnPageChangeTrigger", automation.Trigger
|
||||
)
|
||||
|
||||
CONF_ON_PAGE_CHANGE = "on_page_change"
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ void DutyCycleSensor::setup() {
|
||||
this->store_.pin = this->pin_->to_isr();
|
||||
this->store_.last_level = this->pin_->digital_read();
|
||||
this->last_update_ = micros();
|
||||
this->store_.last_interrupt = micros();
|
||||
|
||||
this->pin_->attach_interrupt(DutyCycleSensorStore::gpio_intr, &this->store_, CHANGE);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class DutyCycleSensor : public sensor::Sensor, public PollingComponent {
|
||||
protected:
|
||||
GPIOPin *pin_;
|
||||
|
||||
DutyCycleSensorStore store_;
|
||||
DutyCycleSensorStore store_{};
|
||||
uint32_t last_update_;
|
||||
};
|
||||
|
||||
|
||||
@@ -109,9 +109,9 @@ def _compute_destination_path(key: str) -> Path:
|
||||
return base_dir / h.hexdigest()[:8]
|
||||
|
||||
|
||||
def _run_git_command(cmd):
|
||||
def _run_git_command(cmd, cwd=None):
|
||||
try:
|
||||
ret = subprocess.run(cmd, capture_output=True, check=False)
|
||||
ret = subprocess.run(cmd, cwd=cwd, capture_output=True, check=False)
|
||||
except FileNotFoundError as err:
|
||||
raise cv.Invalid(
|
||||
"git is not installed but required for external_components.\n"
|
||||
@@ -147,18 +147,20 @@ def _process_git_config(config: dict, refresh) -> str:
|
||||
age = datetime.datetime.now() - datetime.datetime.fromtimestamp(
|
||||
file_timestamp.stat().st_mtime
|
||||
)
|
||||
if age.seconds > refresh.total_seconds:
|
||||
if age.total_seconds() > refresh.total_seconds:
|
||||
_LOGGER.info("Updating %s", key)
|
||||
_LOGGER.debug("Location: %s", repo_dir)
|
||||
# Stash local changes (if any)
|
||||
_run_git_command(["git", "stash", "push", "--include-untracked"])
|
||||
_run_git_command(
|
||||
["git", "stash", "push", "--include-untracked"], str(repo_dir)
|
||||
)
|
||||
# Fetch remote ref
|
||||
cmd = ["git", "fetch", "--", "origin"]
|
||||
if CONF_REF in config:
|
||||
cmd.append(config[CONF_REF])
|
||||
_run_git_command(cmd)
|
||||
_run_git_command(cmd, str(repo_dir))
|
||||
# Hard reset to FETCH_HEAD (short-lived git ref corresponding to most recent fetch)
|
||||
_run_git_command(["git", "reset", "--hard", "FETCH_HEAD"])
|
||||
_run_git_command(["git", "reset", "--hard", "FETCH_HEAD"], str(repo_dir))
|
||||
|
||||
if (repo_dir / "esphome" / "components").is_dir():
|
||||
components_dir = repo_dir / "esphome" / "components"
|
||||
|
||||
@@ -45,6 +45,7 @@ void HLW8012Component::dump_config() {
|
||||
LOG_SENSOR(" ", "Voltage", this->voltage_sensor_)
|
||||
LOG_SENSOR(" ", "Current", this->current_sensor_)
|
||||
LOG_SENSOR(" ", "Power", this->power_sensor_)
|
||||
LOG_SENSOR(" ", "Energy", this->energy_sensor_)
|
||||
}
|
||||
float HLW8012Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||
void HLW8012Component::update() {
|
||||
|
||||
@@ -100,7 +100,7 @@ bool MideaAC::allow_preset(climate::ClimatePreset preset) const {
|
||||
ESP_LOGD(TAG, "BOOST preset is only available in HEAT or COOL mode");
|
||||
}
|
||||
break;
|
||||
case climate::CLIMATE_PRESET_HOME:
|
||||
case climate::CLIMATE_PRESET_NONE:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
@@ -191,7 +191,7 @@ climate::ClimateTraits MideaAC::traits() {
|
||||
if (traits_swing_both_)
|
||||
traits.add_supported_swing_mode(climate::CLIMATE_SWING_BOTH);
|
||||
traits.set_supported_presets({
|
||||
climate::CLIMATE_PRESET_HOME,
|
||||
climate::CLIMATE_PRESET_NONE,
|
||||
});
|
||||
if (traits_preset_eco_)
|
||||
traits.add_supported_preset(climate::CLIMATE_PRESET_ECO);
|
||||
|
||||
@@ -86,18 +86,17 @@ void PropertiesFrame::set_mode(climate::ClimateMode mode) {
|
||||
}
|
||||
|
||||
optional<climate::ClimatePreset> PropertiesFrame::get_preset() const {
|
||||
if (this->get_eco_mode()) {
|
||||
if (this->get_eco_mode())
|
||||
return climate::CLIMATE_PRESET_ECO;
|
||||
} else if (this->get_sleep_mode()) {
|
||||
if (this->get_sleep_mode())
|
||||
return climate::CLIMATE_PRESET_SLEEP;
|
||||
} else if (this->get_turbo_mode()) {
|
||||
if (this->get_turbo_mode())
|
||||
return climate::CLIMATE_PRESET_BOOST;
|
||||
} else {
|
||||
return climate::CLIMATE_PRESET_HOME;
|
||||
}
|
||||
return climate::CLIMATE_PRESET_NONE;
|
||||
}
|
||||
|
||||
void PropertiesFrame::set_preset(climate::ClimatePreset preset) {
|
||||
this->clear_presets();
|
||||
switch (preset) {
|
||||
case climate::CLIMATE_PRESET_ECO:
|
||||
this->set_eco_mode(true);
|
||||
@@ -113,14 +112,21 @@ void PropertiesFrame::set_preset(climate::ClimatePreset preset) {
|
||||
}
|
||||
}
|
||||
|
||||
void PropertiesFrame::clear_presets() {
|
||||
this->set_eco_mode(false);
|
||||
this->set_sleep_mode(false);
|
||||
this->set_turbo_mode(false);
|
||||
this->set_freeze_protection_mode(false);
|
||||
}
|
||||
|
||||
bool PropertiesFrame::is_custom_preset() const { return this->get_freeze_protection_mode(); }
|
||||
|
||||
const std::string &PropertiesFrame::get_custom_preset() const { return midea_ac::MIDEA_FREEZE_PROTECTION_PRESET; };
|
||||
|
||||
void PropertiesFrame::set_custom_preset(const std::string &preset) {
|
||||
if (preset == MIDEA_FREEZE_PROTECTION_PRESET) {
|
||||
this->clear_presets();
|
||||
if (preset == MIDEA_FREEZE_PROTECTION_PRESET)
|
||||
this->set_freeze_protection_mode(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertiesFrame::is_custom_fan_mode() const {
|
||||
|
||||
@@ -115,6 +115,7 @@ class PropertiesFrame : public midea_dongle::BaseFrame {
|
||||
/* PRESET */
|
||||
optional<climate::ClimatePreset> get_preset() const;
|
||||
void set_preset(climate::ClimatePreset preset);
|
||||
void clear_presets();
|
||||
|
||||
bool is_custom_preset() const;
|
||||
const std::string &get_custom_preset() const;
|
||||
|
||||
@@ -72,7 +72,7 @@ void MQTTClimateComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryC
|
||||
root["act_t"] = this->get_action_state_topic();
|
||||
}
|
||||
|
||||
if (traits.get_supports_fan_modes()) {
|
||||
if (traits.get_supports_fan_modes() || !traits.get_supported_custom_fan_modes().empty()) {
|
||||
// fan_mode_command_topic
|
||||
root["fan_mode_cmd_t"] = this->get_fan_mode_command_topic();
|
||||
// fan_mode_state_topic
|
||||
|
||||
@@ -39,8 +39,8 @@ void MQTTNumberComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo
|
||||
// https://www.home-assistant.io/integrations/number.mqtt/
|
||||
if (!traits.get_icon().empty())
|
||||
root["icon"] = traits.get_icon();
|
||||
root["min_value"] = traits.get_min_value();
|
||||
root["max_value"] = traits.get_max_value();
|
||||
root["min"] = traits.get_min_value();
|
||||
root["max"] = traits.get_max_value();
|
||||
root["step"] = traits.get_step();
|
||||
|
||||
config.command_topic = true;
|
||||
|
||||
@@ -35,9 +35,9 @@ void PIDClimate::control(const climate::ClimateCall &call) {
|
||||
if (call.get_target_temperature().has_value())
|
||||
this->target_temperature = *call.get_target_temperature();
|
||||
|
||||
// If switching to non-auto mode, set output immediately
|
||||
if (this->mode != climate::CLIMATE_MODE_HEAT_COOL)
|
||||
this->handle_non_auto_mode_();
|
||||
// If switching to off mode, set output immediately
|
||||
if (this->mode == climate::CLIMATE_MODE_OFF)
|
||||
this->write_output_(0.0f);
|
||||
|
||||
this->publish_state();
|
||||
}
|
||||
@@ -98,15 +98,6 @@ void PIDClimate::write_output_(float value) {
|
||||
}
|
||||
this->pid_computed_callback_.call();
|
||||
}
|
||||
void PIDClimate::handle_non_auto_mode_() {
|
||||
// in non-auto mode, switch directly to appropriate action
|
||||
// - OFF mode -> Output at 0%
|
||||
if (this->mode == climate::CLIMATE_MODE_OFF) {
|
||||
this->write_output_(0.0);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
void PIDClimate::update_pid_() {
|
||||
float value;
|
||||
if (isnan(this->current_temperature) || isnan(this->target_temperature)) {
|
||||
@@ -135,7 +126,7 @@ void PIDClimate::update_pid_() {
|
||||
}
|
||||
|
||||
if (this->mode == climate::CLIMATE_MODE_OFF) {
|
||||
this->handle_non_auto_mode_();
|
||||
this->write_output_(0.0);
|
||||
} else {
|
||||
this->write_output_(value);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ class PIDClimate : public climate::Climate, public Component {
|
||||
bool supports_heat_() const { return this->heat_output_ != nullptr; }
|
||||
|
||||
void write_output_(float value);
|
||||
void handle_non_auto_mode_();
|
||||
|
||||
/// The sensor used for getting the current temperature
|
||||
sensor::Sensor *sensor_;
|
||||
|
||||
@@ -11,8 +11,8 @@ from esphome.const import (
|
||||
CONF_TOTAL,
|
||||
CONF_VALUE,
|
||||
ICON_PULSE,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_PULSES,
|
||||
UNIT_PULSES_PER_MINUTE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
@@ -59,7 +59,12 @@ CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
cv.Optional(CONF_INTERNAL_FILTER, default="13us"): validate_internal_filter,
|
||||
cv.Optional(CONF_TIMEOUT, default="5min"): validate_timeout,
|
||||
cv.Optional(CONF_TOTAL): sensor.sensor_schema(
|
||||
UNIT_PULSES, ICON_PULSE, 0, DEVICE_CLASS_EMPTY, STATE_CLASS_NONE
|
||||
UNIT_PULSES,
|
||||
ICON_PULSE,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -41,6 +41,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
||||
bool initialized_{false};
|
||||
std::vector<rmt_item32_t> rmt_temp_;
|
||||
esp_err_t error_code_{ESP_OK};
|
||||
bool inverted_{false};
|
||||
#endif
|
||||
uint8_t carrier_duty_percent_{50};
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace remote_transmitter {
|
||||
|
||||
static const char *const TAG = "remote_transmitter";
|
||||
|
||||
void RemoteTransmitterComponent::setup() {}
|
||||
void RemoteTransmitterComponent::setup() { this->configure_rmt(); }
|
||||
|
||||
void RemoteTransmitterComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Remote Transmitter...");
|
||||
@@ -50,6 +50,7 @@ void RemoteTransmitterComponent::configure_rmt() {
|
||||
} else {
|
||||
c.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
|
||||
c.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
|
||||
this->inverted_ = true;
|
||||
}
|
||||
|
||||
esp_err_t error = rmt_config(&c);
|
||||
@@ -95,10 +96,10 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
|
||||
val -= item;
|
||||
|
||||
if (rmt_i % 2 == 0) {
|
||||
rmt_item.level0 = static_cast<uint32_t>(level);
|
||||
rmt_item.level0 = static_cast<uint32_t>(level ^ this->inverted_);
|
||||
rmt_item.duration0 = static_cast<uint32_t>(item);
|
||||
} else {
|
||||
rmt_item.level1 = static_cast<uint32_t>(level);
|
||||
rmt_item.level1 = static_cast<uint32_t>(level ^ this->inverted_);
|
||||
rmt_item.duration1 = static_cast<uint32_t>(item);
|
||||
this->rmt_temp_.push_back(rmt_item);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ void CronTrigger::loop() {
|
||||
return;
|
||||
|
||||
if (this->last_check_.has_value()) {
|
||||
if (*this->last_check_ >= time) {
|
||||
if (*this->last_check_ > time && this->last_check_->timestamp - time.timestamp > 900) {
|
||||
// We went back in time (a lot), probably caused by time synchronization
|
||||
ESP_LOGW(TAG, "Time has jumped back!");
|
||||
} else if (*this->last_check_ >= time) {
|
||||
// already handled this one
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, time
|
||||
from esphome.const import CONF_ID, CONF_TIME_ID
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_TIME_ID,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
ICON_EMPTY,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_EMPTY,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["time"]
|
||||
|
||||
@@ -11,13 +19,24 @@ TotalDailyEnergy = total_daily_energy_ns.class_(
|
||||
"TotalDailyEnergy", sensor.Sensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(TotalDailyEnergy),
|
||||
cv.GenerateID(CONF_TIME_ID): cv.use_id(time.RealTimeClock),
|
||||
cv.Required(CONF_POWER_ID): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
UNIT_EMPTY,
|
||||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(TotalDailyEnergy),
|
||||
cv.GenerateID(CONF_TIME_ID): cv.use_id(time.RealTimeClock),
|
||||
cv.Required(CONF_POWER_ID): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
|
||||
@@ -7,10 +7,11 @@ namespace esphome {
|
||||
namespace tuya {
|
||||
|
||||
static const char *const TAG = "tuya";
|
||||
static const int COMMAND_DELAY = 50;
|
||||
static const int COMMAND_DELAY = 10;
|
||||
static const int RECEIVE_TIMEOUT = 300;
|
||||
|
||||
void Tuya::setup() {
|
||||
this->set_interval("heartbeat", 10000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); });
|
||||
this->set_interval("heartbeat", 15000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); });
|
||||
}
|
||||
|
||||
void Tuya::loop() {
|
||||
@@ -113,11 +114,19 @@ void Tuya::handle_char_(uint8_t c) {
|
||||
this->rx_message_.push_back(c);
|
||||
if (!this->validate_message_()) {
|
||||
this->rx_message_.clear();
|
||||
} else {
|
||||
this->last_rx_char_timestamp_ = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void Tuya::handle_command_(uint8_t command, uint8_t version, const uint8_t *buffer, size_t len) {
|
||||
switch ((TuyaCommandType) command) {
|
||||
TuyaCommandType command_type = (TuyaCommandType) command;
|
||||
|
||||
if (this->expected_response_.has_value() && this->expected_response_ == command_type) {
|
||||
this->expected_response_.reset();
|
||||
}
|
||||
|
||||
switch (command_type) {
|
||||
case TuyaCommandType::HEARTBEAT:
|
||||
ESP_LOGV(TAG, "MCU Heartbeat (0x%02X)", buffer[0]);
|
||||
this->protocol_version_ = version;
|
||||
@@ -316,6 +325,25 @@ void Tuya::send_raw_command_(TuyaCommand command) {
|
||||
uint8_t version = 0;
|
||||
|
||||
this->last_command_timestamp_ = millis();
|
||||
switch (command.cmd) {
|
||||
case TuyaCommandType::HEARTBEAT:
|
||||
this->expected_response_ = TuyaCommandType::HEARTBEAT;
|
||||
break;
|
||||
case TuyaCommandType::PRODUCT_QUERY:
|
||||
this->expected_response_ = TuyaCommandType::PRODUCT_QUERY;
|
||||
break;
|
||||
case TuyaCommandType::CONF_QUERY:
|
||||
this->expected_response_ = TuyaCommandType::CONF_QUERY;
|
||||
break;
|
||||
case TuyaCommandType::DATAPOINT_DELIVER:
|
||||
this->expected_response_ = TuyaCommandType::DATAPOINT_REPORT;
|
||||
break;
|
||||
case TuyaCommandType::DATAPOINT_QUERY:
|
||||
this->expected_response_ = TuyaCommandType::DATAPOINT_REPORT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Sending Tuya: CMD=0x%02X VERSION=%u DATA=[%s] INIT_STATE=%u", static_cast<uint8_t>(command.cmd),
|
||||
version, hexencode(command.payload).c_str(), static_cast<uint8_t>(this->init_state_));
|
||||
@@ -331,9 +359,20 @@ void Tuya::send_raw_command_(TuyaCommand command) {
|
||||
}
|
||||
|
||||
void Tuya::process_command_queue_() {
|
||||
uint32_t delay = millis() - this->last_command_timestamp_;
|
||||
uint32_t now = millis();
|
||||
uint32_t delay = now - this->last_command_timestamp_;
|
||||
|
||||
if (now - this->last_rx_char_timestamp_ > RECEIVE_TIMEOUT) {
|
||||
this->rx_message_.clear();
|
||||
}
|
||||
|
||||
if (this->expected_response_.has_value() && delay > RECEIVE_TIMEOUT) {
|
||||
this->expected_response_.reset();
|
||||
}
|
||||
|
||||
// Left check of delay since last command in case theres ever a command sent by calling send_raw_command_ directly
|
||||
if (delay > COMMAND_DELAY && !this->command_queue_.empty() && this->rx_message_.empty()) {
|
||||
if (delay > COMMAND_DELAY && !this->command_queue_.empty() && this->rx_message_.empty() &&
|
||||
!this->expected_response_.has_value()) {
|
||||
this->send_raw_command_(command_queue_.front());
|
||||
this->command_queue_.erase(command_queue_.begin());
|
||||
}
|
||||
@@ -345,7 +384,7 @@ void Tuya::send_command_(const TuyaCommand &command) {
|
||||
}
|
||||
|
||||
void Tuya::send_empty_command_(TuyaCommandType command) {
|
||||
send_command_(TuyaCommand{.cmd = command, .payload = std::vector<uint8_t>{0x04}});
|
||||
send_command_(TuyaCommand{.cmd = command, .payload = std::vector<uint8_t>{}});
|
||||
}
|
||||
|
||||
void Tuya::send_wifi_status_() {
|
||||
|
||||
@@ -107,12 +107,14 @@ class Tuya : public Component, public uart::UARTDevice {
|
||||
int gpio_status_ = -1;
|
||||
int gpio_reset_ = -1;
|
||||
uint32_t last_command_timestamp_ = 0;
|
||||
uint32_t last_rx_char_timestamp_ = 0;
|
||||
std::string product_ = "";
|
||||
std::vector<TuyaDatapointListener> listeners_;
|
||||
std::vector<TuyaDatapoint> datapoints_;
|
||||
std::vector<uint8_t> rx_message_;
|
||||
std::vector<uint8_t> ignore_mcu_update_on_datapoints_{};
|
||||
std::vector<TuyaCommand> command_queue_;
|
||||
optional<TuyaCommandType> expected_response_{};
|
||||
uint8_t wifi_status_ = -1;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Constants used by esphome."""
|
||||
|
||||
__version__ = "1.20.0"
|
||||
__version__ = "1.20.4"
|
||||
|
||||
ESP_PLATFORM_ESP32 = "ESP32"
|
||||
ESP_PLATFORM_ESP8266 = "ESP8266"
|
||||
|
||||
@@ -1104,7 +1104,7 @@ def shorthand_input_pullup_pin(value):
|
||||
|
||||
def shorthand_analog_pin(value):
|
||||
value = analog_pin(value)
|
||||
return GPIO_FULL_INPUT_PIN_SCHEMA({CONF_NUMBER: value})
|
||||
return GPIO_FULL_ANALOG_PIN_SCHEMA({CONF_NUMBER: value})
|
||||
|
||||
|
||||
def validate_has_interrupt(value):
|
||||
|
||||
@@ -11,4 +11,4 @@ ifaddr==0.1.7
|
||||
platformio==5.1.1
|
||||
esptool==2.8
|
||||
click==7.1.2
|
||||
esphome-dashboard==20210719.0
|
||||
esphome-dashboard==20210728.0
|
||||
|
||||
Reference in New Issue
Block a user