v.0.2.9 (inverter power limitaption) - first commit

This commit is contained in:
GrKoR
2023-01-10 17:56:14 +04:00
parent a29326c9eb
commit 252fefbece
5 changed files with 587 additions and 29 deletions

View File

@@ -154,5 +154,33 @@ class AirConSendTestPacketAction : public Action<Ts...> {
std::vector<uint8_t> data_static_{};
};
// **************************************** POWER LIMITATION ACTIONS ****************************************
template <typename... Ts>
class AirConPowerLimitationOffAction : public Action<Ts...> {
public:
explicit AirConPowerLimitationOffAction(AirCon *ac) : ac_(ac) {}
void play(Ts... x) override { this->ac_->powerLimitationOffSequence(); }
protected:
AirCon *ac_;
};
template <typename... Ts>
class AirConPowerLimitationOnAction : public Action<Ts...> {
public:
AirConPowerLimitationOnAction(AirCon *ac) : ac_(ac) {}
TEMPLATABLE_VALUE(uint8_t, value);
void play(Ts... x) {
this->pwr_lim_ = this->value_.value(x...);
this->ac_->powerLimitationOnSequence(this->pwr_lim_);
}
protected:
AirCon *ac_;
uint8_t pwr_lim_;
};
} // namespace aux_ac
} // namespace esphome

View File

