mirror of
https://github.com/esphome/esphome.git
synced 2026-10-26 16:02:13 +00:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cceddfbf4 | ||
|
|
ff6a37a052 | ||
|
|
6990092be0 | ||
|
|
9220c79a51 | ||
|
|
215fcd4f5d | ||
|
|
918e3b3a58 | ||
|
|
347eb3902e | ||
|
|
177820083f | ||
|
|
b0a0524091 |
No files matched your search
@@ -1,7 +1,7 @@
|
||||
#include "bme680_bsec.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <string>
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::bme680_bsec {
|
||||
#ifdef USE_BSEC
|
||||
@@ -9,7 +9,7 @@ ESPHOME_LOG_TAG(TAG, "bme680_bsec.sensor");
|
||||
|
||||
static constexpr uint32_t READ_TIMEOUT_ID = 0;
|
||||
|
||||
static const std::string IAQ_ACCURACY_STATES[4] = {"Stabilizing", "Uncertain", "Calibrating", "Calibrated"};
|
||||
PROGMEM_STRING_TABLE(IaqAccuracyStrings, "Stabilizing", "Uncertain", "Calibrating", "Calibrated");
|
||||
|
||||
std::vector<BME680BSECComponent *>
|
||||
BME680BSECComponent::instances; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
@@ -386,10 +386,11 @@ void BME680BSECComponent::publish_(const bsec_output_t *outputs, uint8_t num_out
|
||||
switch (outputs[i].sensor_id) {
|
||||
case BSEC_OUTPUT_IAQ:
|
||||
case BSEC_OUTPUT_STATIC_IAQ: {
|
||||
uint8_t accuracy = std::min<uint8_t>(outputs[i].accuracy, std::size(IAQ_ACCURACY_STATES) - 1);
|
||||
uint8_t accuracy = std::min<uint8_t>(outputs[i].accuracy, IaqAccuracyStrings::LAST_INDEX);
|
||||
this->queue_push_([this, signal]() { this->publish_sensor_(this->iaq_sensor_, signal); });
|
||||
this->queue_push_([this, accuracy]() {
|
||||
this->publish_sensor_(this->iaq_accuracy_text_sensor_, IAQ_ACCURACY_STATES[accuracy]);
|
||||
this->publish_sensor_(this->iaq_accuracy_text_sensor_,
|
||||
IaqAccuracyStrings::get_progmem_str(accuracy, IaqAccuracyStrings::LAST_INDEX));
|
||||
});
|
||||
this->queue_push_([this, accuracy]() { this->publish_sensor_(this->iaq_accuracy_sensor_, accuracy, true); });
|
||||
|
||||
@@ -435,8 +436,9 @@ void BME680BSECComponent::publish_sensor_(sensor::Sensor *sensor, float value, b
|
||||
sensor->publish_state(value);
|
||||
}
|
||||
|
||||
void BME680BSECComponent::publish_sensor_(text_sensor::TextSensor *sensor, const std::string &value) {
|
||||
if (!sensor || (sensor->has_state() && sensor->state == value)) {
|
||||
void BME680BSECComponent::publish_sensor_(text_sensor::TextSensor *sensor, ProgmemStr value) {
|
||||
if (!sensor ||
|
||||
(sensor->has_state() && ESPHOME_strcmp_P(sensor->state.c_str(), reinterpret_cast<ESPHOME_PGM_P>(value)) == 0)) {
|
||||
return;
|
||||
}
|
||||
sensor->publish_state(value);
|
||||
|
||||
@@ -77,7 +77,7 @@ class BME680BSECComponent final : public Component, public i2c::I2CDevice {
|
||||
int64_t get_time_ns_();
|
||||
|
||||
void publish_sensor_(sensor::Sensor *sensor, float value, bool change_only = false);
|
||||
void publish_sensor_(text_sensor::TextSensor *sensor, const std::string &value);
|
||||
void publish_sensor_(text_sensor::TextSensor *sensor, ProgmemStr value);
|
||||
|
||||
void snapshot_state_(); // Fetch the current BSEC library state and save it in the bsec_state_data_ member (volatile
|
||||
// memory)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "cc1101pa.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
@@ -14,6 +15,9 @@ namespace esphome::cc1101 {
|
||||
ESPHOME_LOG_TAG(TAG, "cc1101");
|
||||
static constexpr size_t TX_FIFO_SIZE = 64;
|
||||
|
||||
// MDMCFG2 MOD_FORMAT values
|
||||
PROGMEM_STRING_TABLE(ModulationStrings, "2-FSK", "GFSK", "UNUSED", "ASK/OOK", "4-FSK", "UNUSED", "UNUSED", "MSK");
|
||||
|
||||
static void split_float(float value, int mbits, uint8_t &e, uint32_t &m) {
|
||||
int e_tmp;
|
||||
float m_tmp = std::frexp(value, &e_tmp);
|
||||
@@ -238,8 +242,6 @@ void CC1101Component::loop() {
|
||||
}
|
||||
|
||||
void CC1101Component::dump_config() {
|
||||
static const char *const MODULATION_NAMES[] = {"2-FSK", "GFSK", "UNUSED", "ASK/OOK",
|
||||
"4-FSK", "UNUSED", "UNUSED", "MSK"};
|
||||
int32_t freq = static_cast<int32_t>(this->state_.FREQ2 << 16 | this->state_.FREQ1 << 8 | this->state_.FREQ0) *
|
||||
XTAL_FREQUENCY / (1 << 16);
|
||||
float symbol_rate = (((256.0f + this->state_.DRATE_M) * (1 << this->state_.DRATE_E)) / (1 << 28)) * XTAL_FREQUENCY;
|
||||
@@ -253,8 +255,9 @@ void CC1101Component::dump_config() {
|
||||
" Symbol Rate: %.0f baud\n"
|
||||
" Filter Bandwidth: %.1f Hz\n"
|
||||
" Output Power: %.1f dBm",
|
||||
this->chip_id_, freq, this->state_.CHANNR, MODULATION_NAMES[this->state_.MOD_FORMAT & 0x07],
|
||||
symbol_rate, bw, this->output_power_effective_);
|
||||
this->chip_id_, freq, this->state_.CHANNR,
|
||||
LOG_STR_ARG(ModulationStrings::get_log_str(this->state_.MOD_FORMAT & 0x07, 0)), symbol_rate, bw,
|
||||
this->output_power_effective_);
|
||||
LOG_PIN(" CS Pin: ", this->cs_);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,21 +4,18 @@
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::epaper_spi {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "epaper_spi");
|
||||
static constexpr size_t EPAPER_MAX_CMD_LOG_BYTES = 128;
|
||||
|
||||
static constexpr const char *const EPAPER_STATE_STRINGS[] = {
|
||||
"IDLE", "UPDATE", "RESET", "RESET_END", "SHOULD_WAIT", "INITIALISE",
|
||||
"TRANSFER_DATA", "POWER_ON", "REFRESH_SCREEN", "POWER_OFF", "DEEP_SLEEP",
|
||||
};
|
||||
PROGMEM_STRING_TABLE(EPaperStateStrings, "IDLE", "UPDATE", "RESET", "RESET_END", "SHOULD_WAIT", "INITIALISE",
|
||||
"TRANSFER_DATA", "POWER_ON", "REFRESH_SCREEN", "POWER_OFF", "DEEP_SLEEP", "Unknown");
|
||||
|
||||
const char *EPaperBase::epaper_state_to_string_() {
|
||||
if (auto idx = static_cast<unsigned>(this->state_); idx < std::size(EPAPER_STATE_STRINGS))
|
||||
return EPAPER_STATE_STRINGS[idx];
|
||||
return "Unknown";
|
||||
const LogString *EPaperBase::epaper_state_to_string_() {
|
||||
return EPaperStateStrings::get_log_str(static_cast<uint8_t>(this->state_), EPaperStateStrings::LAST_INDEX);
|
||||
}
|
||||
|
||||
void EPaperBase::setup() {
|
||||
@@ -159,7 +156,7 @@ void EPaperBase::update_effective_transform_() {
|
||||
|
||||
void EPaperBase::update() {
|
||||
if (this->state_ != EPaperState::IDLE) {
|
||||
ESP_LOGE(TAG, "Display already in state %s", epaper_state_to_string_());
|
||||
ESP_LOGE(TAG, "Display already in state %s", LOG_STR_ARG(epaper_state_to_string_()));
|
||||
return;
|
||||
}
|
||||
this->set_state_(EPaperState::UPDATE);
|
||||
@@ -212,7 +209,7 @@ void EPaperBase::loop() {
|
||||
this->high_frequency_loop_.stop();
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
if (now - this->waiting_for_idle_last_print_ >= 1000) {
|
||||
ESP_LOGV(TAG, "Waiting for idle in state %s", this->epaper_state_to_string_());
|
||||
ESP_LOGV(TAG, "Waiting for idle in state %s", LOG_STR_ARG(this->epaper_state_to_string_()));
|
||||
this->waiting_for_idle_last_print_ = millis();
|
||||
}
|
||||
#endif
|
||||
@@ -227,7 +224,7 @@ void EPaperBase::loop() {
|
||||
// The busy pin never cleared: give up on this update so later ones are not refused, and make the next one full
|
||||
void EPaperBase::abandon_update_() {
|
||||
ESP_LOGE(TAG, "Display stayed busy for %u s in state %s; check the busy pin", (unsigned) this->busy_timeout_seconds_,
|
||||
this->epaper_state_to_string_());
|
||||
LOG_STR_ARG(this->epaper_state_to_string_()));
|
||||
this->status_set_warning(LOG_STR("Busy pin timeout"));
|
||||
if (this->state_ == EPaperState::TRANSFER_DATA)
|
||||
this->abort_transfer();
|
||||
@@ -247,10 +244,10 @@ void EPaperBase::abandon_update_() {
|
||||
* Should a subclassed class need to override this, the method will need to be made virtual.
|
||||
*/
|
||||
void EPaperBase::process_state_() {
|
||||
ESP_LOGV(TAG, "Process state entered in state %s", epaper_state_to_string_());
|
||||
ESP_LOGV(TAG, "Process state entered in state %s", LOG_STR_ARG(epaper_state_to_string_()));
|
||||
switch (this->state_) {
|
||||
default:
|
||||
ESP_LOGE(TAG, "Display is in unhandled state %s", epaper_state_to_string_());
|
||||
ESP_LOGE(TAG, "Display is in unhandled state %s", LOG_STR_ARG(epaper_state_to_string_()));
|
||||
this->set_state_(EPaperState::IDLE);
|
||||
break;
|
||||
case EPaperState::IDLE:
|
||||
@@ -342,7 +339,7 @@ void EPaperBase::process_state_() {
|
||||
}
|
||||
|
||||
void EPaperBase::set_state_(EPaperState state, uint16_t delay) {
|
||||
ESP_LOGV(TAG, "Exit state %s", this->epaper_state_to_string_());
|
||||
ESP_LOGV(TAG, "Exit state %s", LOG_STR_ARG(this->epaper_state_to_string_()));
|
||||
this->state_ = state;
|
||||
// allow subclasses to nominate delays
|
||||
if (delay == 0)
|
||||
@@ -350,7 +347,7 @@ void EPaperBase::set_state_(EPaperState state, uint16_t delay) {
|
||||
this->next_delay_ = 0;
|
||||
this->delay_until_ = millis() + delay;
|
||||
this->wait_for_idle_(state > EPaperState::SHOULD_WAIT);
|
||||
ESP_LOGV(TAG, "Enter state %s, delay %u, wait_for_idle=%s", this->epaper_state_to_string_(), delay,
|
||||
ESP_LOGV(TAG, "Enter state %s, delay %u, wait_for_idle=%s", LOG_STR_ARG(this->epaper_state_to_string_()), delay,
|
||||
TRUEFALSE(this->waiting_for_idle_));
|
||||
// Each step of an update otherwise waits for the next loop iteration; loop() slows down again for long waits
|
||||
if (state == EPaperState::IDLE) {
|
||||
|
||||
@@ -125,7 +125,7 @@ class EPaperBase : public Display,
|
||||
bool is_using_partial_update_() const { return this->full_update_every_ > 1; }
|
||||
void process_state_();
|
||||
|
||||
const char *epaper_state_to_string_();
|
||||
const LogString *epaper_state_to_string_();
|
||||
bool is_idle_() const;
|
||||
void setup_pins_() const;
|
||||
virtual bool reset();
|
||||
|
||||
@@ -152,8 +152,8 @@ void ES8388::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "ES8388 Audio Codec:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
#ifdef USE_ES8388_SELECT
|
||||
LOG_SELECT(" ", "DAC Output", this->dac_output_select_);
|
||||
LOG_SELECT(" ", "ADC Input Mic", this->adc_input_mic_select_);
|
||||
LOG_SELECT(" ", "DacOutputSelect", this->dac_output_select_);
|
||||
LOG_SELECT(" ", "ADCInputMicSelect", this->adc_input_mic_select_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,14 @@ ADC_INPUT_MIC_OPTIONS = AdcInputMicLine.options(
|
||||
)
|
||||
ADC_INPUT_MIC_OPTION_NAMES = list(ADC_INPUT_MIC_OPTIONS)
|
||||
|
||||
DacOutputSelect = es8388_ns.class_("DacOutputSelect", select.Select)
|
||||
ADCInputMicSelect = es8388_ns.class_("ADCInputMicSelect", select.Select)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
{
|
||||
cv.GenerateID(CONF_ES8388_ID): cv.use_id(ES8388),
|
||||
cv.Optional(CONF_DAC_OUTPUT): select.select_schema(
|
||||
select.ApplySelect,
|
||||
DacOutputSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_CHIP,
|
||||
).extend(
|
||||
@@ -40,7 +42,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ADC_INPUT_MIC): select.select_schema(
|
||||
select.ApplySelect,
|
||||
ADCInputMicSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_CHIP,
|
||||
).extend(
|
||||
@@ -59,18 +61,12 @@ async def to_code(config: ConfigType) -> None:
|
||||
hub = await cg.get_variable(config[CONF_ES8388_ID])
|
||||
selects = select.sub_selects(config, parent=hub)
|
||||
await selects(
|
||||
CONF_DAC_OUTPUT,
|
||||
hub.set_dac_output_select,
|
||||
options=DAC_OUTPUT_OPTION_NAMES,
|
||||
apply="set_dac_output(static_cast<es8388::DacOutputLine>(index))",
|
||||
publish="before",
|
||||
CONF_DAC_OUTPUT, hub.set_dac_output_select, options=DAC_OUTPUT_OPTION_NAMES
|
||||
)
|
||||
await selects(
|
||||
CONF_ADC_INPUT_MIC,
|
||||
hub.set_adc_input_mic_select,
|
||||
options=ADC_INPUT_MIC_OPTION_NAMES,
|
||||
apply="set_adc_input_mic(static_cast<es8388::AdcInputMicLine>(index))",
|
||||
publish="before",
|
||||
)
|
||||
if (
|
||||
initial := config.get(CONF_DAC_OUTPUT, {}).get(CONF_INITIAL_OPTION)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "adc_input_mic_select.h"
|
||||
|
||||
namespace esphome::es8388 {
|
||||
|
||||
void ADCInputMicSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_adc_input_mic(static_cast<AdcInputMicLine>(index));
|
||||
}
|
||||
|
||||
} // namespace esphome::es8388
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/es8388/es8388.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
|
||||
namespace esphome::es8388 {
|
||||
|
||||
class ADCInputMicSelect final : public select::Select, public Parented<ES8388> {
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::es8388
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "dac_output_select.h"
|
||||
|
||||
namespace esphome::es8388 {
|
||||
|
||||
void DacOutputSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_dac_output(static_cast<DacOutputLine>(index));
|
||||
}
|
||||
|
||||
} // namespace esphome::es8388
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/es8388/es8388.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
|
||||
namespace esphome::es8388 {
|
||||
|
||||
class DacOutputSelect final : public select::Select, public Parented<ES8388> {
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::es8388
|
||||
@@ -9,23 +9,24 @@ from .. import (
|
||||
CONF_ESPECTRE_ID,
|
||||
DOMAIN,
|
||||
ESPectreComponent,
|
||||
espectre_ns,
|
||||
supported_traffic_generator_modes,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["espectre"]
|
||||
|
||||
TrafficModeSelect = espectre_ns.class_(
|
||||
"TrafficModeSelect", select.Select, cg.Parented.template(ESPectreComponent)
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = select.select_schema(
|
||||
select.ApplySelect, entity_category=ENTITY_CATEGORY_CONFIG
|
||||
TrafficModeSelect, entity_category=ENTITY_CATEGORY_CONFIG
|
||||
).extend({cv.GenerateID(CONF_ESPECTRE_ID): cv.use_id(ESPectreComponent)})
|
||||
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
options = supported_traffic_generator_modes(CORE.config[DOMAIN])
|
||||
hub = await cg.get_variable(config[CONF_ESPECTRE_ID])
|
||||
await select.sub_selects(config, parent=hub).create(
|
||||
config,
|
||||
hub.set_traffic_mode_select,
|
||||
options=options,
|
||||
apply="request_traffic_generator_mode(option)",
|
||||
)
|
||||
var = await select.new_select(config, options=options)
|
||||
await cg.register_parented(var, config[CONF_ESPECTRE_ID])
|
||||
parent = await cg.get_variable(config[CONF_ESPECTRE_ID])
|
||||
cg.add(parent.set_traffic_mode_select(var))
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "espectre_select.h"
|
||||
|
||||
#ifdef USE_ESPECTRE
|
||||
|
||||
namespace esphome::espectre {
|
||||
|
||||
void TrafficModeSelect::control(size_t index) { this->parent_->request_traffic_generator_mode(this->option_at(index)); }
|
||||
|
||||
} // namespace esphome::espectre
|
||||
|
||||
#endif // USE_ESPECTRE
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
|
||||
#ifdef USE_ESPECTRE
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../espectre.h"
|
||||
|
||||
namespace esphome::espectre {
|
||||
|
||||
class TrafficModeSelect final : public select::Select, public Parented<ESPectreComponent> {
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::espectre
|
||||
|
||||
#endif // USE_ESPECTRE
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "ezo.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::ezo {
|
||||
|
||||
static const char *const EZO_COMMAND_TYPE_STRINGS[] = {"EZO_READ", "EZO_LED", "EZO_DEVICE_INFORMATION",
|
||||
"EZO_SLOPE", "EZO_CALIBRATION", "EZO_SLEEP",
|
||||
"EZO_I2C", "EZO_T", "EZO_CUSTOM"};
|
||||
PROGMEM_STRING_TABLE(EzoCommandTypeStrings, "EZO_READ", "EZO_LED", "EZO_DEVICE_INFORMATION", "EZO_SLOPE",
|
||||
"EZO_CALIBRATION", "EZO_SLEEP", "EZO_I2C", "EZO_T", "EZO_CUSTOM");
|
||||
|
||||
static const char *const EZO_CALIBRATION_TYPE_STRINGS[] = {"LOW", "MID", "HIGH"};
|
||||
PROGMEM_STRING_TABLE(EzoCalibrationTypeStrings, "LOW", "MID", "HIGH");
|
||||
|
||||
void EZOSensor::dump_config() {
|
||||
LOG_SENSOR("", "EZO", this);
|
||||
@@ -103,7 +103,8 @@ void EZOSensor::loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Received buffer \"%s\" for command type %s", &buf[1], EZO_COMMAND_TYPE_STRINGS[to_run->command_type]);
|
||||
ESP_LOGV(TAG, "Received buffer \"%s\" for command type %s", &buf[1],
|
||||
LOG_STR_ARG(EzoCommandTypeStrings::get_log_str(to_run->command_type, EzoCommandTypeStrings::LAST_INDEX)));
|
||||
|
||||
if (buf[0] == 1) {
|
||||
std::string payload = reinterpret_cast<char *>(&buf[1]);
|
||||
@@ -168,7 +169,9 @@ void EZOSensor::add_command_(const char *command, EzoCommandType command_type, u
|
||||
void EZOSensor::set_calibration_point_(EzoCalibrationType type, float value) {
|
||||
// max 21: "Cal,"(4) + type(4) + ","(1) + float(11) + null; use 24 for safety
|
||||
char payload[24];
|
||||
snprintf(payload, sizeof(payload), "Cal,%s,%0.2f", EZO_CALIBRATION_TYPE_STRINGS[type], value);
|
||||
ESPHOME_snprintf_P(payload, sizeof(payload), ESPHOME_PSTR("Cal,%s,%0.2f"),
|
||||
LOG_STR_ARG(EzoCalibrationTypeStrings::get_log_str(type, EzoCalibrationTypeStrings::LAST_INDEX)),
|
||||
value);
|
||||
this->add_command_(payload, EzoCommandType::EZO_CALIBRATION, 900);
|
||||
}
|
||||
|
||||
@@ -176,7 +179,7 @@ void EZOSensor::set_address(uint8_t address) {
|
||||
if (address > 0 && address < 128) {
|
||||
// max 8: "I2C,"(4) + uint8(3) + null
|
||||
char payload[8];
|
||||
snprintf(payload, sizeof(payload), "I2C,%u", address);
|
||||
ESPHOME_snprintf_P(payload, sizeof(payload), ESPHOME_PSTR("I2C,%u"), address);
|
||||
this->new_address_ = address;
|
||||
this->add_command_(payload, EzoCommandType::EZO_I2C);
|
||||
} else {
|
||||
@@ -197,7 +200,7 @@ void EZOSensor::get_t() { this->add_command_("T,?", EzoCommandType::EZO_T); }
|
||||
void EZOSensor::set_t(float value) {
|
||||
// max 14 bytes: "T,"(2) + float with "%0.2f" (up to 11 chars) + null(1); use 16 for alignment
|
||||
char payload[16];
|
||||
snprintf(payload, sizeof(payload), "T,%0.2f", value);
|
||||
ESPHOME_snprintf_P(payload, sizeof(payload), ESPHOME_PSTR("T,%0.2f"), value);
|
||||
this->add_command_(payload, EzoCommandType::EZO_T);
|
||||
}
|
||||
|
||||
@@ -220,7 +223,7 @@ void EZOSensor::set_calibration_point_high(float value) {
|
||||
void EZOSensor::set_calibration_generic(float value) {
|
||||
// exact 16 bytes: "Cal," (4) + float with "%0.2f" (up to 11 chars, e.g. "-9999999.99") + null (1) = 16
|
||||
char payload[16];
|
||||
snprintf(payload, sizeof(payload), "Cal,%0.2f", value);
|
||||
ESPHOME_snprintf_P(payload, sizeof(payload), ESPHOME_PSTR("Cal,%0.2f"), value);
|
||||
this->add_command_(payload, EzoCommandType::EZO_CALIBRATION, 900);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "esphome/components/wifi/wifi_component.h"
|
||||
#endif
|
||||
#include "haier_base.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
using namespace esphome::climate;
|
||||
using namespace esphome::uart;
|
||||
@@ -19,28 +20,16 @@ constexpr size_t PROTOCOL_INITIALIZATION_INTERVAL = 10000;
|
||||
constexpr size_t DEFAULT_MESSAGES_INTERVAL_MS = 2000;
|
||||
constexpr size_t CONTROL_MESSAGES_INTERVAL_MS = 400;
|
||||
|
||||
const char *HaierClimateBase::phase_to_string_(ProtocolPhases phase) {
|
||||
static const char *phase_names[] = {
|
||||
"SENDING_INIT_1",
|
||||
"SENDING_INIT_2",
|
||||
"SENDING_FIRST_STATUS_REQUEST",
|
||||
"SENDING_FIRST_ALARM_STATUS_REQUEST",
|
||||
"IDLE",
|
||||
"SENDING_STATUS_REQUEST",
|
||||
"SENDING_UPDATE_SIGNAL_REQUEST",
|
||||
"SENDING_SIGNAL_LEVEL",
|
||||
"SENDING_CONTROL",
|
||||
"SENDING_ACTION_COMMAND",
|
||||
"SENDING_ALARM_STATUS_REQUEST",
|
||||
"UNKNOWN" // Should be the last!
|
||||
};
|
||||
static_assert(
|
||||
(sizeof(phase_names) / sizeof(char *)) == (((int) ProtocolPhases::NUM_PROTOCOL_PHASES) + 1),
|
||||
"Wrong phase_names array size. Please, make sure that this array is aligned with the enum ProtocolPhases");
|
||||
int phase_index = (int) phase;
|
||||
if ((phase_index > (int) ProtocolPhases::NUM_PROTOCOL_PHASES) || (phase_index < 0))
|
||||
phase_index = (int) ProtocolPhases::NUM_PROTOCOL_PHASES;
|
||||
return phase_names[phase_index];
|
||||
PROGMEM_STRING_TABLE(ProtocolPhaseStrings, "SENDING_INIT_1", "SENDING_INIT_2", "SENDING_FIRST_STATUS_REQUEST",
|
||||
"SENDING_FIRST_ALARM_STATUS_REQUEST", "IDLE", "SENDING_STATUS_REQUEST",
|
||||
"SENDING_UPDATE_SIGNAL_REQUEST", "SENDING_SIGNAL_LEVEL", "SENDING_CONTROL",
|
||||
"SENDING_ACTION_COMMAND", "SENDING_ALARM_STATUS_REQUEST", "UNKNOWN");
|
||||
|
||||
const LogString *HaierClimateBase::phase_to_string_(ProtocolPhases phase) {
|
||||
static_assert(ProtocolPhaseStrings::COUNT == ((int) ProtocolPhases::NUM_PROTOCOL_PHASES) + 1,
|
||||
"ProtocolPhaseStrings must match the enum ProtocolPhases, with UNKNOWN last");
|
||||
// UNKNOWN (-1) wraps past the table and reads as the last entry, "UNKNOWN"
|
||||
return ProtocolPhaseStrings::get_log_str(static_cast<uint8_t>(phase), ProtocolPhaseStrings::LAST_INDEX);
|
||||
}
|
||||
|
||||
bool check_timeout(std::chrono::steady_clock::time_point now, std::chrono::steady_clock::time_point tpoint,
|
||||
@@ -71,7 +60,8 @@ HaierClimateBase::~HaierClimateBase() {}
|
||||
|
||||
void HaierClimateBase::set_phase(ProtocolPhases phase) {
|
||||
if (this->protocol_phase_ != phase) {
|
||||
ESP_LOGV(TAG, "Phase transition: %s => %s", phase_to_string_(this->protocol_phase_), phase_to_string_(phase));
|
||||
ESP_LOGV(TAG, "Phase transition: %s => %s", LOG_STR_ARG(phase_to_string_(this->protocol_phase_)),
|
||||
LOG_STR_ARG(phase_to_string_(phase)));
|
||||
this->protocol_phase_ = phase;
|
||||
}
|
||||
}
|
||||
@@ -225,7 +215,7 @@ haier_protocol::HandlerError HaierClimateBase::report_network_status_answer_hand
|
||||
|
||||
haier_protocol::HandlerError HaierClimateBase::timeout_default_handler_(haier_protocol::FrameType request_type) {
|
||||
ESP_LOGW(TAG, "Answer timeout for command %02X, phase %s", (uint8_t) request_type,
|
||||
phase_to_string_(this->protocol_phase_));
|
||||
LOG_STR_ARG(phase_to_string_(this->protocol_phase_)));
|
||||
if (this->protocol_phase_ > ProtocolPhases::IDLE) {
|
||||
this->set_phase(ProtocolPhases::IDLE);
|
||||
} else {
|
||||
|
||||
@@ -95,7 +95,7 @@ class HaierClimateBase : public esphome::Component,
|
||||
SENDING_ALARM_STATUS_REQUEST,
|
||||
NUM_PROTOCOL_PHASES
|
||||
};
|
||||
const char *phase_to_string_(ProtocolPhases phase);
|
||||
const LogString *phase_to_string_(ProtocolPhases phase);
|
||||
virtual void set_handlers() = 0;
|
||||
virtual void process_phase(std::chrono::steady_clock::time_point now) = 0;
|
||||
virtual haier_protocol::HaierMessage get_control_message() = 0; // NOLINT(readability-identifier-naming)
|
||||
|
||||
@@ -564,7 +564,7 @@ void HonClimate::process_phase(std::chrono::steady_clock::time_point now) {
|
||||
default:
|
||||
// Shouldn't get here
|
||||
ESP_LOGE(TAG, "Wrong protocol handler state: %s (%d), resetting communication",
|
||||
phase_to_string_(this->protocol_phase_), (int) this->protocol_phase_);
|
||||
LOG_STR_ARG(phase_to_string_(this->protocol_phase_)), (int) this->protocol_phase_);
|
||||
this->set_phase(ProtocolPhases::SENDING_INIT_1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,12 @@ from ..climate import (
|
||||
CONF_HORIZONTAL_AIRFLOW,
|
||||
CONF_VERTICAL_AIRFLOW,
|
||||
HonClimate,
|
||||
haier_ns,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@paveldn"]
|
||||
VerticalAirflowSelect = haier_ns.class_("VerticalAirflowSelect", select.Select)
|
||||
HorizontalAirflowSelect = haier_ns.class_("HorizontalAirflowSelect", select.Select)
|
||||
|
||||
# Same order as VERTICAL_SWING_MODES_ORDER and HORIZONTAL_SWING_MODES_ORDER in hon_climate.h
|
||||
AIRFLOW_VERTICAL_DIRECTION_OPTIONS = [
|
||||
@@ -36,12 +39,12 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_HAIER_ID): cv.use_id(HonClimate),
|
||||
cv.Optional(CONF_VERTICAL_AIRFLOW): select.select_schema(
|
||||
select.ApplySelect,
|
||||
VerticalAirflowSelect,
|
||||
icon="mdi:arrow-expand-vertical",
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_HORIZONTAL_AIRFLOW): select.select_schema(
|
||||
select.ApplySelect,
|
||||
HorizontalAirflowSelect,
|
||||
icon="mdi:arrow-expand-horizontal",
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
@@ -56,13 +59,9 @@ async def to_code(config: ConfigType) -> None:
|
||||
CONF_VERTICAL_AIRFLOW,
|
||||
hub.set_vertical_airflow_select,
|
||||
options=AIRFLOW_VERTICAL_DIRECTION_OPTIONS,
|
||||
apply="set_vertical_airflow("
|
||||
"haier::airflow_order_at(haier::VERTICAL_SWING_MODES_ORDER, index))",
|
||||
)
|
||||
await selects(
|
||||
CONF_HORIZONTAL_AIRFLOW,
|
||||
hub.set_horizontal_airflow_select,
|
||||
options=AIRFLOW_HORIZONTAL_DIRECTION_OPTIONS,
|
||||
apply="set_horizontal_airflow("
|
||||
"haier::airflow_order_at(haier::HORIZONTAL_SWING_MODES_ORDER, index))",
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../hon_climate.h"
|
||||
|
||||
namespace esphome::haier {
|
||||
|
||||
class HorizontalAirflowSelect : public select::Select, public Parented<HonClimate> {
|
||||
protected:
|
||||
void control(size_t index) override {
|
||||
this->parent_->set_horizontal_airflow(airflow_order_at(HORIZONTAL_SWING_MODES_ORDER, index));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::haier
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../hon_climate.h"
|
||||
|
||||
namespace esphome::haier {
|
||||
|
||||
class VerticalAirflowSelect : public select::Select, public Parented<HonClimate> {
|
||||
protected:
|
||||
void control(size_t index) override {
|
||||
this->parent_->set_vertical_airflow(airflow_order_at(VERTICAL_SWING_MODES_ORDER, index));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::haier
|
||||
@@ -93,7 +93,7 @@ haier_protocol::HandlerError Smartair2Climate::messages_timeout_handler_with_cyc
|
||||
if (this->protocol_phase_ >= ProtocolPhases::IDLE)
|
||||
return HaierClimateBase::timeout_default_handler_(message_type);
|
||||
ESP_LOGI(TAG, "Answer timeout for command %02X, phase %s", (uint8_t) message_type,
|
||||
phase_to_string_(this->protocol_phase_));
|
||||
LOG_STR_ARG(phase_to_string_(this->protocol_phase_)));
|
||||
ProtocolPhases new_phase = (ProtocolPhases) ((int) this->protocol_phase_ + 1);
|
||||
if (new_phase >= ProtocolPhases::SENDING_FIRST_ALARM_STATUS_REQUEST)
|
||||
new_phase = ProtocolPhases::SENDING_INIT_1;
|
||||
@@ -217,7 +217,7 @@ void Smartair2Climate::process_phase(std::chrono::steady_clock::time_point now)
|
||||
default:
|
||||
// Shouldn't get here
|
||||
ESP_LOGE(TAG, "Wrong protocol handler state: %s (%d), resetting communication",
|
||||
phase_to_string_(this->protocol_phase_), (int) this->protocol_phase_);
|
||||
LOG_STR_ARG(phase_to_string_(this->protocol_phase_)), (int) this->protocol_phase_);
|
||||
this->set_phase(ProtocolPhases::SENDING_INIT_1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,20 @@
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::kamstrup_kmp {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "kamstrup_kmp");
|
||||
|
||||
// KMP units indexed by unit code; the empty first entry doubles as the fallback for unknown codes
|
||||
PROGMEM_STRING_TABLE(KmpUnits, "", "Wh", "kWh", "MWh", "GWh", "J", "kJ", "MJ", "GJ", "Cal", "kCal", "Mcal", "Gcal",
|
||||
"varh", "kvarh", "Mvarh", "Gvarh", "VAh", "kVAh", "MVAh", "GVAh", "kW", "kW", "MW", "GW", "kvar",
|
||||
"kvar", "Mvar", "Gvar", "VA", "kVA", "MVA", "GVA", "V", "A", "kV", "kA", "C", "K", "l", "m3",
|
||||
"l/h", "m3/h", "m3xC", "ton", "ton/h", "h", "hh:mm:ss", "yy:mm:dd", "yyyy:mm:dd", "mm:dd", "",
|
||||
"bar", "RTC", "ASCII", "m3 x 10", "ton x 10", "GJ x 10", "minutes", "Bitfield", "s", "ms", "days",
|
||||
"RTC-Q", "Datetime");
|
||||
|
||||
void KamstrupKMPComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "kamstrup_kmp:");
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
@@ -237,8 +246,6 @@ void KamstrupKMPComponent::parse_command_message_(uint16_t command, const uint8_
|
||||
}
|
||||
|
||||
void KamstrupKMPComponent::set_sensor_value_(uint16_t command, float value, uint8_t unit_idx) {
|
||||
const char *unit = unit_idx < sizeof(UNITS) / sizeof(UNITS[0]) ? UNITS[unit_idx] : "";
|
||||
|
||||
// Standard sensors
|
||||
if (command == CMD_HEAT_ENERGY && this->heat_energy_sensor_ != nullptr) {
|
||||
this->heat_energy_sensor_->publish_state(value);
|
||||
@@ -263,7 +270,8 @@ void KamstrupKMPComponent::set_sensor_value_(uint16_t command, float value, uint
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Received value for command 0x%04X: %.3f [%s]", command, value, unit);
|
||||
ESP_LOGD(TAG, "Received value for command 0x%04X: %.3f [%s]", command, value,
|
||||
LOG_STR_ARG(KmpUnits::get_log_str(unit_idx, 0)));
|
||||
}
|
||||
|
||||
} // namespace esphome::kamstrup_kmp
|
||||
@@ -63,16 +63,6 @@ static const uint16_t CMD_TEMP_DIFF = 0x0059;
|
||||
static const uint16_t CMD_FLOW = 0x004A;
|
||||
static const uint16_t CMD_VOLUME = 0x0044;
|
||||
|
||||
// KMP units
|
||||
static const char *const UNITS[] = {
|
||||
"", "Wh", "kWh", "MWh", "GWh", "J", "kJ", "MJ", "GJ", "Cal",
|
||||
"kCal", "Mcal", "Gcal", "varh", "kvarh", "Mvarh", "Gvarh", "VAh", "kVAh", "MVAh",
|
||||
"GVAh", "kW", "kW", "MW", "GW", "kvar", "kvar", "Mvar", "Gvar", "VA",
|
||||
"kVA", "MVA", "GVA", "V", "A", "kV", "kA", "C", "K", "l",
|
||||
"m3", "l/h", "m3/h", "m3xC", "ton", "ton/h", "h", "hh:mm:ss", "yy:mm:dd", "yyyy:mm:dd",
|
||||
"mm:dd", "", "bar", "RTC", "ASCII", "m3 x 10", "ton x 10", "GJ x 10", "minutes", "Bitfield",
|
||||
"s", "ms", "days", "RTC-Q", "Datetime"};
|
||||
|
||||
class KamstrupKMPComponent final : public PollingComponent, public uart::UARTDevice {
|
||||
public:
|
||||
void set_heat_energy_sensor(sensor::Sensor *sensor) { this->heat_energy_sensor_ = sensor; }
|
||||
|
||||
@@ -13,7 +13,11 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2410_ID, LD2410Component
|
||||
from .. import CONF_LD2410_ID, LD2410Component, ld2410_ns
|
||||
|
||||
BaudRateSelect = ld2410_ns.class_("BaudRateSelect", select.Select)
|
||||
DistanceResolutionSelect = ld2410_ns.class_("DistanceResolutionSelect", select.Select)
|
||||
LightOutControlSelect = ld2410_ns.class_("LightOutControlSelect", select.Select)
|
||||
|
||||
CONF_DISTANCE_RESOLUTION = "distance_resolution"
|
||||
CONF_LIGHT_FUNCTION = "light_function"
|
||||
@@ -23,22 +27,22 @@ CONFIG_SCHEMA = {
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(cg.EntityBase),
|
||||
cv.GenerateID(CONF_LD2410_ID): cv.use_id(LD2410Component),
|
||||
cv.Optional(CONF_DISTANCE_RESOLUTION): select.select_schema(
|
||||
select.ApplySelect,
|
||||
DistanceResolutionSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_RULER,
|
||||
),
|
||||
cv.Optional(CONF_LIGHT_FUNCTION): select.select_schema(
|
||||
select.ApplySelect,
|
||||
LightOutControlSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_LIGHTBULB,
|
||||
),
|
||||
cv.Optional(CONF_OUT_PIN_LEVEL): select.select_schema(
|
||||
select.ApplySelect,
|
||||
LightOutControlSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_SCALE,
|
||||
),
|
||||
cv.Optional(CONF_BAUD_RATE): select.select_schema(
|
||||
select.ApplySelect,
|
||||
BaudRateSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_THERMOMETER,
|
||||
),
|
||||
@@ -53,30 +57,18 @@ async def to_code(config: ConfigType) -> None:
|
||||
CONF_DISTANCE_RESOLUTION,
|
||||
hub.set_distance_resolution_select,
|
||||
options=["0.2m", "0.75m"],
|
||||
apply=(
|
||||
"set_distance_resolution(static_cast<ld2410::DistanceResolution>("
|
||||
"progmem_read_byte(&ld2410::DISTANCE_RESOLUTIONS[index])))"
|
||||
),
|
||||
publish="before",
|
||||
)
|
||||
light = {"apply": "set_light_out_control()", "publish": "before"}
|
||||
await selects(
|
||||
CONF_OUT_PIN_LEVEL,
|
||||
hub.set_out_pin_level_select,
|
||||
options=["low", "high"],
|
||||
**light,
|
||||
CONF_OUT_PIN_LEVEL, hub.set_out_pin_level_select, options=["low", "high"]
|
||||
)
|
||||
await selects(
|
||||
CONF_LIGHT_FUNCTION,
|
||||
hub.set_light_function_select,
|
||||
options=["off", "below", "above"],
|
||||
**light,
|
||||
)
|
||||
await selects(
|
||||
CONF_BAUD_RATE,
|
||||
hub.set_baud_rate_select,
|
||||
apply="set_baud_rate(static_cast<ld2410::BaudRate>(index + 1))",
|
||||
publish="before",
|
||||
options=[
|
||||
"9600",
|
||||
"19200",
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "baud_rate_select.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
void BaudRateSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_baud_rate(static_cast<BaudRate>(index + 1));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2410.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
class BaudRateSelect final : public select::Select, public Parented<LD2410Component> {
|
||||
public:
|
||||
BaudRateSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "distance_resolution_select.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
void DistanceResolutionSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_distance_resolution(
|
||||
static_cast<DistanceResolution>(progmem_read_byte(&DISTANCE_RESOLUTIONS[index])));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2410.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
class DistanceResolutionSelect final : public select::Select, public Parented<LD2410Component> {
|
||||
public:
|
||||
DistanceResolutionSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "light_out_control_select.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
void LightOutControlSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_light_out_control();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2410.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
class LightOutControlSelect final : public select::Select, public Parented<LD2410Component> {
|
||||
public:
|
||||
LightOutControlSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -13,7 +13,11 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2412_ID, LD2412Component
|
||||
from .. import CONF_LD2412_ID, LD2412_ns, LD2412Component
|
||||
|
||||
BaudRateSelect = LD2412_ns.class_("BaudRateSelect", select.Select)
|
||||
DistanceResolutionSelect = LD2412_ns.class_("DistanceResolutionSelect", select.Select)
|
||||
LightOutControlSelect = LD2412_ns.class_("LightOutControlSelect", select.Select)
|
||||
|
||||
CONF_DISTANCE_RESOLUTION = "distance_resolution"
|
||||
CONF_LIGHT_FUNCTION = "light_function"
|
||||
@@ -23,17 +27,17 @@ CONFIG_SCHEMA = {
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(cg.EntityBase),
|
||||
cv.GenerateID(CONF_LD2412_ID): cv.use_id(LD2412Component),
|
||||
cv.Optional(CONF_BAUD_RATE): select.select_schema(
|
||||
select.ApplySelect,
|
||||
BaudRateSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_THERMOMETER,
|
||||
),
|
||||
cv.Optional(CONF_DISTANCE_RESOLUTION): select.select_schema(
|
||||
select.ApplySelect,
|
||||
DistanceResolutionSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_RULER,
|
||||
),
|
||||
cv.Optional(CONF_LIGHT_FUNCTION): select.select_schema(
|
||||
select.ApplySelect,
|
||||
LightOutControlSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_LIGHTBULB,
|
||||
),
|
||||
@@ -62,25 +66,16 @@ async def to_code(config: ConfigType) -> None:
|
||||
"256000",
|
||||
"460800",
|
||||
],
|
||||
apply="set_baud_rate(static_cast<ld2412::BaudRate>(index + 1))",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_DISTANCE_RESOLUTION,
|
||||
hub.set_distance_resolution_select,
|
||||
options=["0.2m", "0.5m", "0.75m"],
|
||||
apply=(
|
||||
"set_distance_resolution(static_cast<ld2412::DistanceResolution>("
|
||||
"progmem_read_byte(&ld2412::DISTANCE_RESOLUTIONS[index])))"
|
||||
),
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_LIGHT_FUNCTION,
|
||||
hub.set_light_function_select,
|
||||
options=["off", "below", "above"],
|
||||
apply="set_light_out_control()",
|
||||
publish="before",
|
||||
)
|
||||
# The pin level travels in the basic configuration command, not the light control one
|
||||
await selects(
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "baud_rate_select.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
void BaudRateSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_baud_rate(static_cast<BaudRate>(index + 1));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2412.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
class BaudRateSelect final : public select::Select, public Parented<LD2412Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) BaudRateSelect()` would zero-fill .bss that is already zero.
|
||||
BaudRateSelect() {}
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "distance_resolution_select.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
void DistanceResolutionSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_distance_resolution(
|
||||
static_cast<DistanceResolution>(progmem_read_byte(&DISTANCE_RESOLUTIONS[index])));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2412.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
class DistanceResolutionSelect final : public select::Select, public Parented<LD2412Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) DistanceResolutionSelect()` would zero-fill .bss that is already zero.
|
||||
DistanceResolutionSelect() {}
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "light_out_control_select.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
void LightOutControlSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_light_out_control();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2412.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
class LightOutControlSelect final : public select::Select, public Parented<LD2412Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) LightOutControlSelect()` would zero-fill .bss that is already zero.
|
||||
LightOutControlSelect() {}
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -4,7 +4,7 @@ import esphome.config_validation as cv
|
||||
from esphome.const import ENTITY_CATEGORY_CONFIG
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2420_ID, LD2420Component
|
||||
from .. import CONF_LD2420_ID, LD2420Component, ld2420_ns
|
||||
|
||||
CONF_OPERATING_MODE = "operating_mode"
|
||||
CONF_SELECTS = [
|
||||
@@ -13,11 +13,12 @@ CONF_SELECTS = [
|
||||
"Simple",
|
||||
]
|
||||
|
||||
LD2420Select = ld2420_ns.class_("LD2420Select", select.Select, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
cv.GenerateID(CONF_LD2420_ID): cv.use_id(LD2420Component),
|
||||
cv.Required(CONF_OPERATING_MODE): select.select_schema(
|
||||
select.ApplySelect,
|
||||
LD2420Select,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
}
|
||||
@@ -27,9 +28,5 @@ async def to_code(config: ConfigType) -> None:
|
||||
hub = await cg.get_variable(config[CONF_LD2420_ID])
|
||||
selects = select.sub_selects(config, parent=hub)
|
||||
await selects(
|
||||
CONF_OPERATING_MODE,
|
||||
hub.set_operating_mode_select,
|
||||
options=CONF_SELECTS,
|
||||
apply="set_operating_mode(static_cast<ld2420::OpMode>(index + 1))",
|
||||
publish="before",
|
||||
CONF_OPERATING_MODE, hub.set_operating_mode_select, options=CONF_SELECTS
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "operating_mode_select.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome::ld2420 {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "ld2420.select");
|
||||
|
||||
void LD2420Select::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_operating_mode(static_cast<OpMode>(index + 1));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2420
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ld2420.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
|
||||
namespace esphome::ld2420 {
|
||||
|
||||
class LD2420Select final : public Component, public select::Select, public Parented<LD2420Component> {
|
||||
public:
|
||||
LD2420Select() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2420
|
||||
@@ -9,21 +9,23 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2450_ID, LD2450Component
|
||||
from .. import CONF_LD2450_ID, LD2450Component, ld2450_ns
|
||||
|
||||
CONF_ZONE_TYPE = "zone_type"
|
||||
|
||||
BaudRateSelect = ld2450_ns.class_("BaudRateSelect", select.Select)
|
||||
ZoneTypeSelect = ld2450_ns.class_("ZoneTypeSelect", select.Select)
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(cg.EntityBase),
|
||||
cv.GenerateID(CONF_LD2450_ID): cv.use_id(LD2450Component),
|
||||
cv.Optional(CONF_BAUD_RATE): select.select_schema(
|
||||
select.ApplySelect,
|
||||
BaudRateSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_THERMOMETER,
|
||||
),
|
||||
cv.Optional(CONF_ZONE_TYPE): select.select_schema(
|
||||
select.ApplySelect,
|
||||
ZoneTypeSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_THERMOMETER,
|
||||
),
|
||||
@@ -47,8 +49,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
"256000",
|
||||
"460800",
|
||||
],
|
||||
apply="set_baud_rate(static_cast<ld2450::BaudRate>(index + 1))",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_ZONE_TYPE,
|
||||
@@ -58,6 +58,4 @@ async def to_code(config: ConfigType) -> None:
|
||||
"Detection",
|
||||
"Filter",
|
||||
],
|
||||
apply="set_zone_type(static_cast<ld2450::ZoneType>(index))",
|
||||
publish="before",
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "baud_rate_select.h"
|
||||
|
||||
namespace esphome::ld2450 {
|
||||
|
||||
void BaudRateSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_baud_rate(static_cast<BaudRate>(index + 1));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2450
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2450.h"
|
||||
|
||||
namespace esphome::ld2450 {
|
||||
|
||||
class BaudRateSelect : public select::Select, public Parented<LD2450Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) BaudRateSelect()` would zero-fill .bss that is already zero.
|
||||
BaudRateSelect() {}
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2450
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "zone_type_select.h"
|
||||
|
||||
namespace esphome::ld2450 {
|
||||
|
||||
void ZoneTypeSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_zone_type(static_cast<ZoneType>(index));
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2450
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../ld2450.h"
|
||||
|
||||
namespace esphome::ld2450 {
|
||||
|
||||
class ZoneTypeSelect : public select::Select, public Parented<LD2450Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) ZoneTypeSelect()` would zero-fill .bss that is already zero.
|
||||
ZoneTypeSelect() {}
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2450
|
||||
@@ -1,9 +1,13 @@
|
||||
#include "micronova_text_sensor.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::micronova {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "micronova.text_sensor");
|
||||
|
||||
PROGMEM_STRING_TABLE(StoveStateStrings, "Off", "Start", "Pellets loading", "Ignition", "Working", "Brazier Cleaning",
|
||||
"Final Cleaning", "Standby", "No pellets alarm", "No ignition alarm", "Undefined alarm");
|
||||
|
||||
void MicroNovaTextSensor::dump_config() {
|
||||
LOG_TEXT_SENSOR("", "Micronova text sensor", this);
|
||||
this->dump_base_config();
|
||||
@@ -15,7 +19,9 @@ void MicroNovaTextSensor::process_value_from_stove(int value_from_stove) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->publish_state(STOVE_STATES[value_from_stove]);
|
||||
// Values past the table read as "Undefined alarm"
|
||||
this->publish_state(
|
||||
StoveStateStrings::get_progmem_str(static_cast<uint8_t>(value_from_stove), StoveStateStrings::LAST_INDEX));
|
||||
}
|
||||
|
||||
} // namespace esphome::micronova
|
||||
@@ -5,18 +5,6 @@
|
||||
|
||||
namespace esphome::micronova {
|
||||
|
||||
static const char *const STOVE_STATES[11] = {"Off",
|
||||
"Start",
|
||||
"Pellets loading",
|
||||
"Ignition",
|
||||
"Working",
|
||||
"Brazier Cleaning",
|
||||
"Final Cleaning",
|
||||
"Standby",
|
||||
"No pellets alarm",
|
||||
"No ignition alarm",
|
||||
"Undefined alarm"};
|
||||
|
||||
class MicroNovaTextSensor final : public text_sensor::TextSensor, public MicroNovaListener {
|
||||
public:
|
||||
MicroNovaTextSensor(MicroNova *m) : MicroNovaListener(m) {}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "pulse_counter_sensor.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
#ifdef HAS_PCNT
|
||||
#include <driver/gpio.h>
|
||||
@@ -11,7 +12,7 @@ namespace esphome::pulse_counter {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "pulse_counter");
|
||||
|
||||
const char *const EDGE_MODE_TO_STRING[] = {"DISABLE", "INCREMENT", "DECREMENT"};
|
||||
PROGMEM_STRING_TABLE(EdgeModeStrings, "DISABLE", "INCREMENT", "DECREMENT");
|
||||
|
||||
#ifdef HAS_PCNT
|
||||
PulseCounterStorageBase *get_storage(bool hw_pcnt) {
|
||||
@@ -227,8 +228,9 @@ void PulseCounterSensor::dump_config() {
|
||||
" Rising Edge: %s\n"
|
||||
" Falling Edge: %s\n"
|
||||
" Filtering pulses shorter than %" PRIu32 " µs",
|
||||
EDGE_MODE_TO_STRING[this->storage_.rising_edge_mode],
|
||||
EDGE_MODE_TO_STRING[this->storage_.falling_edge_mode], this->storage_.filter_us);
|
||||
LOG_STR_ARG(EdgeModeStrings::get_log_str(this->storage_.rising_edge_mode, 0)),
|
||||
LOG_STR_ARG(EdgeModeStrings::get_log_str(this->storage_.falling_edge_mode, 0)),
|
||||
this->storage_.filter_us);
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@@ -11,6 +12,11 @@ ESPHOME_LOG_TAG(TAG, "seeed_mr24hpc1");
|
||||
|
||||
static constexpr uint32_t STARTUP_DELAY_MS = 1000;
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
PROGMEM_STRING_TABLE(MotionStatusStrings, "None", "Motionless", "Active");
|
||||
PROGMEM_STRING_TABLE(KeepAwayStrings, "None", "Close", "Away");
|
||||
#endif
|
||||
|
||||
// Prints the component's configuration data. dump_config() prints all of the component's configuration
|
||||
// items in an easy-to-read format, including the configuration key-value pairs.
|
||||
void MR24HPC1Component::dump_config() {
|
||||
@@ -434,10 +440,9 @@ void MR24HPC1Component::r24_frame_parse_open_underlying_information_(uint8_t *da
|
||||
}
|
||||
break;
|
||||
case 0x83:
|
||||
if (this->custom_presence_of_detection_sensor_ != nullptr &&
|
||||
data[FRAME_DATA_INDEX] < std::size(S_PRESENCE_OF_DETECTION_RANGE_STR)) {
|
||||
this->custom_presence_of_detection_sensor_->publish_state(
|
||||
S_PRESENCE_OF_DETECTION_RANGE_STR[data[FRAME_DATA_INDEX]]);
|
||||
// 0 to 3 m in steps of 0.5 m
|
||||
if (this->custom_presence_of_detection_sensor_ != nullptr && data[FRAME_DATA_INDEX] <= 6) {
|
||||
this->custom_presence_of_detection_sensor_->publish_state(data[FRAME_DATA_INDEX] * 0.5f);
|
||||
}
|
||||
break;
|
||||
case 0x84:
|
||||
@@ -455,8 +460,9 @@ void MR24HPC1Component::r24_frame_parse_open_underlying_information_(uint8_t *da
|
||||
case 0x06:
|
||||
case 0x86:
|
||||
// none:0x00 close_to:0x01 far_away:0x02
|
||||
if ((this->keep_away_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < 3)) {
|
||||
this->keep_away_text_sensor_->publish_state(S_KEEP_AWAY_STR[data[FRAME_DATA_INDEX]]);
|
||||
if ((this->keep_away_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < KeepAwayStrings::COUNT)) {
|
||||
this->keep_away_text_sensor_->publish_state(
|
||||
KeepAwayStrings::get_progmem_str(data[FRAME_DATA_INDEX], KeepAwayStrings::LAST_INDEX));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -629,8 +635,8 @@ void MR24HPC1Component::r24_frame_parse_human_information_(uint8_t *data) {
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
case 0x01:
|
||||
case 0x81:
|
||||
if (this->has_target_binary_sensor_ != nullptr && data[FRAME_DATA_INDEX] < std::size(S_SOMEONE_EXISTS_STR)) {
|
||||
this->has_target_binary_sensor_->publish_state(S_SOMEONE_EXISTS_STR[data[FRAME_DATA_INDEX]]);
|
||||
if (this->has_target_binary_sensor_ != nullptr && data[FRAME_DATA_INDEX] <= 1) {
|
||||
this->has_target_binary_sensor_->publish_state(data[FRAME_DATA_INDEX] == 1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -645,15 +651,17 @@ void MR24HPC1Component::r24_frame_parse_human_information_(uint8_t *data) {
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
case 0x02:
|
||||
case 0x82:
|
||||
if ((this->motion_status_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < 3)) {
|
||||
this->motion_status_text_sensor_->publish_state(S_MOTION_STATUS_STR[data[FRAME_DATA_INDEX]]);
|
||||
if ((this->motion_status_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < MotionStatusStrings::COUNT)) {
|
||||
this->motion_status_text_sensor_->publish_state(
|
||||
MotionStatusStrings::get_progmem_str(data[FRAME_DATA_INDEX], MotionStatusStrings::LAST_INDEX));
|
||||
}
|
||||
break;
|
||||
case 0x0B:
|
||||
case 0x8B:
|
||||
// none:0x00 close_to:0x01 far_away:0x02
|
||||
if ((this->keep_away_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < 3)) {
|
||||
this->keep_away_text_sensor_->publish_state(S_KEEP_AWAY_STR[data[FRAME_DATA_INDEX]]);
|
||||
if ((this->keep_away_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < KeepAwayStrings::COUNT)) {
|
||||
this->keep_away_text_sensor_->publish_state(
|
||||
KeepAwayStrings::get_progmem_str(data[FRAME_DATA_INDEX], KeepAwayStrings::LAST_INDEX));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -82,16 +82,6 @@ enum OutputSwitch {
|
||||
OUTPUT_SWTICH_OFF,
|
||||
};
|
||||
|
||||
static const char *const S_SCENE_STR[5] = {"None", "Living Room", "Bedroom", "Washroom", "Area Detection"};
|
||||
static const bool S_SOMEONE_EXISTS_STR[2] = {false, true};
|
||||
static const char *const S_MOTION_STATUS_STR[3] = {"None", "Motionless", "Active"};
|
||||
static const char *const S_KEEP_AWAY_STR[3] = {"None", "Close", "Away"};
|
||||
static const char *const S_UNMANNED_TIME_STR[9] = {"None", "10s", "30s", "1min", "2min",
|
||||
"5min", "10min", "30min", "60min"};
|
||||
static const char *const S_BOUNDARY_STR[10] = {"0.5m", "1.0m", "1.5m", "2.0m", "2.5m",
|
||||
"3.0m", "3.5m", "4.0m", "4.5m", "5.0m"}; // uint: m
|
||||
static const float S_PRESENCE_OF_DETECTION_RANGE_STR[7] = {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f}; // uint: m
|
||||
|
||||
class MR24HPC1Component final : public Component,
|
||||
public uart::UARTDevice { // The class name must be the name defined by text_sensor.py
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
|
||||
@@ -4,7 +4,12 @@ import esphome.config_validation as cv
|
||||
from esphome.const import ENTITY_CATEGORY_CONFIG
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_MR24HPC1_ID, MR24HPC1Component
|
||||
from .. import CONF_MR24HPC1_ID, MR24HPC1Component, mr24hpc1_ns
|
||||
|
||||
SceneModeSelect = mr24hpc1_ns.class_("SceneModeSelect", select.Select)
|
||||
UnmanTimeSelect = mr24hpc1_ns.class_("UnmanTimeSelect", select.Select)
|
||||
ExistenceBoundarySelect = mr24hpc1_ns.class_("ExistenceBoundarySelect", select.Select)
|
||||
MotionBoundarySelect = mr24hpc1_ns.class_("MotionBoundarySelect", select.Select)
|
||||
|
||||
CONF_SCENE_MODE = "scene_mode"
|
||||
CONF_UNMAN_TIME = "unman_time"
|
||||
@@ -14,21 +19,21 @@ CONF_MOTION_BOUNDARY = "motion_boundary"
|
||||
CONFIG_SCHEMA = {
|
||||
cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component),
|
||||
cv.Optional(CONF_SCENE_MODE): select.select_schema(
|
||||
select.ApplySelect,
|
||||
SceneModeSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:hoop-house",
|
||||
),
|
||||
cv.Optional(CONF_UNMAN_TIME): select.select_schema(
|
||||
select.ApplySelect,
|
||||
UnmanTimeSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:timeline-clock",
|
||||
),
|
||||
cv.Optional(CONF_EXISTENCE_BOUNDARY): select.select_schema(
|
||||
select.ApplySelect,
|
||||
ExistenceBoundarySelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_MOTION_BOUNDARY): select.select_schema(
|
||||
select.ApplySelect,
|
||||
MotionBoundarySelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
}
|
||||
@@ -41,8 +46,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
CONF_SCENE_MODE,
|
||||
hub.set_scene_mode_select,
|
||||
options=["None", "Living Room", "Bedroom", "Washroom", "Area Detection"],
|
||||
apply="set_scene_mode(index)",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_UNMAN_TIME,
|
||||
@@ -58,8 +61,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
"30min",
|
||||
"60min",
|
||||
],
|
||||
apply="set_unman_time(index)",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_EXISTENCE_BOUNDARY,
|
||||
@@ -76,8 +77,6 @@ async def to_code(config: ConfigType) -> None:
|
||||
"4.5m",
|
||||
"5.0m",
|
||||
],
|
||||
apply="set_existence_boundary(index)",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_MOTION_BOUNDARY,
|
||||
@@ -94,6 +93,4 @@ async def to_code(config: ConfigType) -> None:
|
||||
"4.5m",
|
||||
"5.0m",
|
||||
],
|
||||
apply="set_motion_boundary(index)",
|
||||
publish="before",
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "existence_boundary_select.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void ExistenceBoundarySelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_existence_boundary(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class ExistenceBoundarySelect final : public select::Select, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
ExistenceBoundarySelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "motion_boundary_select.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void MotionBoundarySelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_motion_boundary(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class MotionBoundarySelect final : public select::Select, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
MotionBoundarySelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "scene_mode_select.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void SceneModeSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_scene_mode(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class SceneModeSelect final : public select::Select, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
SceneModeSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "unman_time_select.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void UnmanTimeSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_unman_time(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class UnmanTimeSelect final : public select::Select, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
UnmanTimeSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -4,10 +4,13 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_SENSITIVITY, ENTITY_CATEGORY_CONFIG, ICON_ACCELERATION_Z
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_MR60FDA2_ID, MR60FDA2Component
|
||||
from .. import CONF_MR60FDA2_ID, MR60FDA2Component, mr60fda2_ns
|
||||
|
||||
DEPENDENCIES = ["seeed_mr60fda2"]
|
||||
|
||||
InstallHeightSelect = mr60fda2_ns.class_("InstallHeightSelect", select.Select)
|
||||
HeightThresholdSelect = mr60fda2_ns.class_("HeightThresholdSelect", select.Select)
|
||||
SensitivitySelect = mr60fda2_ns.class_("SensitivitySelect", select.Select)
|
||||
|
||||
CONF_INSTALL_HEIGHT = "install_height"
|
||||
CONF_HEIGHT_THRESHOLD = "height_threshold"
|
||||
@@ -15,17 +18,17 @@ CONF_HEIGHT_THRESHOLD = "height_threshold"
|
||||
CONFIG_SCHEMA = {
|
||||
cv.GenerateID(CONF_MR60FDA2_ID): cv.use_id(MR60FDA2Component),
|
||||
cv.Optional(CONF_INSTALL_HEIGHT): select.select_schema(
|
||||
select.ApplySelect,
|
||||
InstallHeightSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_ACCELERATION_Z,
|
||||
),
|
||||
cv.Optional(CONF_HEIGHT_THRESHOLD): select.select_schema(
|
||||
select.ApplySelect,
|
||||
HeightThresholdSelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_ACCELERATION_Z,
|
||||
),
|
||||
cv.Optional(CONF_SENSITIVITY): select.select_schema(
|
||||
select.ApplySelect,
|
||||
SensitivitySelect,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
}
|
||||
@@ -38,20 +41,10 @@ async def to_code(config: ConfigType) -> None:
|
||||
CONF_INSTALL_HEIGHT,
|
||||
hub.set_install_height_select,
|
||||
options=["2.4m", "2.5m", "2.6m", "2.7m", "2.8m", "2.9m", "3.0m"],
|
||||
apply="set_install_height(index)",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_HEIGHT_THRESHOLD,
|
||||
hub.set_height_threshold_select,
|
||||
options=["0.0m", "0.1m", "0.2m", "0.3m", "0.4m", "0.5m", "0.6m"],
|
||||
apply="set_height_threshold(index)",
|
||||
publish="before",
|
||||
)
|
||||
await selects(
|
||||
CONF_SENSITIVITY,
|
||||
hub.set_sensitivity_select,
|
||||
options=["1", "2", "3"],
|
||||
apply="set_sensitivity(index)",
|
||||
publish="before",
|
||||
)
|
||||
await selects(CONF_SENSITIVITY, hub.set_sensitivity_select, options=["1", "2", "3"])
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "height_threshold_select.h"
|
||||
|
||||
namespace esphome::seeed_mr60fda2 {
|
||||
|
||||
void HeightThresholdSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_height_threshold(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr60fda2
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr60fda2.h"
|
||||
|
||||
namespace esphome::seeed_mr60fda2 {
|
||||
|
||||
class HeightThresholdSelect final : public select::Select, public Parented<MR60FDA2Component> {
|
||||
public:
|
||||
HeightThresholdSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr60fda2
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "install_height_select.h"
|
||||
|
||||
namespace esphome::seeed_mr60fda2 {
|
||||
|
||||
void InstallHeightSelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_install_height(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr60fda2
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr60fda2.h"
|
||||
|
||||
namespace esphome::seeed_mr60fda2 {
|
||||
|
||||
class InstallHeightSelect final : public select::Select, public Parented<MR60FDA2Component> {
|
||||
public:
|
||||
InstallHeightSelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr60fda2
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "sensitivity_select.h"
|
||||
|
||||
namespace esphome::seeed_mr60fda2 {
|
||||
|
||||
void SensitivitySelect::control(size_t index) {
|
||||
this->publish_state(index);
|
||||
this->parent_->set_sensitivity(index);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr60fda2
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "../seeed_mr60fda2.h"
|
||||
|
||||
namespace esphome::seeed_mr60fda2 {
|
||||
|
||||
class SensitivitySelect final : public select::Select, public Parented<MR60FDA2Component> {
|
||||
public:
|
||||
SensitivitySelect() = default;
|
||||
|
||||
protected:
|
||||
void control(size_t index) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr60fda2
|
||||
Reference in new issue
Block a user