mirror of
https://github.com/esphome/esphome.git
synced 2025-11-07 10:31:49 +00:00
Compare commits
22 Commits
2021.11.0b
...
2021.11.0b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7279f1fcc1 | ||
|
|
d7432f7c10 | ||
|
|
b0a0a153f3 | ||
|
|
024632dbd0 | ||
|
|
0a545a28b9 | ||
|
|
0f2df59998 | ||
|
|
29a7d32f77 | ||
|
|
687a7e9b2f | ||
|
|
09e8782318 | ||
|
|
f2aea02210 | ||
|
|
194f922312 | ||
|
|
fea3c48098 | ||
|
|
c2f57baec2 | ||
|
|
f4a140e126 | ||
|
|
ab506b09fe | ||
|
|
87e1cdeedb | ||
|
|
81a36146ef | ||
|
|
7fa4a68a27 | ||
|
|
f1c5e2ef81 | ||
|
|
b526155cce | ||
|
|
62c3f301e7 | ||
|
|
38cb988809 |
@@ -44,10 +44,11 @@ from esphome.const import (
|
|||||||
DEVICE_CLASS_POWER,
|
DEVICE_CLASS_POWER,
|
||||||
DEVICE_CLASS_PRESENCE,
|
DEVICE_CLASS_PRESENCE,
|
||||||
DEVICE_CLASS_PROBLEM,
|
DEVICE_CLASS_PROBLEM,
|
||||||
|
DEVICE_CLASS_RUNNING,
|
||||||
DEVICE_CLASS_SAFETY,
|
DEVICE_CLASS_SAFETY,
|
||||||
DEVICE_CLASS_SMOKE,
|
DEVICE_CLASS_SMOKE,
|
||||||
DEVICE_CLASS_SOUND,
|
DEVICE_CLASS_SOUND,
|
||||||
DEVICE_CLASS_UPDATE,
|
DEVICE_CLASS_TAMPER,
|
||||||
DEVICE_CLASS_VIBRATION,
|
DEVICE_CLASS_VIBRATION,
|
||||||
DEVICE_CLASS_WINDOW,
|
DEVICE_CLASS_WINDOW,
|
||||||
)
|
)
|
||||||
@@ -76,10 +77,11 @@ DEVICE_CLASSES = [
|
|||||||
DEVICE_CLASS_POWER,
|
DEVICE_CLASS_POWER,
|
||||||
DEVICE_CLASS_PRESENCE,
|
DEVICE_CLASS_PRESENCE,
|
||||||
DEVICE_CLASS_PROBLEM,
|
DEVICE_CLASS_PROBLEM,
|
||||||
|
DEVICE_CLASS_RUNNING,
|
||||||
DEVICE_CLASS_SAFETY,
|
DEVICE_CLASS_SAFETY,
|
||||||
DEVICE_CLASS_SMOKE,
|
DEVICE_CLASS_SMOKE,
|
||||||
DEVICE_CLASS_SOUND,
|
DEVICE_CLASS_SOUND,
|
||||||
DEVICE_CLASS_UPDATE,
|
DEVICE_CLASS_TAMPER,
|
||||||
DEVICE_CLASS_VIBRATION,
|
DEVICE_CLASS_VIBRATION,
|
||||||
DEVICE_CLASS_WINDOW,
|
DEVICE_CLASS_WINDOW,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace esphome {
|
|||||||
namespace esp32_improv {
|
namespace esp32_improv {
|
||||||
|
|
||||||
static const char *const TAG = "esp32_improv.component";
|
static const char *const TAG = "esp32_improv.component";
|
||||||
|
static const char *const ESPHOME_MY_LINK = "https://my.home-assistant.io/redirect/config_flow_start?domain=esphome";
|
||||||
|
|
||||||
ESP32ImprovComponent::ESP32ImprovComponent() { global_improv_component = this; }
|
ESP32ImprovComponent::ESP32ImprovComponent() { global_improv_component = this; }
|
||||||
|
|
||||||
@@ -124,8 +125,13 @@ void ESP32ImprovComponent::loop() {
|
|||||||
this->cancel_timeout("wifi-connect-timeout");
|
this->cancel_timeout("wifi-connect-timeout");
|
||||||
this->set_state_(improv::STATE_PROVISIONED);
|
this->set_state_(improv::STATE_PROVISIONED);
|
||||||
|
|
||||||
std::string url = "https://my.home-assistant.io/redirect/config_flow_start?domain=esphome";
|
std::vector<std::string> urls = {ESPHOME_MY_LINK};
|
||||||
std::vector<uint8_t> data = improv::build_rpc_response(improv::WIFI_SETTINGS, {url});
|
#ifdef USE_WEBSERVER
|
||||||
|
auto ip = wifi::global_wifi_component->wifi_sta_ip();
|
||||||
|
std::string webserver_url = "http://" + ip.str() + ":" + to_string(WEBSERVER_PORT);
|
||||||
|
urls.push_back(webserver_url);
|
||||||
|
#endif
|
||||||
|
std::vector<uint8_t> data = improv::build_rpc_response(improv::WIFI_SETTINGS, urls);
|
||||||
this->send_response_(data);
|
this->send_response_(data);
|
||||||
this->set_timeout("end-service", 1000, [this] {
|
this->set_timeout("end-service", 1000, [this] {
|
||||||
this->service_->stop();
|
this->service_->stop();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
#include "esp32_touch.h"
|
#include "esp32_touch.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
@@ -93,7 +94,6 @@ void ESP32TouchComponent::dump_config() {
|
|||||||
|
|
||||||
if (this->iir_filter_enabled_()) {
|
if (this->iir_filter_enabled_()) {
|
||||||
ESP_LOGCONFIG(TAG, " IIR Filter: %ums", this->iir_filter_);
|
ESP_LOGCONFIG(TAG, " IIR Filter: %ums", this->iir_filter_);
|
||||||
touch_pad_filter_start(this->iir_filter_);
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGCONFIG(TAG, " IIR Filter DISABLED");
|
ESP_LOGCONFIG(TAG, " IIR Filter DISABLED");
|
||||||
}
|
}
|
||||||
@@ -125,6 +125,8 @@ void ESP32TouchComponent::loop() {
|
|||||||
if (should_print) {
|
if (should_print) {
|
||||||
ESP_LOGD(TAG, "Touch Pad '%s' (T%u): %u", child->get_name().c_str(), child->get_touch_pad(), value);
|
ESP_LOGD(TAG, "Touch Pad '%s' (T%u): %u", child->get_name().c_str(), child->get_touch_pad(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App.feed_wdt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_print) {
|
if (should_print) {
|
||||||
|
|||||||
@@ -2,30 +2,32 @@
|
|||||||
|
|
||||||
namespace improv {
|
namespace improv {
|
||||||
|
|
||||||
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data) {
|
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data, bool check_checksum) {
|
||||||
return parse_improv_data(data.data(), data.size());
|
return parse_improv_data(data.data(), data.size(), check_checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImprovCommand parse_improv_data(const uint8_t *data, size_t length) {
|
ImprovCommand parse_improv_data(const uint8_t *data, size_t length, bool check_checksum) {
|
||||||
ImprovCommand improv_command;
|
ImprovCommand improv_command;
|
||||||
Command command = (Command) data[0];
|
Command command = (Command) data[0];
|
||||||
uint8_t data_length = data[1];
|
uint8_t data_length = data[1];
|
||||||
|
|
||||||
if (data_length != length - 3) {
|
if (data_length != length - 2 - check_checksum) {
|
||||||
improv_command.command = UNKNOWN;
|
improv_command.command = UNKNOWN;
|
||||||
return improv_command;
|
return improv_command;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t checksum = data[length - 1];
|
if (check_checksum) {
|
||||||
|
uint8_t checksum = data[length - 1];
|
||||||
|
|
||||||
uint32_t calculated_checksum = 0;
|
uint32_t calculated_checksum = 0;
|
||||||
for (uint8_t i = 0; i < length - 1; i++) {
|
for (uint8_t i = 0; i < length - 1; i++) {
|
||||||
calculated_checksum += data[i];
|
calculated_checksum += data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint8_t) calculated_checksum != checksum) {
|
if ((uint8_t) calculated_checksum != checksum) {
|
||||||
improv_command.command = BAD_CHECKSUM;
|
improv_command.command = BAD_CHECKSUM;
|
||||||
return improv_command;
|
return improv_command;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == WIFI_SETTINGS) {
|
if (command == WIFI_SETTINGS) {
|
||||||
@@ -46,7 +48,7 @@ ImprovCommand parse_improv_data(const uint8_t *data, size_t length) {
|
|||||||
return improv_command;
|
return improv_command;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::string> &datum) {
|
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::string> &datum, bool add_checksum) {
|
||||||
std::vector<uint8_t> out;
|
std::vector<uint8_t> out;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
out.push_back(command);
|
out.push_back(command);
|
||||||
@@ -58,17 +60,19 @@ std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::
|
|||||||
}
|
}
|
||||||
out.insert(out.begin() + 1, length);
|
out.insert(out.begin() + 1, length);
|
||||||
|
|
||||||
uint32_t calculated_checksum = 0;
|
if (add_checksum) {
|
||||||
|
uint32_t calculated_checksum = 0;
|
||||||
|
|
||||||
for (uint8_t byte : out) {
|
for (uint8_t byte : out) {
|
||||||
calculated_checksum += byte;
|
calculated_checksum += byte;
|
||||||
|
}
|
||||||
|
out.push_back(calculated_checksum);
|
||||||
}
|
}
|
||||||
out.push_back(calculated_checksum);
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ARDUINO
|
#ifdef ARDUINO
|
||||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<String> &datum) {
|
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<String> &datum, bool add_checksum) {
|
||||||
std::vector<uint8_t> out;
|
std::vector<uint8_t> out;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
out.push_back(command);
|
out.push_back(command);
|
||||||
@@ -80,14 +84,16 @@ std::vector<uint8_t> build_rpc_response(Command command, const std::vector<Strin
|
|||||||
}
|
}
|
||||||
out.insert(out.begin() + 1, length);
|
out.insert(out.begin() + 1, length);
|
||||||
|
|
||||||
uint32_t calculated_checksum = 0;
|
if (add_checksum) {
|
||||||
|
uint32_t calculated_checksum = 0;
|
||||||
|
|
||||||
for (uint8_t byte : out) {
|
for (uint8_t byte : out) {
|
||||||
calculated_checksum += byte;
|
calculated_checksum += byte;
|
||||||
|
}
|
||||||
|
out.push_back(calculated_checksum);
|
||||||
}
|
}
|
||||||
out.push_back(calculated_checksum);
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
#endif // USE_ARDUINO
|
#endif // ARDUINO
|
||||||
|
|
||||||
} // namespace improv
|
} // namespace improv
|
||||||
|
|||||||
@@ -51,12 +51,13 @@ struct ImprovCommand {
|
|||||||
std::string password;
|
std::string password;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data);
|
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data, bool check_checksum = true);
|
||||||
ImprovCommand parse_improv_data(const uint8_t *data, size_t length);
|
ImprovCommand parse_improv_data(const uint8_t *data, size_t length, bool check_checksum = true);
|
||||||
|
|
||||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::string> &datum);
|
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::string> &datum,
|
||||||
|
bool add_checksum = true);
|
||||||
#ifdef ARDUINO
|
#ifdef ARDUINO
|
||||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<String> &datum);
|
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<String> &datum, bool add_checksum = true);
|
||||||
#endif // ARDUINO
|
#endif // ARDUINO
|
||||||
|
|
||||||
} // namespace improv
|
} // namespace improv
|
||||||
|
|||||||
@@ -92,20 +92,19 @@ void ImprovSerialComponent::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> ImprovSerialComponent::build_rpc_settings_response_(improv::Command command) {
|
std::vector<uint8_t> ImprovSerialComponent::build_rpc_settings_response_(improv::Command command) {
|
||||||
std::string url = "https://my.home-assistant.io/redirect/config_flow_start?domain=esphome";
|
std::vector<std::string> urls;
|
||||||
std::vector<std::string> urls = {url};
|
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
auto ip = wifi::global_wifi_component->wifi_sta_ip();
|
auto ip = wifi::global_wifi_component->wifi_sta_ip();
|
||||||
std::string webserver_url = "http://" + ip.str() + ":" + to_string(WEBSERVER_PORT);
|
std::string webserver_url = "http://" + ip.str() + ":" + to_string(WEBSERVER_PORT);
|
||||||
urls.push_back(webserver_url);
|
urls.push_back(webserver_url);
|
||||||
#endif
|
#endif
|
||||||
std::vector<uint8_t> data = improv::build_rpc_response(command, urls);
|
std::vector<uint8_t> data = improv::build_rpc_response(command, urls, false);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> ImprovSerialComponent::build_version_info_() {
|
std::vector<uint8_t> ImprovSerialComponent::build_version_info_() {
|
||||||
std::vector<std::string> infos = {"ESPHome", ESPHOME_VERSION, ESPHOME_VARIANT, App.get_name()};
|
std::vector<std::string> infos = {"ESPHome", ESPHOME_VERSION, ESPHOME_VARIANT, App.get_name()};
|
||||||
std::vector<uint8_t> data = improv::build_rpc_response(improv::GET_DEVICE_INFO, infos);
|
std::vector<uint8_t> data = improv::build_rpc_response(improv::GET_DEVICE_INFO, infos, false);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,22 +140,33 @@ bool ImprovSerialComponent::parse_improv_serial_byte_(uint8_t byte) {
|
|||||||
if (at < 8 + data_len)
|
if (at < 8 + data_len)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (at == 8 + data_len) {
|
if (at == 8 + data_len)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (at == 8 + data_len + 1) {
|
||||||
|
uint8_t checksum = 0x00;
|
||||||
|
for (uint8_t i = 0; i < at; i++)
|
||||||
|
checksum += raw[i];
|
||||||
|
|
||||||
|
if (checksum != byte) {
|
||||||
|
ESP_LOGW(TAG, "Error decoding Improv payload");
|
||||||
|
this->set_error_(improv::ERROR_INVALID_RPC);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == TYPE_RPC) {
|
if (type == TYPE_RPC) {
|
||||||
this->set_error_(improv::ERROR_NONE);
|
this->set_error_(improv::ERROR_NONE);
|
||||||
auto command = improv::parse_improv_data(&raw[9], data_len);
|
auto command = improv::parse_improv_data(&raw[9], data_len, false);
|
||||||
return this->parse_improv_payload_(command);
|
return this->parse_improv_payload_(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
// If we got here then the command coming is is improv, but not an RPC command
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command) {
|
bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command) {
|
||||||
switch (command.command) {
|
switch (command.command) {
|
||||||
case improv::BAD_CHECKSUM:
|
|
||||||
ESP_LOGW(TAG, "Error decoding Improv payload");
|
|
||||||
this->set_error_(improv::ERROR_INVALID_RPC);
|
|
||||||
return false;
|
|
||||||
case improv::WIFI_SETTINGS: {
|
case improv::WIFI_SETTINGS: {
|
||||||
wifi::WiFiAP sta{};
|
wifi::WiFiAP sta{};
|
||||||
sta.set_ssid(command.ssid);
|
sta.set_ssid(command.ssid);
|
||||||
@@ -233,6 +243,12 @@ void ImprovSerialComponent::send_response_(std::vector<uint8_t> &response) {
|
|||||||
data[7] = TYPE_RPC_RESPONSE;
|
data[7] = TYPE_RPC_RESPONSE;
|
||||||
data[8] = response.size();
|
data[8] = response.size();
|
||||||
data.insert(data.end(), response.begin(), response.end());
|
data.insert(data.end(), response.begin(), response.end());
|
||||||
|
|
||||||
|
uint8_t checksum = 0x00;
|
||||||
|
for (uint8_t d : data)
|
||||||
|
checksum += d;
|
||||||
|
data.push_back(checksum);
|
||||||
|
|
||||||
this->write_data_(data);
|
this->write_data_(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "adapter.h"
|
#include "ac_adapter.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
namespace ac {
|
||||||
|
|
||||||
const char *const Constants::TAG = "midea";
|
const char *const Constants::TAG = "midea";
|
||||||
const std::string Constants::FREEZE_PROTECTION = "freeze protection";
|
const std::string Constants::FREEZE_PROTECTION = "freeze protection";
|
||||||
@@ -171,6 +172,7 @@ void Converters::to_climate_traits(ClimateTraits &traits, const dudanov::midea::
|
|||||||
traits.add_supported_custom_preset(Constants::FREEZE_PROTECTION);
|
traits.add_supported_custom_preset(Constants::FREEZE_PROTECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace ac
|
||||||
} // namespace midea
|
} // namespace midea
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
@@ -2,12 +2,15 @@
|
|||||||
|
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
|
// MideaUART
|
||||||
#include <Appliance/AirConditioner/AirConditioner.h>
|
#include <Appliance/AirConditioner/AirConditioner.h>
|
||||||
|
|
||||||
#include "esphome/components/climate/climate_traits.h"
|
#include "esphome/components/climate/climate_traits.h"
|
||||||
#include "appliance_base.h"
|
#include "air_conditioner.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
namespace ac {
|
||||||
|
|
||||||
using MideaMode = dudanov::midea::ac::Mode;
|
using MideaMode = dudanov::midea::ac::Mode;
|
||||||
using MideaSwingMode = dudanov::midea::ac::SwingMode;
|
using MideaSwingMode = dudanov::midea::ac::SwingMode;
|
||||||
@@ -41,6 +44,7 @@ class Converters {
|
|||||||
static void to_climate_traits(ClimateTraits &traits, const dudanov::midea::ac::Capabilities &capabilities);
|
static void to_climate_traits(ClimateTraits &traits, const dudanov::midea::ac::Capabilities &capabilities);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace ac
|
||||||
} // namespace midea
|
} // namespace midea
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
namespace ac {
|
||||||
|
|
||||||
template<typename... Ts> class MideaActionBase : public Action<Ts...> {
|
template<typename... Ts> class MideaActionBase : public Action<Ts...> {
|
||||||
public:
|
public:
|
||||||
@@ -55,6 +56,7 @@ template<typename... Ts> class PowerOffAction : public MideaActionBase<Ts...> {
|
|||||||
void play(Ts... x) override { this->parent_->do_power_off(); }
|
void play(Ts... x) override { this->parent_->do_power_off(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace ac
|
||||||
} // namespace midea
|
} // namespace midea
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
@@ -2,13 +2,11 @@
|
|||||||
|
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "air_conditioner.h"
|
#include "air_conditioner.h"
|
||||||
#include "adapter.h"
|
#include "ac_adapter.h"
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
|
||||||
#include "midea_ir.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
namespace ac {
|
||||||
|
|
||||||
static void set_sensor(Sensor *sensor, float value) {
|
static void set_sensor(Sensor *sensor, float value) {
|
||||||
if (sensor != nullptr && (!sensor->has_state() || sensor->get_raw_state() != value))
|
if (sensor != nullptr && (!sensor->has_state() || sensor->get_raw_state() != value))
|
||||||
@@ -122,7 +120,7 @@ void AirConditioner::dump_config() {
|
|||||||
void AirConditioner::do_follow_me(float temperature, bool beeper) {
|
void AirConditioner::do_follow_me(float temperature, bool beeper) {
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
#ifdef USE_REMOTE_TRANSMITTER
|
||||||
IrFollowMeData data(static_cast<uint8_t>(lroundf(temperature)), beeper);
|
IrFollowMeData data(static_cast<uint8_t>(lroundf(temperature)), beeper);
|
||||||
this->transmit_ir(data);
|
this->transmitter_.transmit(data);
|
||||||
#else
|
#else
|
||||||
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
||||||
#endif
|
#endif
|
||||||
@@ -131,7 +129,7 @@ void AirConditioner::do_follow_me(float temperature, bool beeper) {
|
|||||||
void AirConditioner::do_swing_step() {
|
void AirConditioner::do_swing_step() {
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
#ifdef USE_REMOTE_TRANSMITTER
|
||||||
IrSpecialData data(0x01);
|
IrSpecialData data(0x01);
|
||||||
this->transmit_ir(data);
|
this->transmitter_.transmit(data);
|
||||||
#else
|
#else
|
||||||
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
||||||
#endif
|
#endif
|
||||||
@@ -143,13 +141,14 @@ void AirConditioner::do_display_toggle() {
|
|||||||
} else {
|
} else {
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
#ifdef USE_REMOTE_TRANSMITTER
|
||||||
IrSpecialData data(0x08);
|
IrSpecialData data(0x08);
|
||||||
this->transmit_ir(data);
|
this->transmitter_.transmit(data);
|
||||||
#else
|
#else
|
||||||
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace ac
|
||||||
} // namespace midea
|
} // namespace midea
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,25 @@
|
|||||||
|
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
|
// MideaUART
|
||||||
#include <Appliance/AirConditioner/AirConditioner.h>
|
#include <Appliance/AirConditioner/AirConditioner.h>
|
||||||
|
|
||||||
#include "appliance_base.h"
|
#include "appliance_base.h"
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
namespace ac {
|
||||||
|
|
||||||
using sensor::Sensor;
|
using sensor::Sensor;
|
||||||
using climate::ClimateCall;
|
using climate::ClimateCall;
|
||||||
|
using climate::ClimatePreset;
|
||||||
|
using climate::ClimateTraits;
|
||||||
|
using climate::ClimateMode;
|
||||||
|
using climate::ClimateSwingMode;
|
||||||
|
using climate::ClimateFanMode;
|
||||||
|
|
||||||
class AirConditioner : public ApplianceBase<dudanov::midea::ac::AirConditioner> {
|
class AirConditioner : public ApplianceBase<dudanov::midea::ac::AirConditioner>, public climate::Climate {
|
||||||
public:
|
public:
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void set_outdoor_temperature_sensor(Sensor *sensor) { this->outdoor_sensor_ = sensor; }
|
void set_outdoor_temperature_sensor(Sensor *sensor) { this->outdoor_sensor_ = sensor; }
|
||||||
@@ -31,15 +39,26 @@ class AirConditioner : public ApplianceBase<dudanov::midea::ac::AirConditioner>
|
|||||||
void do_beeper_off() { this->set_beeper_feedback(false); }
|
void do_beeper_off() { this->set_beeper_feedback(false); }
|
||||||
void do_power_on() { this->base_.setPowerState(true); }
|
void do_power_on() { this->base_.setPowerState(true); }
|
||||||
void do_power_off() { this->base_.setPowerState(false); }
|
void do_power_off() { this->base_.setPowerState(false); }
|
||||||
|
void set_supported_modes(const std::set<ClimateMode> &modes) { this->supported_modes_ = modes; }
|
||||||
|
void set_supported_swing_modes(const std::set<ClimateSwingMode> &modes) { this->supported_swing_modes_ = modes; }
|
||||||
|
void set_supported_presets(const std::set<ClimatePreset> &presets) { this->supported_presets_ = presets; }
|
||||||
|
void set_custom_presets(const std::set<std::string> &presets) { this->supported_custom_presets_ = presets; }
|
||||||
|
void set_custom_fan_modes(const std::set<std::string> &modes) { this->supported_custom_fan_modes_ = modes; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void control(const ClimateCall &call) override;
|
void control(const ClimateCall &call) override;
|
||||||
ClimateTraits traits() override;
|
ClimateTraits traits() override;
|
||||||
|
std::set<ClimateMode> supported_modes_{};
|
||||||
|
std::set<ClimateSwingMode> supported_swing_modes_{};
|
||||||
|
std::set<ClimatePreset> supported_presets_{};
|
||||||
|
std::set<std::string> supported_custom_presets_{};
|
||||||
|
std::set<std::string> supported_custom_fan_modes_{};
|
||||||
Sensor *outdoor_sensor_{nullptr};
|
Sensor *outdoor_sensor_{nullptr};
|
||||||
Sensor *humidity_sensor_{nullptr};
|
Sensor *humidity_sensor_{nullptr};
|
||||||
Sensor *power_sensor_{nullptr};
|
Sensor *power_sensor_{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace ac
|
||||||
} // namespace midea
|
} // namespace midea
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|||||||
@@ -2,84 +2,97 @@
|
|||||||
|
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
|
// MideaUART
|
||||||
|
#include <Appliance/ApplianceBase.h>
|
||||||
|
#include <Helpers/Logger.h>
|
||||||
|
|
||||||
|
// Include global defines
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/components/uart/uart.h"
|
#include "esphome/components/uart/uart.h"
|
||||||
#include "esphome/components/climate/climate.h"
|
#include "esphome/components/climate/climate.h"
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
#include "ir_transmitter.h"
|
||||||
#include "esphome/components/remote_base/midea_protocol.h"
|
|
||||||
#include "esphome/components/remote_transmitter/remote_transmitter.h"
|
|
||||||
#endif
|
|
||||||
#include <Appliance/ApplianceBase.h>
|
|
||||||
#include <Helpers/Logger.h>
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
|
||||||
using climate::ClimatePreset;
|
/* Stream from UART component */
|
||||||
using climate::ClimateTraits;
|
class UARTStream : public Stream {
|
||||||
using climate::ClimateMode;
|
public:
|
||||||
using climate::ClimateSwingMode;
|
void set_uart(uart::UARTComponent *uart) { this->uart_ = uart; }
|
||||||
using climate::ClimateFanMode;
|
|
||||||
|
|
||||||
template<typename T>
|
/* Stream interface implementation */
|
||||||
class ApplianceBase : public Component, public uart::UARTDevice, public climate::Climate, public Stream {
|
|
||||||
|
int available() override { return this->uart_->available(); }
|
||||||
|
int read() override {
|
||||||
|
uint8_t data;
|
||||||
|
this->uart_->read_byte(&data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
int peek() override {
|
||||||
|
uint8_t data;
|
||||||
|
this->uart_->peek_byte(&data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
size_t write(uint8_t data) override {
|
||||||
|
this->uart_->write_byte(data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
size_t write(const uint8_t *data, size_t size) override {
|
||||||
|
this->uart_->write_array(data, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
void flush() override { this->uart_->flush(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uart::UARTComponent *uart_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> class ApplianceBase : public Component {
|
||||||
static_assert(std::is_base_of<dudanov::midea::ApplianceBase, T>::value,
|
static_assert(std::is_base_of<dudanov::midea::ApplianceBase, T>::value,
|
||||||
"T must derive from dudanov::midea::ApplianceBase class");
|
"T must derive from dudanov::midea::ApplianceBase class");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ApplianceBase() {
|
ApplianceBase() {
|
||||||
this->base_.setStream(this);
|
this->base_.setStream(&this->stream_);
|
||||||
this->base_.addOnStateCallback(std::bind(&ApplianceBase::on_status_change, this));
|
this->base_.addOnStateCallback(std::bind(&ApplianceBase::on_status_change, this));
|
||||||
dudanov::midea::ApplianceBase::setLogger(
|
dudanov::midea::ApplianceBase::setLogger(
|
||||||
[](int level, const char *tag, int line, const String &format, va_list args) {
|
[](int level, const char *tag, int line, const String &format, va_list args) {
|
||||||
esp_log_vprintf_(level, tag, line, format.c_str(), args);
|
esp_log_vprintf_(level, tag, line, format.c_str(), args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
bool can_proceed() override {
|
|
||||||
return this->base_.getAutoconfStatus() != dudanov::midea::AutoconfStatus::AUTOCONF_PROGRESS;
|
#ifdef USE_REMOTE_TRANSMITTER
|
||||||
}
|
void set_transmitter(RemoteTransmitterBase *transmitter) { this->transmitter_.set_transmitter(transmitter); }
|
||||||
float get_setup_priority() const override { return setup_priority::BEFORE_CONNECTION; }
|
#endif
|
||||||
void setup() override { this->base_.setup(); }
|
|
||||||
void loop() override { this->base_.loop(); }
|
/* UART communication */
|
||||||
|
|
||||||
|
void set_uart_parent(uart::UARTComponent *parent) { this->stream_.set_uart(parent); }
|
||||||
void set_period(uint32_t ms) { this->base_.setPeriod(ms); }
|
void set_period(uint32_t ms) { this->base_.setPeriod(ms); }
|
||||||
void set_response_timeout(uint32_t ms) { this->base_.setTimeout(ms); }
|
void set_response_timeout(uint32_t ms) { this->base_.setTimeout(ms); }
|
||||||
void set_request_attempts(uint32_t attempts) { this->base_.setNumAttempts(attempts); }
|
void set_request_attempts(uint32_t attempts) { this->base_.setNumAttempts(attempts); }
|
||||||
|
|
||||||
|
/* Component methods */
|
||||||
|
|
||||||
|
void setup() override { this->base_.setup(); }
|
||||||
|
void loop() override { this->base_.loop(); }
|
||||||
|
float get_setup_priority() const override { return setup_priority::BEFORE_CONNECTION; }
|
||||||
|
bool can_proceed() override {
|
||||||
|
return this->base_.getAutoconfStatus() != dudanov::midea::AutoconfStatus::AUTOCONF_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
void set_beeper_feedback(bool state) { this->base_.setBeeper(state); }
|
void set_beeper_feedback(bool state) { this->base_.setBeeper(state); }
|
||||||
void set_autoconf(bool value) { this->base_.setAutoconf(value); }
|
void set_autoconf(bool value) { this->base_.setAutoconf(value); }
|
||||||
void set_supported_modes(const std::set<ClimateMode> &modes) { this->supported_modes_ = modes; }
|
|
||||||
void set_supported_swing_modes(const std::set<ClimateSwingMode> &modes) { this->supported_swing_modes_ = modes; }
|
|
||||||
void set_supported_presets(const std::set<ClimatePreset> &presets) { this->supported_presets_ = presets; }
|
|
||||||
void set_custom_presets(const std::set<std::string> &presets) { this->supported_custom_presets_ = presets; }
|
|
||||||
void set_custom_fan_modes(const std::set<std::string> &modes) { this->supported_custom_fan_modes_ = modes; }
|
|
||||||
virtual void on_status_change() = 0;
|
virtual void on_status_change() = 0;
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
|
||||||
void set_transmitter(remote_transmitter::RemoteTransmitterComponent *transmitter) {
|
|
||||||
this->transmitter_ = transmitter;
|
|
||||||
}
|
|
||||||
void transmit_ir(remote_base::MideaData &data) {
|
|
||||||
data.finalize();
|
|
||||||
auto transmit = this->transmitter_->transmit();
|
|
||||||
remote_base::MideaProtocol().encode(transmit.get_data(), data);
|
|
||||||
transmit.perform();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int available() override { return uart::UARTDevice::available(); }
|
|
||||||
int read() override { return uart::UARTDevice::read(); }
|
|
||||||
int peek() override { return uart::UARTDevice::peek(); }
|
|
||||||
void flush() override { uart::UARTDevice::flush(); }
|
|
||||||
size_t write(uint8_t data) override { return uart::UARTDevice::write(data); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T base_;
|
T base_;
|
||||||
std::set<ClimateMode> supported_modes_{};
|
UARTStream stream_;
|
||||||
std::set<ClimateSwingMode> supported_swing_modes_{};
|
|
||||||
std::set<ClimatePreset> supported_presets_{};
|
|
||||||
std::set<std::string> supported_custom_presets_{};
|
|
||||||
std::set<std::string> supported_custom_fan_modes_{};
|
|
||||||
#ifdef USE_REMOTE_TRANSMITTER
|
#ifdef USE_REMOTE_TRANSMITTER
|
||||||
remote_transmitter::RemoteTransmitterComponent *transmitter_{nullptr};
|
IrTransmitter transmitter_;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ AUTO_LOAD = ["sensor"]
|
|||||||
CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
|
CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
|
||||||
CONF_POWER_USAGE = "power_usage"
|
CONF_POWER_USAGE = "power_usage"
|
||||||
CONF_HUMIDITY_SETPOINT = "humidity_setpoint"
|
CONF_HUMIDITY_SETPOINT = "humidity_setpoint"
|
||||||
midea_ns = cg.esphome_ns.namespace("midea")
|
midea_ac_ns = cg.esphome_ns.namespace("midea").namespace("ac")
|
||||||
AirConditioner = midea_ns.class_("AirConditioner", climate.Climate, cg.Component)
|
AirConditioner = midea_ac_ns.class_("AirConditioner", climate.Climate, cg.Component)
|
||||||
Capabilities = midea_ns.namespace("Constants")
|
Capabilities = midea_ac_ns.namespace("Constants")
|
||||||
|
|
||||||
|
|
||||||
def templatize(value):
|
def templatize(value):
|
||||||
@@ -156,13 +156,13 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Actions
|
# Actions
|
||||||
FollowMeAction = midea_ns.class_("FollowMeAction", automation.Action)
|
FollowMeAction = midea_ac_ns.class_("FollowMeAction", automation.Action)
|
||||||
DisplayToggleAction = midea_ns.class_("DisplayToggleAction", automation.Action)
|
DisplayToggleAction = midea_ac_ns.class_("DisplayToggleAction", automation.Action)
|
||||||
SwingStepAction = midea_ns.class_("SwingStepAction", automation.Action)
|
SwingStepAction = midea_ac_ns.class_("SwingStepAction", automation.Action)
|
||||||
BeeperOnAction = midea_ns.class_("BeeperOnAction", automation.Action)
|
BeeperOnAction = midea_ac_ns.class_("BeeperOnAction", automation.Action)
|
||||||
BeeperOffAction = midea_ns.class_("BeeperOffAction", automation.Action)
|
BeeperOffAction = midea_ac_ns.class_("BeeperOffAction", automation.Action)
|
||||||
PowerOnAction = midea_ns.class_("PowerOnAction", automation.Action)
|
PowerOnAction = midea_ac_ns.class_("PowerOnAction", automation.Action)
|
||||||
PowerOffAction = midea_ns.class_("PowerOffAction", automation.Action)
|
PowerOffAction = midea_ac_ns.class_("PowerOffAction", automation.Action)
|
||||||
|
|
||||||
MIDEA_ACTION_BASE_SCHEMA = cv.Schema(
|
MIDEA_ACTION_BASE_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace midea {
|
namespace midea {
|
||||||
|
|
||||||
|
using remote_base::RemoteTransmitterBase;
|
||||||
using IrData = remote_base::MideaData;
|
using IrData = remote_base::MideaData;
|
||||||
|
|
||||||
class IrFollowMeData : public IrData {
|
class IrFollowMeData : public IrData {
|
||||||
@@ -38,6 +39,20 @@ class IrSpecialData : public IrData {
|
|||||||
IrSpecialData(uint8_t code) : IrData({MIDEA_TYPE_SPECIAL, code, 0xFF, 0xFF, 0xFF}) {}
|
IrSpecialData(uint8_t code) : IrData({MIDEA_TYPE_SPECIAL, code, 0xFF, 0xFF, 0xFF}) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IrTransmitter {
|
||||||
|
public:
|
||||||
|
void set_transmitter(RemoteTransmitterBase *transmitter) { this->transmitter_ = transmitter; }
|
||||||
|
void transmit(IrData &data) {
|
||||||
|
data.finalize();
|
||||||
|
auto transmit = this->transmitter_->transmit();
|
||||||
|
remote_base::MideaProtocol().encode(transmit.get_data(), data);
|
||||||
|
transmit.perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RemoteTransmitterBase *transmitter_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace midea
|
} // namespace midea
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
@@ -129,14 +129,14 @@ async def to_code(config):
|
|||||||
return_type=cg.optional.template(float),
|
return_type=cg.optional.template(float),
|
||||||
)
|
)
|
||||||
cg.add(var.set_template(template_))
|
cg.add(var.set_template(template_))
|
||||||
if CONF_WRITE_LAMBDA in config:
|
if CONF_WRITE_LAMBDA in config:
|
||||||
template_ = await cg.process_lambda(
|
template_ = await cg.process_lambda(
|
||||||
config[CONF_WRITE_LAMBDA],
|
config[CONF_WRITE_LAMBDA],
|
||||||
[
|
[
|
||||||
(ModbusNumber.operator("ptr"), "item"),
|
(ModbusNumber.operator("ptr"), "item"),
|
||||||
(cg.float_, "x"),
|
(cg.float_, "x"),
|
||||||
(cg.std_vector.template(cg.uint16).operator("ref"), "payload"),
|
(cg.std_vector.template(cg.uint16).operator("ref"), "payload"),
|
||||||
],
|
],
|
||||||
return_type=cg.optional.template(float),
|
return_type=cg.optional.template(float),
|
||||||
)
|
)
|
||||||
cg.add(var.set_write_template(template_))
|
cg.add(var.set_write_template(template_))
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ NumberInRangeCondition = number_ns.class_(
|
|||||||
|
|
||||||
icon = cv.icon
|
icon = cv.icon
|
||||||
|
|
||||||
NUMBER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
NUMBER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||||
{
|
{
|
||||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTNumberComponent),
|
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTNumberComponent),
|
||||||
cv.GenerateID(): cv.declare_id(Number),
|
cv.GenerateID(): cv.declare_id(Number),
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ CONFIG_SCHEMA = cv.Schema(
|
|||||||
cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(
|
cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(
|
||||||
web_server_base.WebServerBase
|
web_server_base.WebServerBase
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
|
cv.only_with_arduino,
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ SelectSetAction = select_ns.class_("SelectSetAction", automation.Action)
|
|||||||
|
|
||||||
icon = cv.icon
|
icon = cv.icon
|
||||||
|
|
||||||
SELECT_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
SELECT_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||||
{
|
{
|
||||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTSelectComponent),
|
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTSelectComponent),
|
||||||
cv.GenerateID(): cv.declare_id(Select),
|
cv.GenerateID(): cv.declare_id(Select),
|
||||||
|
|||||||
@@ -28,4 +28,4 @@ async def to_code(config):
|
|||||||
cg.add_library("FS", None)
|
cg.add_library("FS", None)
|
||||||
cg.add_library("Update", None)
|
cg.add_library("Update", None)
|
||||||
# https://github.com/esphome/ESPAsyncWebServer/blob/master/library.json
|
# https://github.com/esphome/ESPAsyncWebServer/blob/master/library.json
|
||||||
cg.add_library("esphome/ESPAsyncWebServer-esphome", "2.0.1")
|
cg.add_library("esphome/ESPAsyncWebServer-esphome", "2.1.0")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2021.11.0b2"
|
__version__ = "2021.11.0b7"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
|
|
||||||
@@ -878,10 +878,11 @@ DEVICE_CLASS_OPENING = "opening"
|
|||||||
DEVICE_CLASS_PLUG = "plug"
|
DEVICE_CLASS_PLUG = "plug"
|
||||||
DEVICE_CLASS_PRESENCE = "presence"
|
DEVICE_CLASS_PRESENCE = "presence"
|
||||||
DEVICE_CLASS_PROBLEM = "problem"
|
DEVICE_CLASS_PROBLEM = "problem"
|
||||||
|
DEVICE_CLASS_RUNNING = "running"
|
||||||
DEVICE_CLASS_SAFETY = "safety"
|
DEVICE_CLASS_SAFETY = "safety"
|
||||||
DEVICE_CLASS_SMOKE = "smoke"
|
DEVICE_CLASS_SMOKE = "smoke"
|
||||||
DEVICE_CLASS_SOUND = "sound"
|
DEVICE_CLASS_SOUND = "sound"
|
||||||
DEVICE_CLASS_UPDATE = "update"
|
DEVICE_CLASS_TAMPER = "tamper"
|
||||||
DEVICE_CLASS_VIBRATION = "vibration"
|
DEVICE_CLASS_VIBRATION = "vibration"
|
||||||
DEVICE_CLASS_WINDOW = "window"
|
DEVICE_CLASS_WINDOW = "window"
|
||||||
# device classes of both binary_sensor and sensor component
|
# device classes of both binary_sensor and sensor component
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifdef USE_WIFI
|
#ifdef USE_WIFI
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <Arduino.h>
|
||||||
#include <osapi.h>
|
#include <osapi.h>
|
||||||
#elif defined(USE_ESP32_FRAMEWORK_ARDUINO)
|
#elif defined(USE_ESP32_FRAMEWORK_ARDUINO)
|
||||||
#include <Esp.h>
|
#include <Esp.h>
|
||||||
@@ -430,13 +431,8 @@ void hsv_to_rgb(int hue, float saturation, float value, float &red, float &green
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
#ifdef USE_WIFI
|
|
||||||
IRAM_ATTR InterruptLock::InterruptLock() { xt_state_ = xt_rsil(15); }
|
IRAM_ATTR InterruptLock::InterruptLock() { xt_state_ = xt_rsil(15); }
|
||||||
IRAM_ATTR InterruptLock::~InterruptLock() { xt_wsr_ps(xt_state_); }
|
IRAM_ATTR InterruptLock::~InterruptLock() { xt_wsr_ps(xt_state_); }
|
||||||
#else
|
|
||||||
IRAM_ATTR InterruptLock::InterruptLock() {}
|
|
||||||
IRAM_ATTR InterruptLock::~InterruptLock() {}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
|
IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ lib_deps =
|
|||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
ottowinter/AsyncMqttClient-esphome@0.8.6 ; mqtt
|
ottowinter/AsyncMqttClient-esphome@0.8.6 ; mqtt
|
||||||
ottowinter/ArduinoJson-esphomelib@5.13.3 ; json
|
ottowinter/ArduinoJson-esphomelib@5.13.3 ; json
|
||||||
esphome/ESPAsyncWebServer-esphome@2.0.1 ; web_server_base
|
esphome/ESPAsyncWebServer-esphome@2.1.0 ; web_server_base
|
||||||
fastled/FastLED@3.3.2 ; fastled_base
|
fastled/FastLED@3.3.2 ; fastled_base
|
||||||
mikalhart/TinyGPSPlus@1.0.2 ; gps
|
mikalhart/TinyGPSPlus@1.0.2 ; gps
|
||||||
freekode/TM1651@1.0.1 ; tm1651
|
freekode/TM1651@1.0.1 ; tm1651
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ esptool==3.2
|
|||||||
click==8.0.3
|
click==8.0.3
|
||||||
esphome-dashboard==20211021.1
|
esphome-dashboard==20211021.1
|
||||||
aioesphomeapi==10.2.0
|
aioesphomeapi==10.2.0
|
||||||
|
zeroconf==0.36.13
|
||||||
|
|
||||||
# esp-idf requires this, but doesn't bundle it by default
|
# esp-idf requires this, but doesn't bundle it by default
|
||||||
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24
|
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24
|
||||||
|
|||||||
@@ -2512,3 +2512,23 @@ teleinfo:
|
|||||||
uart_id: uart0
|
uart_id: uart0
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
historical_mode: true
|
historical_mode: true
|
||||||
|
|
||||||
|
number:
|
||||||
|
- platform: template
|
||||||
|
id: test_number
|
||||||
|
state_topic: livingroom/custom_state_topic
|
||||||
|
command_topic: livingroom/custom_command_topic
|
||||||
|
min_value: 0
|
||||||
|
step: 1
|
||||||
|
max_value: 10
|
||||||
|
optimistic: true
|
||||||
|
|
||||||
|
select:
|
||||||
|
- platform: template
|
||||||
|
id: test_select
|
||||||
|
state_topic: livingroom/custom_state_topic
|
||||||
|
command_topic: livingroom/custom_command_topic
|
||||||
|
options:
|
||||||
|
- one
|
||||||
|
- two
|
||||||
|
optimistic: true
|
||||||
|
|||||||
Reference in New Issue
Block a user