mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[mitsubishi_cn105] Add vertical vane control action (#16737)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
co-authored by
J. Nick Koston
parent
3540012529
commit
9556c2bc4c
@@ -2,9 +2,15 @@ from esphome import automation
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import uart
|
from esphome.components import uart
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ID, CONF_ON_STATE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
from esphome.const import (
|
||||||
from esphome.core import ID
|
CONF_DIRECTION,
|
||||||
from esphome.cpp_generator import MockObj
|
CONF_ID,
|
||||||
|
CONF_ON_STATE,
|
||||||
|
CONF_TEMPERATURE,
|
||||||
|
CONF_UPDATE_INTERVAL,
|
||||||
|
)
|
||||||
|
from esphome.core import ID, Lambda
|
||||||
|
from esphome.cpp_generator import LambdaExpression, MockObj
|
||||||
from esphome.types import ConfigType, TemplateArgsType
|
from esphome.types import ConfigType, TemplateArgsType
|
||||||
|
|
||||||
CODEOWNERS = ["@crnjan"]
|
CODEOWNERS = ["@crnjan"]
|
||||||
@@ -14,6 +20,7 @@ DOMAIN = "mitsubishi_cn105"
|
|||||||
CONF_MITSUBISHI_CN105_ID = f"{DOMAIN}_id"
|
CONF_MITSUBISHI_CN105_ID = f"{DOMAIN}_id"
|
||||||
CONF_TELEMETRY_REQUEST_MIN_INTERVAL = "telemetry_request_min_interval"
|
CONF_TELEMETRY_REQUEST_MIN_INTERVAL = "telemetry_request_min_interval"
|
||||||
CONF_VANE = "vane"
|
CONF_VANE = "vane"
|
||||||
|
CONF_VERTICAL = "vertical"
|
||||||
|
|
||||||
mitsubishi_ns = cg.esphome_ns.namespace(DOMAIN)
|
mitsubishi_ns = cg.esphome_ns.namespace(DOMAIN)
|
||||||
|
|
||||||
@@ -24,6 +31,20 @@ MitsubishiCN105Component = mitsubishi_ns.class_(
|
|||||||
)
|
)
|
||||||
|
|
||||||
VaneState = mitsubishi_ns.struct("VaneState")
|
VaneState = mitsubishi_ns.struct("VaneState")
|
||||||
|
VaneCall = mitsubishi_ns.class_("VaneCall")
|
||||||
|
VerticalVaneMode = mitsubishi_ns.enum("VerticalVaneMode")
|
||||||
|
|
||||||
|
# The insertion order must match VALUES in
|
||||||
|
# select/mitsubishi_cn105_vane_select_vertical.cpp.
|
||||||
|
VERTICAL_VANE_DIRECTIONS = {
|
||||||
|
"AUTO": VerticalVaneMode.VERTICAL_VANE_MODE_AUTO,
|
||||||
|
"1": VerticalVaneMode.VERTICAL_VANE_MODE_POSITION_1,
|
||||||
|
"2": VerticalVaneMode.VERTICAL_VANE_MODE_POSITION_2,
|
||||||
|
"3": VerticalVaneMode.VERTICAL_VANE_MODE_POSITION_3,
|
||||||
|
"4": VerticalVaneMode.VERTICAL_VANE_MODE_POSITION_4,
|
||||||
|
"5": VerticalVaneMode.VERTICAL_VANE_MODE_POSITION_5,
|
||||||
|
"SWING": VerticalVaneMode.VERTICAL_VANE_MODE_SWING,
|
||||||
|
}
|
||||||
|
|
||||||
SetRemoteTemperatureAction = mitsubishi_ns.class_(
|
SetRemoteTemperatureAction = mitsubishi_ns.class_(
|
||||||
"SetRemoteTemperatureAction",
|
"SetRemoteTemperatureAction",
|
||||||
@@ -37,6 +58,11 @@ ClearRemoteTemperatureAction = mitsubishi_ns.class_(
|
|||||||
cg.Parented.template(MitsubishiCN105Component),
|
cg.Parented.template(MitsubishiCN105Component),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
VaneControlAction = mitsubishi_ns.class_(
|
||||||
|
"VaneControlAction",
|
||||||
|
automation.Action,
|
||||||
|
)
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
@@ -152,3 +178,70 @@ async def clear_temperature_action_to_code(
|
|||||||
var = cg.new_Pvariable(action_id, template_arg)
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
await cg.register_parented(var, config[CONF_ID])
|
await cg.register_parented(var, config[CONF_ID])
|
||||||
return var
|
return var
|
||||||
|
|
||||||
|
|
||||||
|
VANE_CONTROL_FIELDS = (
|
||||||
|
(
|
||||||
|
(CONF_VERTICAL, CONF_DIRECTION),
|
||||||
|
"vertical.set_direction",
|
||||||
|
VerticalVaneMode,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
VANE_CONTROL_ACTION_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_ID): cv.use_id(MitsubishiCN105Component),
|
||||||
|
cv.Optional(CONF_VERTICAL): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_DIRECTION): cv.templatable(
|
||||||
|
cv.enum(VERTICAL_VANE_DIRECTIONS, upper=True)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action(
|
||||||
|
f"{DOMAIN}.vane.control",
|
||||||
|
VaneControlAction,
|
||||||
|
VANE_CONTROL_ACTION_SCHEMA,
|
||||||
|
synchronous=True,
|
||||||
|
)
|
||||||
|
async def vane_control_to_code(
|
||||||
|
config: ConfigType,
|
||||||
|
action_id: ID,
|
||||||
|
template_arg: cg.TemplateArguments,
|
||||||
|
args: TemplateArgsType,
|
||||||
|
) -> MockObj:
|
||||||
|
cg.add_global(mitsubishi_ns.using)
|
||||||
|
parent = await cg.get_variable(config[CONF_ID])
|
||||||
|
normalized_args = [
|
||||||
|
(cg.RawExpression(f"const std::remove_cvref_t<{cg.safe_exp(t)}> &"), name)
|
||||||
|
for t, name in args
|
||||||
|
]
|
||||||
|
forwarded_args = ", ".join(name for _, name in args)
|
||||||
|
body_lines: list[str] = []
|
||||||
|
|
||||||
|
for path, setter, type_ in VANE_CONTROL_FIELDS:
|
||||||
|
if (section := config.get(path[0])) is None:
|
||||||
|
continue
|
||||||
|
if (value := section.get(path[1])) is None:
|
||||||
|
continue
|
||||||
|
if isinstance(value, Lambda):
|
||||||
|
inner = await cg.process_lambda(
|
||||||
|
value,
|
||||||
|
normalized_args,
|
||||||
|
return_type=type_,
|
||||||
|
)
|
||||||
|
body_lines.append(f"call.{setter}(({inner})({forwarded_args}));")
|
||||||
|
else:
|
||||||
|
body_lines.append(f"call.{setter}({cg.safe_exp(value)});")
|
||||||
|
|
||||||
|
apply_lambda = LambdaExpression(
|
||||||
|
["\n".join(body_lines)],
|
||||||
|
[(VaneCall.operator("ref"), "call"), *normalized_args],
|
||||||
|
capture="",
|
||||||
|
return_type=cg.void,
|
||||||
|
)
|
||||||
|
return cg.new_Pvariable(action_id, template_arg, parent, apply_lambda)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "esphome/core/automation.h"
|
#include "esphome/core/automation.h"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace esphome::mitsubishi_cn105 {
|
namespace esphome::mitsubishi_cn105 {
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
@@ -20,4 +22,21 @@ class ClearRemoteTemperatureAction : public Action<Ts...>, public Parented<Mitsu
|
|||||||
void play(const Ts &...x) override { this->parent_->clear_remote_temperature(); }
|
void play(const Ts &...x) override { this->parent_->clear_remote_temperature(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class VaneControlAction : public Action<Ts...> {
|
||||||
|
public:
|
||||||
|
using ApplyFn = void (*)(VaneCall &, const std::remove_cvref_t<Ts> &...);
|
||||||
|
|
||||||
|
VaneControlAction(MitsubishiCN105Component *parent, ApplyFn apply) : parent_(parent), apply_(apply) {}
|
||||||
|
|
||||||
|
void play(const Ts &...x) override {
|
||||||
|
auto call = this->parent_->make_vane_call();
|
||||||
|
this->apply_(call, x...);
|
||||||
|
call.perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MitsubishiCN105Component *parent_;
|
||||||
|
ApplyFn apply_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace esphome::mitsubishi_cn105
|
} // namespace esphome::mitsubishi_cn105
|
||||||
|
|||||||
@@ -31,4 +31,11 @@ void MitsubishiCN105Component::loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VaneCall::perform() {
|
||||||
|
if (const auto &direction = this->vertical.get_direction(); direction.has_value()) {
|
||||||
|
this->parent_->set_vane_mode(static_cast<MitsubishiCN105::VaneMode>(*direction));
|
||||||
|
}
|
||||||
|
this->parent_->publish_status();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace esphome::mitsubishi_cn105
|
} // namespace esphome::mitsubishi_cn105
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "esphome/components/uart/uart.h"
|
#include "esphome/components/uart/uart.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace esphome::mitsubishi_cn105 {
|
namespace esphome::mitsubishi_cn105 {
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ enum VerticalVaneMode : uint8_t {
|
|||||||
VERTICAL_VANE_MODE_POSITION_4 = static_cast<uint8_t>(MitsubishiCN105::VaneMode::POSITION_4),
|
VERTICAL_VANE_MODE_POSITION_4 = static_cast<uint8_t>(MitsubishiCN105::VaneMode::POSITION_4),
|
||||||
VERTICAL_VANE_MODE_POSITION_5 = static_cast<uint8_t>(MitsubishiCN105::VaneMode::POSITION_5),
|
VERTICAL_VANE_MODE_POSITION_5 = static_cast<uint8_t>(MitsubishiCN105::VaneMode::POSITION_5),
|
||||||
VERTICAL_VANE_MODE_SWING = static_cast<uint8_t>(MitsubishiCN105::VaneMode::SWING),
|
VERTICAL_VANE_MODE_SWING = static_cast<uint8_t>(MitsubishiCN105::VaneMode::SWING),
|
||||||
|
VERTICAL_VANE_MODE_UNKNOWN = static_cast<uint8_t>(MitsubishiCN105::VaneMode::UNKNOWN),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VaneState {
|
struct VaneState {
|
||||||
@@ -27,6 +29,27 @@ struct VaneState {
|
|||||||
Vertical vertical;
|
Vertical vertical;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MitsubishiCN105Component;
|
||||||
|
|
||||||
|
struct VaneCall {
|
||||||
|
struct Vertical {
|
||||||
|
void set_direction(VerticalVaneMode direction) { this->direction_ = direction; }
|
||||||
|
const std::optional<VerticalVaneMode> &get_direction() const { return this->direction_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::optional<VerticalVaneMode> direction_;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit VaneCall(MitsubishiCN105Component *parent) : parent_(parent) {}
|
||||||
|
|
||||||
|
Vertical vertical;
|
||||||
|
|
||||||
|
void perform();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MitsubishiCN105Component *parent_;
|
||||||
|
};
|
||||||
|
|
||||||
class MitsubishiCN105Component : public Component, public uart::UARTDevice {
|
class MitsubishiCN105Component : public Component, public uart::UARTDevice {
|
||||||
public:
|
public:
|
||||||
explicit MitsubishiCN105Component() : hp_(*this) {}
|
explicit MitsubishiCN105Component() : hp_(*this) {}
|
||||||
@@ -47,6 +70,7 @@ class MitsubishiCN105Component : public Component, public uart::UARTDevice {
|
|||||||
void set_fan_mode(MitsubishiCN105::FanMode fan_mode) { this->hp_.set_fan_mode(fan_mode); }
|
void set_fan_mode(MitsubishiCN105::FanMode fan_mode) { this->hp_.set_fan_mode(fan_mode); }
|
||||||
void set_vane_mode(MitsubishiCN105::VaneMode vane_mode) { this->hp_.set_vane_mode(vane_mode); }
|
void set_vane_mode(MitsubishiCN105::VaneMode vane_mode) { this->hp_.set_vane_mode(vane_mode); }
|
||||||
void set_wide_vane_mode(MitsubishiCN105::WideVaneMode mode) { this->hp_.set_wide_vane_mode(mode); }
|
void set_wide_vane_mode(MitsubishiCN105::WideVaneMode mode) { this->hp_.set_wide_vane_mode(mode); }
|
||||||
|
VaneCall make_vane_call() { return VaneCall(this); }
|
||||||
|
|
||||||
const MitsubishiCN105::Status &status() const { return this->hp_.status(); }
|
const MitsubishiCN105::Status &status() const { return this->hp_.status(); }
|
||||||
bool is_status_initialized() const { return this->hp_.is_status_initialized(); }
|
bool is_status_initialized() const { return this->hp_.is_status_initialized(); }
|
||||||
@@ -69,11 +93,9 @@ class MitsubishiCN105Component : public Component, public uart::UARTDevice {
|
|||||||
protected:
|
protected:
|
||||||
void notify_status_listeners_() {
|
void notify_status_listeners_() {
|
||||||
this->status_callback_.call();
|
this->status_callback_.call();
|
||||||
if (this->status().vane_mode != MitsubishiCN105::VaneMode::UNKNOWN) {
|
this->vane_state_callback_.call(VaneState{
|
||||||
this->vane_state_callback_.call(VaneState{
|
.vertical = {.direction = static_cast<VerticalVaneMode>(this->status().vane_mode)},
|
||||||
.vertical = {.direction = static_cast<VerticalVaneMode>(this->status().vane_mode)},
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MitsubishiCN105 hp_;
|
MitsubishiCN105 hp_;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from esphome.types import ConfigType
|
|||||||
|
|
||||||
from .. import (
|
from .. import (
|
||||||
MITSUBISHI_CN105_DEVICE_SCHEMA,
|
MITSUBISHI_CN105_DEVICE_SCHEMA,
|
||||||
|
VERTICAL_VANE_DIRECTIONS,
|
||||||
MitsubishiCN105Component,
|
MitsubishiCN105Component,
|
||||||
mitsubishi_ns,
|
mitsubishi_ns,
|
||||||
register_mitsubishi_cn105_device,
|
register_mitsubishi_cn105_device,
|
||||||
@@ -15,9 +16,6 @@ DEPENDENCIES = ["mitsubishi_cn105"]
|
|||||||
|
|
||||||
CONF_VERTICAL_VANE_DIRECTION = "vertical_vane_direction"
|
CONF_VERTICAL_VANE_DIRECTION = "vertical_vane_direction"
|
||||||
|
|
||||||
# The insertion order must match VALUES in mitsubishi_cn105_vane_select_vertical.cpp.
|
|
||||||
VERTICAL_VANE_DIRECTIONS = ["Auto", "1", "2", "3", "4", "5", "Swing"]
|
|
||||||
|
|
||||||
MitsubishiCN105VerticalVaneDirectionSelect = mitsubishi_ns.class_(
|
MitsubishiCN105VerticalVaneDirectionSelect = mitsubishi_ns.class_(
|
||||||
"MitsubishiCN105VerticalVaneDirectionSelect",
|
"MitsubishiCN105VerticalVaneDirectionSelect",
|
||||||
select.Select,
|
select.Select,
|
||||||
@@ -42,6 +40,6 @@ async def to_code(config: ConfigType) -> None:
|
|||||||
await select.register_select(
|
await select.register_select(
|
||||||
var,
|
var,
|
||||||
vertical_vane_direction,
|
vertical_vane_direction,
|
||||||
options=VERTICAL_VANE_DIRECTIONS,
|
options=[direction.capitalize() for direction in VERTICAL_VANE_DIRECTIONS],
|
||||||
)
|
)
|
||||||
await register_mitsubishi_cn105_device(var, config)
|
await register_mitsubishi_cn105_device(var, config)
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace esphome::mitsubishi_cn105 {
|
namespace esphome::mitsubishi_cn105 {
|
||||||
|
|
||||||
// NOTE: This order must match VERTICAL_VANE_DIRECTIONS in select.py.
|
// NOTE: This order must match VERTICAL_VANE_DIRECTIONS in the hub's __init__.py.
|
||||||
// MitsubishiCN105VerticalVaneDirectionSelect uses the preferred index-based
|
// MitsubishiCN105VerticalVaneDirectionSelect uses the preferred index-based
|
||||||
// Select API, so Python option order and this array must stay aligned.
|
// Select API, so Python option order and this array must stay aligned.
|
||||||
static constexpr std::array VALUES{
|
static constexpr std::array VALUES{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "esphome/components/uart/uart_component.h"
|
#include "esphome/components/uart/uart_component.h"
|
||||||
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105.h"
|
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105.h"
|
||||||
|
#include "esphome/components/mitsubishi_cn105/automation.h"
|
||||||
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105_component.h"
|
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105_component.h"
|
||||||
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105_climate.h"
|
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105_climate.h"
|
||||||
|
|
||||||
|
|||||||
@@ -29,3 +29,11 @@ esphome:
|
|||||||
temperature: 22.0
|
temperature: 22.0
|
||||||
- mitsubishi_cn105.clear_remote_temperature:
|
- mitsubishi_cn105.clear_remote_temperature:
|
||||||
id: ac
|
id: ac
|
||||||
|
- mitsubishi_cn105.vane.control:
|
||||||
|
id: ac
|
||||||
|
vertical:
|
||||||
|
direction: SWING
|
||||||
|
- mitsubishi_cn105.vane.control:
|
||||||
|
id: ac
|
||||||
|
vertical:
|
||||||
|
direction: !lambda return esphome::mitsubishi_cn105::VERTICAL_VANE_MODE_SWING;
|
||||||
|
|||||||
@@ -24,25 +24,50 @@ TEST(MitsubishiCN105ComponentTests, PublishesVaneStateForEveryValidSnapshot) {
|
|||||||
EXPECT_EQ(callback_direction, std::optional{VERTICAL_VANE_MODE_POSITION_4});
|
EXPECT_EQ(callback_direction, std::optional{VERTICAL_VANE_MODE_POSITION_4});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105ComponentTests, DoesNotPublishUnknownVaneState) {
|
TEST(MitsubishiCN105ComponentTests, PublishesUnknownVaneState) {
|
||||||
TestableMitsubishiCN105Component hub;
|
TestableMitsubishiCN105Component hub;
|
||||||
size_t status_callback_count = 0;
|
size_t status_callback_count = 0;
|
||||||
size_t vane_callback_count = 0;
|
size_t vane_callback_count = 0;
|
||||||
|
std::optional<VerticalVaneMode> callback_direction;
|
||||||
hub.add_on_status_callback([&]() { status_callback_count++; });
|
hub.add_on_status_callback([&]() { status_callback_count++; });
|
||||||
hub.add_on_vane_state_callback([&](const VaneState &) { vane_callback_count++; });
|
hub.add_on_vane_state_callback([&](const VaneState &state) {
|
||||||
|
vane_callback_count++;
|
||||||
|
callback_direction = state.vertical.direction;
|
||||||
|
});
|
||||||
|
|
||||||
hub.mutable_status().room_temperature = 20.0f;
|
hub.mutable_status().room_temperature = 20.0f;
|
||||||
hub.mutable_status().vane_mode = MitsubishiCN105::VaneMode::UNKNOWN;
|
hub.mutable_status().vane_mode = MitsubishiCN105::VaneMode::UNKNOWN;
|
||||||
hub.publish_status();
|
hub.publish_status();
|
||||||
|
|
||||||
EXPECT_EQ(status_callback_count, 1);
|
EXPECT_EQ(status_callback_count, 1);
|
||||||
EXPECT_EQ(vane_callback_count, 0);
|
EXPECT_EQ(vane_callback_count, 1);
|
||||||
|
EXPECT_EQ(callback_direction, std::optional{VERTICAL_VANE_MODE_UNKNOWN});
|
||||||
|
|
||||||
hub.mutable_status().vane_mode = MitsubishiCN105::VaneMode::POSITION_4;
|
hub.mutable_status().vane_mode = MitsubishiCN105::VaneMode::POSITION_4;
|
||||||
hub.publish_status();
|
hub.publish_status();
|
||||||
|
|
||||||
EXPECT_EQ(status_callback_count, 2);
|
EXPECT_EQ(status_callback_count, 2);
|
||||||
EXPECT_EQ(vane_callback_count, 1);
|
EXPECT_EQ(vane_callback_count, 2);
|
||||||
|
EXPECT_EQ(callback_direction, std::optional{VERTICAL_VANE_MODE_POSITION_4});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105ComponentTests, VaneCallAppliesVerticalDirection) {
|
||||||
|
TestableMitsubishiCN105Component hub;
|
||||||
|
|
||||||
|
auto call = hub.make_vane_call();
|
||||||
|
call.vertical.set_direction(VERTICAL_VANE_MODE_POSITION_5);
|
||||||
|
call.perform();
|
||||||
|
|
||||||
|
EXPECT_EQ(hub.status().vane_mode, MitsubishiCN105::VaneMode::POSITION_5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105ComponentTests, VaneControlActionAppliesConfiguredFields) {
|
||||||
|
TestableMitsubishiCN105Component hub;
|
||||||
|
VaneControlAction<> action(&hub, [](VaneCall &call) { call.vertical.set_direction(VERTICAL_VANE_MODE_SWING); });
|
||||||
|
|
||||||
|
action.play();
|
||||||
|
|
||||||
|
EXPECT_EQ(hub.status().vane_mode, MitsubishiCN105::VaneMode::SWING);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace esphome::mitsubishi_cn105::testing
|
} // namespace esphome::mitsubishi_cn105::testing
|
||||||
|
|||||||
Reference in New Issue
Block a user