@@ -56,13 +56,17 @@ class Constants {
/// шаг изменения целевой температуры, градусы Цельсия
static const float AC_TEMPERATURE_STEP;
/// минимальное и максимальное значение мощности инвертора при установке ограничений
static const uint8_t AC_MIN_INVERTER_POWER_LIMIT;
static const uint8_t AC_MAX_INVERTER_POWER_LIMIT;
// периодичность опроса кондиционера на предмет изменения состояния
// изменение параметров с пульта не сообщается в UART, поэтому надо запрашивать состояние, чтобы быть в курсе
// значение в миллисекундах
static const uint32_t AC_STATES_REQUEST_INTERVAL;
};
const std::string Constants::AC_FIRMWARE_VERSION = "0.2.8";
const std::string Constants::AC_FIRMWARE_VERSION = "0.2.9 dev";
// custom fan modes
const std::string Constants::MUTE = "mute";
@@ -77,6 +81,8 @@ const std::string Constants::ANTIFUNGUS = "Antifungus";
const float Constants::AC_MIN_TEMPERATURE = 16.0;
const float Constants::AC_MAX_TEMPERATURE = 32.0;
const float Constants::AC_TEMPERATURE_STEP = 0.5;
const uint8_t Constants::AC_MIN_INVERTER_POWER_LIMIT = 30; // 30%
const uint8_t Constants::AC_MAX_INVERTER_POWER_LIMIT = 100; // 100%
const uint32_t Constants::AC_STATES_REQUEST_INTERVAL = 7000;
class AirCon;
@@ -319,20 +325,50 @@ struct packet_big_info_body_t {
// тело малого информационного пакета
// https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11
struct packet_small_info_body_t {
// байт 8 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b08
uint8_t byte_01;
// байт 9 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b09
uint8_t cmd_answer;
// байт 10 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b10
uint8_t target_temp_int_and_v_louver;
// байт 11 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b11
uint8_t h_louver;
// байт 12 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b12
uint8_t target_temp_frac;
// байт 13 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b13
uint8_t fan_speed;
// байт 14 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b14
uint8_t fan_turbo_and_mute;
// байт 15 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b15
uint8_t mode;
// байт 16 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b16
uint8_t zero1; // всегда 0x00
// байт 17 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b17
uint8_t zero2; // всегда 0x00
// байт 18 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b18
uint8_t status;
// байт 19 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b19
uint8_t zero3; // всегда 0x00
// байт 20 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b20
uint8_t display_and_mildew;
uint8_t zero4; // всегда 0x00
// байт 21 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b21
bool inverter_power_limitation_enable : 1;
uint8_t inverter_power_limitation_value : 7;
// байт 22 пакета: https://github.com/GrKoR/AUX_HVAC_Protocol#packet_cmd_11_b22
uint8_t target_temp_frac2;
};
@@ -475,6 +511,10 @@ enum ac_mildew : uint8_t { AC_MILDEW_OFF = 0x00,
// GK: define убрал, т.к. считаю, что сбрасывать счетчик не надо.
// #define AC_MIN_COUNTER_MASK 0b00111111
// маски ограничения мощности для инверторного кондиционера
#define AC_INVERTER_POWER_LIMITATION_ENABLE_MASK 0b10000000
#define AC_INVERTER_POWER_LIMITATION_VALUE_MASK 0b01111111
// положение вертикальных жалюзи для фронтенда
enum ac_vlouver_frontend : uint8_t {
AC_VLOUVER_FRONTEND_SWING = 0x00,
@@ -546,6 +586,8 @@ struct ac_command_t {
ac_realFan realFanSpeed; // текущая скорость вентилятора
uint8_t invertor_power; // мощность инвертора
bool defrost; // режим разморозки внешнего блока (накопление тепла + прогрев испарителя)
bool inverter_power_limitation_enable; // ограничение мощности инвертора
uint8_t inverter_power_limitation_value; // значение ограничения мощности инвертора
};
typedef ac_command_t ac_state_t; // текущее состояние параметров кондея можно хранить в таком же формате, как и комманды
@@ -713,13 +755,6 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
// сырые данные последних полученных большого и маленького информационных пакетов
ac_last_raw_data _last_raw_data;
// последовательность пакетов текущий шаг в последовательности
sequence_item_t _sequence[AC_SEQUENCE_MAX_LEN];
uint8_t _sequence_current_step;
// флаг успешного выполнения стартовой последовательности команд
bool _startupSequenceComlete = false;
// нормализация показаний температуры, приведение в диапазон
float _temp_target_normalise(float temp) {
auto traits = this->get_traits();
@@ -732,6 +767,20 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
return temp;
}
// нормализация лимита ограничения мощности инвертора, приведение в диапазон
uint8_t _power_limitation_value_normalise(uint8_t power_limitation_value) {
if (power_limitation_value < Constants::AC_MIN_INVERTER_POWER_LIMIT) power_limitation_value = Constants::AC_MIN_INVERTER_POWER_LIMIT;
if (power_limitation_value > Constants::AC_MAX_INVERTER_POWER_LIMIT) power_limitation_value = Constants::AC_MAX_INVERTER_POWER_LIMIT;
return power_limitation_value;
}
// последовательность пакетов текущий шаг в последовательности
sequence_item_t _sequence[AC_SEQUENCE_MAX_LEN];
uint8_t _sequence_current_step;
// флаг успешного выполнения стартовой последовательности команд
bool _startupSequenceComlete = false;
// очистка последовательности команд
void _clearSequence() {
for (uint8_t i = 0; i < AC_SEQUENCE_MAX_LEN; i++) {
@@ -909,6 +958,8 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
cmd->realFanSpeed = AC_REAL_FAN_UNTOUCHED;
cmd->invertor_power = 0;
cmd->defrost = false;
cmd->inverter_power_limitation_enable =false;
cmd->inverter_power_limitation_value = 0;
};
// очистка буфера размером AC_BUFFER_SIZE
@@ -1238,6 +1289,16 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
stateChangedFlag = stateChangedFlag || (_current_ac_state.mildew != (ac_mildew)stateByte);
_current_ac_state.mildew = (ac_mildew)stateByte;
// enable flag of power limitation for inverter ACs
bool temp = small_info_body->inverter_power_limitation_enable;
stateChangedFlag = stateChangedFlag || (_current_ac_state.inverter_power_limitation_enable != temp);
_current_ac_state.inverter_power_limitation_enable = temp;
// the limit value of power limitation for inverter ACs
stateByte = small_info_body->inverter_power_limitation_value;
stateChangedFlag = stateChangedFlag || (_current_ac_state.inverter_power_limitation_value != stateByte);
_current_ac_state.inverter_power_limitation_value = stateByte;
// уведомляем об изменении статуса сплита
if (stateChangedFlag) stateChanged();
@@ -1256,7 +1317,7 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
// тип кондея (инвертор или старт стоп)
_is_invertor = big_info_body->is_invertor;
// температура воздуха в помещении по версии сплит-системы
stateFloat = big_info_body->ambient_temperature_int - 0x20 + (float)(big_info_body->ambient_temperature_frac & 0x0f) / 10.0;
stateChangedFlag = stateChangedFlag || (_current_ac_state.temp_ambient != stateFloat);
@@ -1309,8 +1370,8 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
case AC_CMD_SET_PARAMS: { // такой статусный пакет присылается кондиционером в ответ на команду установки параметров
// в теле пакета нет ничего примечательного
// в байтах 2 и 3 тела похоже передается CRC пакета поступившей команды, на которую сплит отвечает
// но я решил этот момент тут не проверять и не контролировать.
// в байтах 2 и 3 тела передается CRC пакета поступившей команды, на которую сплит отвечает
// я решил этот момент тут не проверять и не контролировать.
// корректную установку параметров можно определить, запросив статус кондиционера сразу после получения этой команды кондея
// в настоящий момент проверка сделана в механизме sequences
break;
@@ -1604,6 +1665,11 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
}
}
// ограничение мощности инвертора
pack->body[13] = (pack->body[13] & ~AC_INVERTER_POWER_LIMITATION_ENABLE_MASK) | cmd->inverter_power_limitation_enable;
cmd->inverter_power_limitation_value = _power_limitation_value_normalise(cmd->inverter_power_limitation_value);
pack->body[13] = (pack->body[13] & ~AC_INVERTER_POWER_LIMITATION_VALUE_MASK) | cmd->inverter_power_limitation_value;
// обнулить счетчик минут с последней команды
// GK: считаю, что так делать не надо. Штатный wifi-модуль не сбрасывает счетчик минут.
// pack->body[4] &= ~ AC_MIN_COUNTER_MASK ;
@@ -1874,6 +1940,8 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
esphome::binary_sensor::BinarySensor *sensor_display_ = nullptr;
esphome::binary_sensor::BinarySensor *sensor_defrost_ = nullptr;
esphome::text_sensor::TextSensor *sensor_preset_reporter_ = nullptr;
esphome::sensor::Sensor *sensor_invertor_power_limit_value_ = nullptr;
esphome::binary_sensor::BinarySensor *sensor_invertor_power_limit_state_ = nullptr;
// загружает на выполнение последовательность команд на включение/выключение табло с температурой
bool _displaySequence(ac_display dsp = AC_DISPLAY_ON) {
@@ -1991,6 +2059,8 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
void set_display_sensor(binary_sensor::BinarySensor *display_sensor) { sensor_display_ = display_sensor; }
void set_invertor_power_sensor(sensor::Sensor *invertor_power_sensor) { sensor_invertor_power_ = invertor_power_sensor; }
void set_preset_reporter_sensor(text_sensor::TextSensor *preset_reporter_sensor) { sensor_preset_reporter_ = preset_reporter_sensor; }
void set_invertor_power_limit_value_sensor(sensor::Sensor *invertor_power_limit_value_sensor) { sensor_invertor_power_limit_value_ = invertor_power_limit_value_sensor; }
void set_invertor_power_limit_state_sensor(binary_sensor::BinarySensor *invertor_power_limit_state_sensor) { sensor_invertor_power_limit_state_ = invertor_power_limit_state_sensor; }
bool get_hw_initialized() { return _hw_initialized; };
bool get_has_connection() { return _has_connection; };
@@ -2314,6 +2384,12 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
// положение вертикальных жалюзи
if (sensor_vlouver_state_ != nullptr)
sensor_vlouver_state_->publish_state((float)this->getCurrentVlouverFrontendState());
// флаг включенного ограничения мощности инвертора
if (sensor_invertor_power_limit_state_ != nullptr)
sensor_invertor_power_limit_state_->publish_state(_current_ac_state.inverter_power_limitation_enable);
// значение ограничения мощности инвертора
if (sensor_invertor_power_limit_value_ != nullptr)
sensor_invertor_power_limit_value_->publish_state(_current_ac_state.inverter_power_limitation_value);
// сенсор состояния сплита
if (sensor_preset_reporter_ != nullptr) {
@@ -2965,6 +3041,53 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
return true;
}
// выключает ограничение мощности сплита
bool powerLimitationOffSequence() {
// нет смысла в последовательности, если нет коннекта с кондиционером
if (!get_has_connection()) {
_debugMsg(F("powerLimitationOffSequence: no pings from HVAC. It seems like no AC connected."), ESPHOME_LOG_LEVEL_ERROR, __LINE__);
return false;
}
if (!this->_is_invertor) return false; // если кондиционер не инверторный, то выходим
// формируем команду
ac_command_t cmd;
_clearCommand(&cmd); // не забываем очищать, а то будет мусор
cmd.inverter_power_limitation_value = this->_current_ac_state.inverter_power_limitation_value;
cmd.inverter_power_limitation_enable = false;
// добавляем команду в последовательность
if (!commandSequence(&cmd)) return false;
_debugMsg(F("powerLimitationOffSequence: loaded (value = %02X)"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, cmd.inverter_power_limitation_enable);
return true;
}
// включает ограничение мощности сплита на нужный уровень
bool powerLimitationOnSequence(uint8_t power_limit = Constants::AC_MIN_INVERTER_POWER_LIMIT) {
// нет смысла в последовательности, если нет коннекта с кондиционером
if (!get_has_connection()) {
_debugMsg(F("powerLimitationOnSequence: no pings from HVAC. It seems like no AC connected."), ESPHOME_LOG_LEVEL_ERROR, __LINE__);
return false;
}
if (!this->_is_invertor) return false; // если кондиционер не инверторный, то выходим
power_limit = this->_power_limitation_value_normalise(power_limit);
// формируем команду
ac_command_t cmd;
_clearCommand(&cmd); // не забываем очищать, а то будет мусор
cmd.inverter_power_limitation_enable = true;
cmd.inverter_power_limitation_value = power_limit;
// добавляем команду в последовательность
if (!commandSequence(&cmd)) return false;
_debugMsg(F("powerLimitationOnSequence: loaded (power limit = %02X)"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, power_limit);
return true;
}
// конвертирует состояние жалюзи из кодов сплита в коды для фронтенда
ac_vlouver_frontend AUXvlouverToVlouverFrontend(const ac_louver_V vLouver) {
switch (vLouver) {
@@ -3048,7 +3171,7 @@ class AirCon : public esphome::Component, public esphome::climate::Climate {
// добавляем команду в последовательность
if (!commandSequence(&cmd)) return false;
_debugMsg(F("setVLouverSequence: loaded (power = %02X)"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, vLouver);
_debugMsg(F("setVLouverSequence: loaded (vLouver = %02X)"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, vLouver);
return true;
}

View File

@@ -5,16 +5,17 @@ from esphome.components import climate, uart, sensor, binary_sensor, text_sensor
from esphome import automation
from esphome.automation import maybe_simple_id
from esphome.const import (
CONF_ID,
CONF_UART_ID,
CONF_PERIOD,
CONF_CUSTOM_FAN_MODES,
CONF_CUSTOM_PRESETS,
CONF_INTERNAL,
CONF_DATA,
CONF_ID,
CONF_INTERNAL,
CONF_PERIOD,
CONF_POSITION,
CONF_SUPPORTED_MODES,
CONF_SUPPORTED_SWING_MODES,
CONF_SUPPORTED_PRESETS,
CONF_UART_ID,
UNIT_CELSIUS,
UNIT_PERCENT,
ICON_POWER,
@@ -22,7 +23,6 @@ from esphome.const import (
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_POWER_FACTOR,
STATE_CLASS_MEASUREMENT,
CONF_POSITION,
)
from esphome.components.climate import (
ClimateMode,
@@ -37,26 +37,41 @@ DEPENDENCIES = ["climate", "uart"]
AUTO_LOAD = ["sensor", "binary_sensor", "text_sensor"]
CONF_SHOW_ACTION = "show_action"
CONF_INDOOR_TEMPERATURE = "indoor_temperature"
CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
ICON_OUTDOOR_TEMPERATURE = "mdi:home-thermometer-outline"
CONF_INBOUND_TEMPERATURE = "inbound_temperature"
ICON_INBOUND_TEMPERATURE = "mdi:thermometer-plus"
CONF_OUTBOUND_TEMPERATURE = "outbound_temperature"
ICON_OUTBOUND_TEMPERATURE = "mdi:thermometer-minus"
CONF_COMPRESSOR_TEMPERATURE = "compressor_temperature"
ICON_COMPRESSOR_TEMPERATURE = "mdi:thermometer-lines"
CONF_DISPLAY_STATE = "display_state"
CONF_INVERTOR_POWER = "invertor_power"
CONF_DEFROST_STATE = "defrost_state"
ICON_DEFROST = "mdi:snowflake-melt"
CONF_DISPLAY_INVERTED = "display_inverted"
ICON_DISPLAY = "mdi:clock-digital"
CONF_PRESET_REPORTER = "preset_reporter"
ICON_PRESET_REPORTER = "mdi:format-list-group"
CONF_VLOUVER_STATE = "vlouver_state"
ICON_VLOUVER_STATE = "mdi:compare-vertical"
CONF_LIMIT = "limit"
CONF_INVERTER_POWER_LIMIT_VALUE = "inverter_power_limit_value"
ICON_INVERTER_POWER_LIMIT_VALUE = "mdi:meter-electric-outline"
CONF_INVERTER_POWER_LIMIT_STATE = "inverter_power_limit_state"
ICON_INVERTER_POWER_LIMIT_STATE = "mdi:meter-electric-outline"
aux_ac_ns = cg.esphome_ns.namespace("aux_ac")
AirCon = aux_ac_ns.class_("AirCon", climate.Climate, cg.Component)
@@ -89,8 +104,18 @@ AirConVLouverMiddleBelowAction = aux_ac_ns.class_(
AirConVLouverBottomAction = aux_ac_ns.class_(
"AirConVLouverBottomAction", automation.Action
)
AirConVLouverSetAction = aux_ac_ns.class_(
"AirConVLouverSetAction", automation.Action
)
# power limitation actions
AirConPowerLimitationOffAction = aux_ac_ns.class_(
"AirConPowerLimitationOffAction", automation.Action
)
AirConPowerLimitationOnAction = aux_ac_ns.class_(
"AirConPowerLimitationOnAction", automation.Action
)
AirConVLouverSetAction = aux_ac_ns.class_("AirConVLouverSetAction", automation.Action)
ALLOWED_CLIMATE_MODES = {
"HEAT_COOL": ClimateMode.CLIMATE_MODE_HEAT_COOL,
@@ -240,6 +265,24 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
}
),
cv.Optional(CONF_INVERTER_POWER_LIMIT_VALUE): sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
icon=ICON_INVERTER_POWER_LIMIT_VALUE,
accuracy_decimals=0,
device_class=DEVICE_CLASS_POWER_FACTOR,
state_class=STATE_CLASS_MEASUREMENT,
).extend(
{
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
}
),
cv.Optional(CONF_INVERTER_POWER_LIMIT_STATE): binary_sensor.binary_sensor_schema(
icon=ICON_INVERTER_POWER_LIMIT_STATE,
).extend(
{
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
}
),
cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list(validate_modes),
cv.Optional(CONF_SUPPORTED_SWING_MODES): cv.ensure_list(
validate_swing_modes
@@ -316,6 +359,16 @@ async def to_code(config):
conf = config[CONF_PRESET_REPORTER]
sens = await text_sensor.new_text_sensor(conf)
cg.add(var.set_preset_reporter_sensor(sens))
if CONF_INVERTER_POWER_LIMIT_VALUE in config:
conf = config[CONF_INVERTER_POWER_LIMIT_VALUE]
sens = await sensor.new_sensor(conf)
cg.add(var.set_invertor_power_limit_value_sensor(sens))
if CONF_INVERTER_POWER_LIMIT_STATE in config:
conf = config[CONF_INVERTER_POWER_LIMIT_STATE]
sens = await binary_sensor.new_binary_sensor(conf)
cg.add(var.set_invertor_power_limit_state_sensor(sens))
cg.add(var.set_period(config[CONF_PERIOD].total_milliseconds))
cg.add(var.set_show_action(config[CONF_SHOW_ACTION]))
@@ -332,13 +385,13 @@ async def to_code(config):
cg.add(var.set_custom_fan_modes(config[CONF_CUSTOM_FAN_MODES]))
DISPLAY_ACTION_SCHEMA = maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(AirCon),
}
)
@automation.register_action(
"aux_ac.display_off", AirConDisplayOffAction, DISPLAY_ACTION_SCHEMA
)
@@ -346,7 +399,6 @@ async def display_off_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.display_on", AirConDisplayOnAction, DISPLAY_ACTION_SCHEMA
)
@@ -355,13 +407,13 @@ async def display_on_to_code(config, action_id, template_arg, args):
return cg.new_Pvariable(action_id, template_arg, paren)
VLOUVER_ACTION_SCHEMA = maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(AirCon),
}
)
@automation.register_action(
"aux_ac.vlouver_stop", AirConVLouverStopAction, VLOUVER_ACTION_SCHEMA
)
@@ -369,7 +421,6 @@ async def vlouver_stop_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.vlouver_swing", AirConVLouverSwingAction, VLOUVER_ACTION_SCHEMA
)
@@ -377,7 +428,6 @@ async def vlouver_swing_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.vlouver_top", AirConVLouverTopAction, VLOUVER_ACTION_SCHEMA
)
@@ -385,7 +435,6 @@ async def vlouver_top_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.vlouver_middle_above", AirConVLouverMiddleAboveAction, VLOUVER_ACTION_SCHEMA
)
@@ -393,7 +442,6 @@ async def vlouver_middle_above_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.vlouver_middle", AirConVLouverMiddleAction, VLOUVER_ACTION_SCHEMA
)
@@ -401,7 +449,6 @@ async def vlouver_middle_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.vlouver_middle_below", AirConVLouverMiddleBelowAction, VLOUVER_ACTION_SCHEMA
)
@@ -409,7 +456,6 @@ async def vlouver_middle_below_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"aux_ac.vlouver_bottom", AirConVLouverBottomAction, VLOUVER_ACTION_SCHEMA
)
@@ -418,6 +464,7 @@ async def vlouver_bottom_to_code(config, action_id, template_arg, args):
return cg.new_Pvariable(action_id, template_arg, paren)
VLOUVER_SET_ACTION_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.use_id(AirCon),
@@ -425,7 +472,6 @@ VLOUVER_SET_ACTION_SCHEMA = cv.Schema(
}
)
@automation.register_action(
"aux_ac.vlouver_set", AirConVLouverSetAction, VLOUVER_SET_ACTION_SCHEMA
)
@@ -437,6 +483,43 @@ async def vlouver_set_to_code(config, action_id, template_arg, args):
return var
POWER_LIMITATION_OFF_ACTION_SCHEMA = maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(AirCon),
}
)
@automation.register_action(
"aux_ac.power_limit_off", AirConPowerLimitationOffAction, POWER_LIMITATION_OFF_ACTION_SCHEMA
)
async def power_limit_off_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
POWER_LIMITATION_ON_ACTION_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.use_id(AirCon),
cv.Optional(CONF_LIMIT, default=Capabilities.AC_MIN_INVERTER_POWER_LIMIT): cv.templatable(
cv.int_range(30, 100)
),
}
)
@automation.register_action(
"aux_ac.power_limit_on", AirConPowerLimitationOnAction, POWER_LIMITATION_ON_ACTION_SCHEMA
)
async def power_limit_on_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(config[CONF_LIMIT], args, int)
cg.add(var.set_value(template_))
return var
# *********************************************************************************************************
# ВАЖНО! Только для инженеров!
# Вызывайте метод aux_ac.send_packet только если понимаете, что делаете! Он не проверяет данные, а передаёт

View File

@@ -0,0 +1,162 @@
external_components:
- source: github://GrKoR/esphome_aux_ac_component@dev
components: [ aux_ac ]
refresh: 0s
substitutions:
devicename: test_local_airflow_dir
upper_devicename: Test AUX
esphome:
name: $devicename
platform: ESP8266
board: esp12e
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pass
manual_ip:
static_ip: !secret wifi_ip
gateway: !secret wifi_gateway
subnet: !secret wifi_subnet
dns1: 8.8.8.8
dns2: 1.1.1.1
reboot_timeout: 0s
ap:
ssid: Test AUX Fallback Hotspot
password: !secret wifi_ap_pass
logger:
level: DEBUG
baud_rate: 0
api:
password: !secret api_pass
reboot_timeout: 0s
ota:
password: !secret ota_pass
web_server:
port: 80
uart:
id: ac_uart_bus
tx_pin: GPIO1
rx_pin: GPIO3
baud_rate: 4800
data_bits: 8
parity: EVEN
stop_bits: 1
sensor:
- platform: uptime
name: Uptime Sensor
climate:
- platform: aux_ac
name: $upper_devicename
id: aux_id
uart_id: ac_uart_bus
period: 7s
show_action: true
display_inverted: true
indoor_temperature:
name: $upper_devicename Indoor Temperature
id: ${devicename}_indoor_temp
internal: false
display_state:
name: $upper_devicename Display State
id: ${devicename}_display_state
internal: false
outdoor_temperature:
name: $upper_devicename Outdoor Temperature
id: ${devicename}_outdoor_temp
internal: false
outbound_temperature:
name: $upper_devicename Colant Outbound Temperature
id: ${devicename}_outbound_temp
internal: false
inbound_temperature:
name: $upper_devicename Colant Inbound Temperature
id: ${devicename}_inbound_temp
internal: false
compressor_temperature:
name: $upper_devicename Compressor Temperature
id: ${devicename}_strange_temp
internal: false
defrost_state:
name: $upper_devicename Defrost State
id: ${devicename}_defrost_state
internal: false
invertor_power:
name: $upper_devicename Invertor Power
id: ${devicename}_invertor_power
internal: false
preset_reporter:
name: $upper_devicename Preset Reporter
id: ${devicename}_preset_reporter
internal: false
inverter_power_limit_value:
name: $upper_devicename Inverter Power Limit Value
id: ${devicename}_inverter_power_limit_value
internal: false
inverter_power_limit_state:
name: $upper_devicename Inverter Power Limit State
id: ${devicename}_inverter_power_limit_state
internal: false
visual:
min_temperature: 16
max_temperature: 32
temperature_step: 0.5
supported_modes:
- HEAT_COOL
- COOL
- HEAT
- DRY
- FAN_ONLY
custom_fan_modes:
- MUTE
- TURBO
supported_presets:
- SLEEP
custom_presets:
- CLEAN
- HEALTH
- ANTIFUNGUS
supported_swing_modes:
- VERTICAL
- HORIZONTAL
- BOTH
button:
- platform: template
name: ${upper_devicename} IPower Limit Off
icon: "mdi:power-plug-off-outline"
on_press:
- aux_ac.power_limit_off: aux_id
- platform: template
name: ${upper_devicename} IPower Limit On Half
icon: "mdi:fraction-one-half"
on_press:
- aux_ac.power_limit_on:
id: aux_id
limit: 50
number:
- platform: template
name: ${upper_devicename} IPower Limit Value
id: ${devicename}_ipower_limit_value
icon: "mdi:battery-unknown"
mode: "slider"
min_value: 30
max_value: 100
step: 1
set_action:
then:
- lambda: !lambda |-
id(aux_id).powerLimitationOnSequence( x );

View File

@@ -0,0 +1,162 @@
external_components:
- source:
type: local
path: ../components
substitutions:
devicename: test_local_airflow_dir
upper_devicename: Test AUX
esphome:
name: $devicename
platform: ESP8266
board: esp12e
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pass
manual_ip:
static_ip: !secret wifi_ip
gateway: !secret wifi_gateway
subnet: !secret wifi_subnet
dns1: 8.8.8.8
dns2: 1.1.1.1
reboot_timeout: 0s
ap:
ssid: Test AUX Fallback Hotspot
password: !secret wifi_ap_pass
logger:
level: DEBUG
baud_rate: 0
api:
password: !secret api_pass
reboot_timeout: 0s
ota:
password: !secret ota_pass
web_server:
port: 80
uart:
id: ac_uart_bus
tx_pin: GPIO1
rx_pin: GPIO3
baud_rate: 4800
data_bits: 8
parity: EVEN
stop_bits: 1
sensor:
- platform: uptime
name: Uptime Sensor
climate:
- platform: aux_ac
name: $upper_devicename
id: aux_id
uart_id: ac_uart_bus
period: 7s
show_action: true
display_inverted: true
indoor_temperature:
name: $upper_devicename Indoor Temperature
id: ${devicename}_indoor_temp
internal: false
display_state:
name: $upper_devicename Display State
id: ${devicename}_display_state
internal: false
outdoor_temperature:
name: $upper_devicename Outdoor Temperature
id: ${devicename}_outdoor_temp
internal: false
outbound_temperature:
name: $upper_devicename Colant Outbound Temperature
id: ${devicename}_outbound_temp
internal: false
inbound_temperature:
name: $upper_devicename Colant Inbound Temperature
id: ${devicename}_inbound_temp
internal: false
compressor_temperature:
name: $upper_devicename Compressor Temperature
id: ${devicename}_strange_temp
internal: false
defrost_state:
name: $upper_devicename Defrost State
id: ${devicename}_defrost_state
internal: false
invertor_power:
name: $upper_devicename Invertor Power
id: ${devicename}_invertor_power
internal: false
preset_reporter:
name: $upper_devicename Preset Reporter
id: ${devicename}_preset_reporter
internal: false
inverter_power_limit_value:
name: $upper_devicename Inverter Power Limit Value
id: ${devicename}_inverter_power_limit_value
internal: false
inverter_power_limit_state:
name: $upper_devicename Inverter Power Limit State
id: ${devicename}_inverter_power_limit_state
internal: false
visual:
min_temperature: 16
max_temperature: 32
temperature_step: 0.5
supported_modes:
- HEAT_COOL
- COOL
- HEAT
- DRY
- FAN_ONLY
custom_fan_modes:
- MUTE
- TURBO
supported_presets:
- SLEEP
custom_presets:
- CLEAN
- HEALTH
- ANTIFUNGUS
supported_swing_modes:
- VERTICAL
- HORIZONTAL
- BOTH
button:
- platform: template
name: ${upper_devicename} IPower Limit Off
icon: "mdi:power-plug-off-outline"
on_press:
- aux_ac.power_limit_off: aux_id
- platform: template
name: ${upper_devicename} IPower Limit On Half
icon: "mdi:fraction-one-half"
on_press:
- aux_ac.power_limit_on:
id: aux_id
limit: 50
number:
- platform: template
name: ${upper_devicename} IPower Limit Value
id: ${devicename}_ipower_limit_value
icon: "mdi:battery-unknown"
mode: "slider"
min_value: 30
max_value: 100
step: 1
set_action:
then:
- lambda: !lambda |-
id(aux_id).powerLimitationOnSequence( x );