mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[mitsubishi_cn105] Add vertical vane direction select (#16723)
Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
co-authored by
J. Nick Koston
J. Nick Koston
parent
82a63658f9
commit
c8d2c3691a
@@ -133,9 +133,7 @@ void MitsubishiCN105Climate::control(const climate::ClimateCall &call) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->parent_->is_status_initialized()) {
|
this->parent_->publish_status();
|
||||||
this->apply_values_();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MitsubishiCN105Climate::apply_values_() {
|
void MitsubishiCN105Climate::apply_values_() {
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ class MitsubishiCN105Component : public Component, public uart::UARTDevice {
|
|||||||
this->status_callback_.add(std::forward<F>(callback));
|
this->status_callback_.add(std::forward<F>(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void publish_status() {
|
||||||
|
if (this->is_status_initialized()) {
|
||||||
|
this->status_callback_.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MitsubishiCN105 hp_;
|
MitsubishiCN105 hp_;
|
||||||
CallbackManager<void()> status_callback_;
|
CallbackManager<void()> status_callback_;
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import select
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
from esphome.types import ConfigType
|
||||||
|
|
||||||
|
from .. import (
|
||||||
|
MITSUBISHI_CN105_DEVICE_SCHEMA,
|
||||||
|
MitsubishiCN105Component,
|
||||||
|
mitsubishi_ns,
|
||||||
|
register_mitsubishi_cn105_device,
|
||||||
|
)
|
||||||
|
|
||||||
|
DEPENDENCIES = ["mitsubishi_cn105"]
|
||||||
|
|
||||||
|
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",
|
||||||
|
select.Select,
|
||||||
|
cg.Component,
|
||||||
|
cg.Parented.template(MitsubishiCN105Component),
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_VERTICAL_VANE_DIRECTION): select.select_schema(
|
||||||
|
MitsubishiCN105VerticalVaneDirectionSelect,
|
||||||
|
icon="mdi:arrow-up-down",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
).extend(MITSUBISHI_CN105_DEVICE_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config: ConfigType) -> None:
|
||||||
|
if vertical_vane_direction := config.get(CONF_VERTICAL_VANE_DIRECTION):
|
||||||
|
var = cg.new_Pvariable(vertical_vane_direction[CONF_ID])
|
||||||
|
await cg.register_component(var, vertical_vane_direction)
|
||||||
|
await select.register_select(
|
||||||
|
var,
|
||||||
|
vertical_vane_direction,
|
||||||
|
options=VERTICAL_VANE_DIRECTIONS,
|
||||||
|
)
|
||||||
|
await register_mitsubishi_cn105_device(var, config)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include "mitsubishi_cn105_vane_select_vertical.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace esphome::mitsubishi_cn105 {
|
||||||
|
|
||||||
|
// NOTE: This order must match VERTICAL_VANE_DIRECTIONS in select.py.
|
||||||
|
// MitsubishiCN105VerticalVaneDirectionSelect uses the preferred index-based
|
||||||
|
// Select API, so Python option order and this array must stay aligned.
|
||||||
|
static constexpr std::array VALUES{
|
||||||
|
MitsubishiCN105::VaneMode::AUTO, MitsubishiCN105::VaneMode::POSITION_1, MitsubishiCN105::VaneMode::POSITION_2,
|
||||||
|
MitsubishiCN105::VaneMode::POSITION_3, MitsubishiCN105::VaneMode::POSITION_4, MitsubishiCN105::VaneMode::POSITION_5,
|
||||||
|
MitsubishiCN105::VaneMode::SWING,
|
||||||
|
};
|
||||||
|
|
||||||
|
void MitsubishiCN105VerticalVaneDirectionSelect::setup() {
|
||||||
|
this->parent_->add_on_status_callback([this]() { this->publish_vane_state(this->parent_->status().vane_mode); });
|
||||||
|
if (this->parent_->is_status_initialized()) {
|
||||||
|
this->publish_vane_state(this->parent_->status().vane_mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MitsubishiCN105VerticalVaneDirectionSelect::control(size_t index) {
|
||||||
|
if (index < VALUES.size()) {
|
||||||
|
this->parent_->set_vane_mode(VALUES[index]);
|
||||||
|
this->parent_->publish_status();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MitsubishiCN105VerticalVaneDirectionSelect::publish_vane_state(MitsubishiCN105::VaneMode mode) {
|
||||||
|
for (size_t i = 0; i < VALUES.size(); ++i) {
|
||||||
|
if (VALUES[i] == mode) {
|
||||||
|
this->publish_state(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace esphome::mitsubishi_cn105
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../mitsubishi_cn105_component.h"
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
|
||||||
|
namespace esphome::mitsubishi_cn105 {
|
||||||
|
|
||||||
|
class MitsubishiCN105VerticalVaneDirectionSelect : public select::Select,
|
||||||
|
public Component,
|
||||||
|
public Parented<MitsubishiCN105Component> {
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void publish_vane_state(MitsubishiCN105::VaneMode mode);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(size_t index) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace esphome::mitsubishi_cn105
|
||||||
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
namespace esphome::mitsubishi_cn105::testing {
|
namespace esphome::mitsubishi_cn105::testing {
|
||||||
|
|
||||||
struct TestContext {
|
struct MitsubishiCN105TestsContext {
|
||||||
MockUARTComponent uart;
|
MockUARTComponent uart;
|
||||||
uart::UARTDevice device{&uart};
|
uart::UARTDevice device{&uart};
|
||||||
TestableMitsubishiCN105 sut{device};
|
TestableMitsubishiCN105 sut{device};
|
||||||
|
|
||||||
TestContext() { this->sut.set_current_time(0); }
|
MitsubishiCN105TestsContext() { this->sut.set_current_time(0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, InitSendsConnectPacket) {
|
TEST(MitsubishiCN105Tests, InitSendsConnectPacket) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_current_time(123);
|
ctx.sut.set_current_time(123);
|
||||||
EXPECT_EQ(ctx.sut.state_, TestableMitsubishiCN105::State::NOT_CONNECTED);
|
EXPECT_EQ(ctx.sut.state_, TestableMitsubishiCN105::State::NOT_CONNECTED);
|
||||||
@@ -26,7 +26,7 @@ TEST(MitsubishiCN105Tests, InitSendsConnectPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ConnectAndUpdateStatus) {
|
TEST(MitsubishiCN105Tests, ConnectAndUpdateStatus) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.initialize();
|
ctx.sut.initialize();
|
||||||
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
||||||
@@ -106,7 +106,7 @@ TEST(MitsubishiCN105Tests, ConnectAndUpdateStatus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, NoResponseTriggersReconnect) {
|
TEST(MitsubishiCN105Tests, NoResponseTriggersReconnect) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.initialize();
|
ctx.sut.initialize();
|
||||||
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
||||||
@@ -133,7 +133,7 @@ TEST(MitsubishiCN105Tests, NoResponseTriggersReconnect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, RxWatchdogLimitsProcessingPerUpdate) {
|
TEST(MitsubishiCN105Tests, RxWatchdogLimitsProcessingPerUpdate) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.initialize();
|
ctx.sut.initialize();
|
||||||
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
||||||
@@ -164,7 +164,7 @@ TEST(MitsubishiCN105Tests, RxWatchdogLimitsProcessingPerUpdate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ParserHandlesMixedRxStream) {
|
TEST(MitsubishiCN105Tests, ParserHandlesMixedRxStream) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.initialize();
|
ctx.sut.initialize();
|
||||||
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
ctx.uart.tx.clear(); // Remove first connect packet bytes
|
||||||
@@ -228,7 +228,7 @@ TEST(MitsubishiCN105Tests, ParserHandlesMixedRxStream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, NextStatusUpdateAfterUpdateIntervalMilliseconds) {
|
TEST(MitsubishiCN105Tests, NextStatusUpdateAfterUpdateIntervalMilliseconds) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_update_interval(2000);
|
ctx.sut.set_update_interval(2000);
|
||||||
ctx.sut.set_current_time(80000);
|
ctx.sut.set_current_time(80000);
|
||||||
@@ -258,7 +258,7 @@ TEST(MitsubishiCN105Tests, NextStatusUpdateAfterUpdateIntervalMilliseconds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, DecodeStatusSettingsPackageTempEncodedA) {
|
TEST(MitsubishiCN105Tests, DecodeStatusSettingsPackageTempEncodedA) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.uart.push_rx(
|
ctx.uart.push_rx(
|
||||||
{0xFC, 0x62, 0x01, 0x30, 0x0C, 0x02, 0x00, 0x00, 0x01, 0x03, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55});
|
{0xFC, 0x62, 0x01, 0x30, 0x0C, 0x02, 0x00, 0x00, 0x01, 0x03, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55});
|
||||||
@@ -273,7 +273,7 @@ TEST(MitsubishiCN105Tests, DecodeStatusSettingsPackageTempEncodedA) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, DecodeStatusSettingsPackageTempEncodedB) {
|
TEST(MitsubishiCN105Tests, DecodeStatusSettingsPackageTempEncodedB) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.uart.push_rx(
|
ctx.uart.push_rx(
|
||||||
{0xFC, 0x62, 0x01, 0x30, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xAD});
|
{0xFC, 0x62, 0x01, 0x30, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xAD});
|
||||||
@@ -288,7 +288,7 @@ TEST(MitsubishiCN105Tests, DecodeStatusSettingsPackageTempEncodedB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, DecodeStatusRoomTempPackageTempEncodedA) {
|
TEST(MitsubishiCN105Tests, DecodeStatusRoomTempPackageTempEncodedA) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x07, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5D});
|
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x07, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5D});
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@ TEST(MitsubishiCN105Tests, DecodeStatusRoomTempPackageTempEncodedA) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, DecodeStatusRoomTempPackageTempEncodedB) {
|
TEST(MitsubishiCN105Tests, DecodeStatusRoomTempPackageTempEncodedB) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xA7});
|
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xA7});
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ TEST(MitsubishiCN105Tests, DecodeStatusRoomTempPackageTempEncodedB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, DecodeWideVanePackageHighBitNotSet) {
|
TEST(MitsubishiCN105Tests, DecodeWideVanePackageHighBitNotSet) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58});
|
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58});
|
||||||
@@ -320,7 +320,7 @@ TEST(MitsubishiCN105Tests, DecodeWideVanePackageHighBitNotSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, DecodeWideVanePackageHighBitSet) {
|
TEST(MitsubishiCN105Tests, DecodeWideVanePackageHighBitSet) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
ctx.uart.push_rx({0xFC, 0x62, 0x01, 0x30, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8});
|
0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8});
|
||||||
@@ -332,7 +332,7 @@ TEST(MitsubishiCN105Tests, DecodeWideVanePackageHighBitSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplySettingsPowerOn) {
|
TEST(MitsubishiCN105Tests, ApplySettingsPowerOn) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_power(true);
|
ctx.sut.set_power(true);
|
||||||
ctx.sut.apply_settings();
|
ctx.sut.apply_settings();
|
||||||
@@ -342,7 +342,7 @@ TEST(MitsubishiCN105Tests, ApplySettingsPowerOn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedA) {
|
TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedA) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_target_temperature(23.0f);
|
ctx.sut.set_target_temperature(23.0f);
|
||||||
ctx.sut.apply_settings();
|
ctx.sut.apply_settings();
|
||||||
@@ -352,7 +352,7 @@ TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedA) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedB) {
|
TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedB) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.use_temperature_encoding_b_ = true;
|
ctx.sut.use_temperature_encoding_b_ = true;
|
||||||
ctx.sut.set_target_temperature(26.0f);
|
ctx.sut.set_target_temperature(26.0f);
|
||||||
@@ -363,7 +363,7 @@ TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplySettingsHalfDegreeTemperatureEncodedB) {
|
TEST(MitsubishiCN105Tests, ApplySettingsHalfDegreeTemperatureEncodedB) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.use_temperature_encoding_b_ = true;
|
ctx.sut.use_temperature_encoding_b_ = true;
|
||||||
ctx.sut.set_target_temperature(26.5f);
|
ctx.sut.set_target_temperature(26.5f);
|
||||||
@@ -374,7 +374,7 @@ TEST(MitsubishiCN105Tests, ApplySettingsHalfDegreeTemperatureEncodedB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplyModeCool) {
|
TEST(MitsubishiCN105Tests, ApplyModeCool) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_mode(MitsubishiCN105::Mode::COOL);
|
ctx.sut.set_mode(MitsubishiCN105::Mode::COOL);
|
||||||
ctx.sut.apply_settings();
|
ctx.sut.apply_settings();
|
||||||
@@ -384,7 +384,7 @@ TEST(MitsubishiCN105Tests, ApplyModeCool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplyFanModeSpeed1) {
|
TEST(MitsubishiCN105Tests, ApplyFanModeSpeed1) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_fan_mode(MitsubishiCN105::FanMode::SPEED_1);
|
ctx.sut.set_fan_mode(MitsubishiCN105::FanMode::SPEED_1);
|
||||||
ctx.sut.apply_settings();
|
ctx.sut.apply_settings();
|
||||||
@@ -394,7 +394,7 @@ TEST(MitsubishiCN105Tests, ApplyFanModeSpeed1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplyVaneModeSwing) {
|
TEST(MitsubishiCN105Tests, ApplyVaneModeSwing) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_vane_mode(MitsubishiCN105::VaneMode::SWING);
|
ctx.sut.set_vane_mode(MitsubishiCN105::VaneMode::SWING);
|
||||||
ctx.sut.apply_settings();
|
ctx.sut.apply_settings();
|
||||||
@@ -404,7 +404,7 @@ TEST(MitsubishiCN105Tests, ApplyVaneModeSwing) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplyWideVaneModeLeftAndHighBitNotSet) {
|
TEST(MitsubishiCN105Tests, ApplyWideVaneModeLeftAndHighBitNotSet) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_wide_vane_mode(MitsubishiCN105::WideVaneMode::LEFT);
|
ctx.sut.set_wide_vane_mode(MitsubishiCN105::WideVaneMode::LEFT);
|
||||||
ctx.sut.apply_settings();
|
ctx.sut.apply_settings();
|
||||||
@@ -414,7 +414,7 @@ TEST(MitsubishiCN105Tests, ApplyWideVaneModeLeftAndHighBitNotSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplyWideVaneModeLeftAndHighBitSet) {
|
TEST(MitsubishiCN105Tests, ApplyWideVaneModeLeftAndHighBitSet) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_wide_vane_high_bit_ = true;
|
ctx.sut.set_wide_vane_high_bit_ = true;
|
||||||
ctx.sut.set_wide_vane_mode(MitsubishiCN105::WideVaneMode::LEFT);
|
ctx.sut.set_wide_vane_mode(MitsubishiCN105::WideVaneMode::LEFT);
|
||||||
@@ -425,7 +425,7 @@ TEST(MitsubishiCN105Tests, ApplyWideVaneModeLeftAndHighBitSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, WriteInterruptsWaitingForNextStatusUpdate) {
|
TEST(MitsubishiCN105Tests, WriteInterruptsWaitingForNextStatusUpdate) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_update_interval(2000);
|
ctx.sut.set_update_interval(2000);
|
||||||
ctx.sut.set_current_time(5000);
|
ctx.sut.set_current_time(5000);
|
||||||
@@ -470,7 +470,7 @@ TEST(MitsubishiCN105Tests, WriteInterruptsWaitingForNextStatusUpdate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, SetAndClearRemoteRoomTemp) {
|
TEST(MitsubishiCN105Tests, SetAndClearRemoteRoomTemp) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
// Set remote temperature
|
// Set remote temperature
|
||||||
ctx.sut.set_remote_temperature(28.5f);
|
ctx.sut.set_remote_temperature(28.5f);
|
||||||
@@ -505,7 +505,7 @@ TEST(MitsubishiCN105Tests, SetAndClearRemoteRoomTemp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, ApplyQueuedSettingsThenRemoteRoomTempInSecondWrite) {
|
TEST(MitsubishiCN105Tests, ApplyQueuedSettingsThenRemoteRoomTempInSecondWrite) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
// Queue normal settings plus remote temperature together.
|
// Queue normal settings plus remote temperature together.
|
||||||
ctx.sut.use_temperature_encoding_b_ = true;
|
ctx.sut.use_temperature_encoding_b_ = true;
|
||||||
@@ -545,7 +545,7 @@ TEST(MitsubishiCN105Tests, ApplyQueuedSettingsThenRemoteRoomTempInSecondWrite) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, WriteTimeoutClearsStatusUpdateWaitCreditOnReconnect) {
|
TEST(MitsubishiCN105Tests, WriteTimeoutClearsStatusUpdateWaitCreditOnReconnect) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
ctx.sut.set_update_interval(2000);
|
ctx.sut.set_update_interval(2000);
|
||||||
ctx.sut.set_current_time(5000);
|
ctx.sut.set_current_time(5000);
|
||||||
|
|
||||||
@@ -578,7 +578,7 @@ TEST(MitsubishiCN105Tests, WriteTimeoutClearsStatusUpdateWaitCreditOnReconnect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, SetOutOfRangeRemoteRoomTempIsIgnored) {
|
TEST(MitsubishiCN105Tests, SetOutOfRangeRemoteRoomTempIsIgnored) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
|
|
||||||
ctx.sut.set_remote_temperature(7.0f);
|
ctx.sut.set_remote_temperature(7.0f);
|
||||||
EXPECT_FALSE(ctx.sut.pending_updates_.contains(TestableMitsubishiCN105::UpdateFlag::REMOTE_TEMPERATURE));
|
EXPECT_FALSE(ctx.sut.pending_updates_.contains(TestableMitsubishiCN105::UpdateFlag::REMOTE_TEMPERATURE));
|
||||||
@@ -591,13 +591,13 @@ TEST(MitsubishiCN105Tests, SetOutOfRangeRemoteRoomTempIsIgnored) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, SetMinRemoteRoomTemp) {
|
TEST(MitsubishiCN105Tests, SetMinRemoteRoomTemp) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
ctx.sut.set_remote_temperature(8.0f);
|
ctx.sut.set_remote_temperature(8.0f);
|
||||||
EXPECT_TRUE(ctx.sut.pending_updates_.contains(TestableMitsubishiCN105::UpdateFlag::REMOTE_TEMPERATURE));
|
EXPECT_TRUE(ctx.sut.pending_updates_.contains(TestableMitsubishiCN105::UpdateFlag::REMOTE_TEMPERATURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MitsubishiCN105Tests, SetMaxRemoteRoomTemp) {
|
TEST(MitsubishiCN105Tests, SetMaxRemoteRoomTemp) {
|
||||||
auto ctx = TestContext{};
|
MitsubishiCN105TestsContext ctx;
|
||||||
ctx.sut.set_remote_temperature(39.5f);
|
ctx.sut.set_remote_temperature(39.5f);
|
||||||
EXPECT_TRUE(ctx.sut.pending_updates_.contains(TestableMitsubishiCN105::UpdateFlag::REMOTE_TEMPERATURE));
|
EXPECT_TRUE(ctx.sut.pending_updates_.contains(TestableMitsubishiCN105::UpdateFlag::REMOTE_TEMPERATURE));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ climate:
|
|||||||
name: "AC Test"
|
name: "AC Test"
|
||||||
supported_swing_modes: BOTH
|
supported_swing_modes: BOTH
|
||||||
|
|
||||||
|
select:
|
||||||
|
- platform: mitsubishi_cn105
|
||||||
|
mitsubishi_cn105_id: ac
|
||||||
|
vertical_vane_direction:
|
||||||
|
name: "Vertical Vane"
|
||||||
|
|
||||||
esphome:
|
esphome:
|
||||||
on_boot:
|
on_boot:
|
||||||
then:
|
then:
|
||||||
|
|||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
#include "../common.h"
|
||||||
|
#include "esphome/components/mitsubishi_cn105/select/mitsubishi_cn105_vane_select_vertical.h"
|
||||||
|
|
||||||
|
namespace esphome::mitsubishi_cn105::testing {
|
||||||
|
|
||||||
|
class TestableMitsubishiCN105Component : public MitsubishiCN105Component {
|
||||||
|
public:
|
||||||
|
MitsubishiCN105::Status &mutable_status() { return const_cast<MitsubishiCN105::Status &>(this->status()); }
|
||||||
|
|
||||||
|
void notify_status() { this->status_callback_.call(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestableMitsubishiCN105VerticalVaneDirectionSelect : public MitsubishiCN105VerticalVaneDirectionSelect {
|
||||||
|
public:
|
||||||
|
using MitsubishiCN105VerticalVaneDirectionSelect::control;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VerticalVaneDirectionSelectTestContext {
|
||||||
|
TestableMitsubishiCN105Component hub;
|
||||||
|
TestableMitsubishiCN105VerticalVaneDirectionSelect select;
|
||||||
|
|
||||||
|
VerticalVaneDirectionSelectTestContext() {
|
||||||
|
this->select.traits.set_options({"Auto", "1", "2", "3", "4", "5", "Swing"});
|
||||||
|
this->select.set_parent(&this->hub);
|
||||||
|
this->select.setup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105VerticalVaneDirectionSelectTests, MapsIndexesToVaneModes) {
|
||||||
|
VerticalVaneDirectionSelectTestContext ctx;
|
||||||
|
|
||||||
|
constexpr std::array expected_modes{
|
||||||
|
MitsubishiCN105::VaneMode::AUTO, MitsubishiCN105::VaneMode::POSITION_1,
|
||||||
|
MitsubishiCN105::VaneMode::POSITION_2, MitsubishiCN105::VaneMode::POSITION_3,
|
||||||
|
MitsubishiCN105::VaneMode::POSITION_4, MitsubishiCN105::VaneMode::POSITION_5,
|
||||||
|
MitsubishiCN105::VaneMode::SWING,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < expected_modes.size(); ++i) {
|
||||||
|
SCOPED_TRACE(i);
|
||||||
|
ctx.select.control(i);
|
||||||
|
EXPECT_EQ(ctx.hub.status().vane_mode, expected_modes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105VerticalVaneDirectionSelectTests, PublishesIncomingVaneModes) {
|
||||||
|
VerticalVaneDirectionSelectTestContext ctx;
|
||||||
|
|
||||||
|
constexpr std::array modes{
|
||||||
|
MitsubishiCN105::VaneMode::AUTO, MitsubishiCN105::VaneMode::POSITION_1,
|
||||||
|
MitsubishiCN105::VaneMode::POSITION_2, MitsubishiCN105::VaneMode::POSITION_3,
|
||||||
|
MitsubishiCN105::VaneMode::POSITION_4, MitsubishiCN105::VaneMode::POSITION_5,
|
||||||
|
MitsubishiCN105::VaneMode::SWING,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < modes.size(); ++i) {
|
||||||
|
SCOPED_TRACE(i);
|
||||||
|
ctx.hub.mutable_status().vane_mode = modes[i];
|
||||||
|
ctx.hub.notify_status();
|
||||||
|
EXPECT_EQ(ctx.select.active_index(), std::optional{i});
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.hub.mutable_status().vane_mode = MitsubishiCN105::VaneMode::UNKNOWN;
|
||||||
|
ctx.hub.notify_status();
|
||||||
|
EXPECT_EQ(ctx.select.active_index(), std::optional{modes.size() - 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105VerticalVaneDirectionSelectTests, ControlPublishesSelectAndClimateThroughHub) {
|
||||||
|
VerticalVaneDirectionSelectTestContext ctx;
|
||||||
|
MitsubishiCN105Climate climate_entity;
|
||||||
|
climate_entity.set_parent(&ctx.hub);
|
||||||
|
climate_entity.set_supported_swing_mode(climate::CLIMATE_SWING_VERTICAL);
|
||||||
|
|
||||||
|
ctx.hub.mutable_status().room_temperature = 20.0f;
|
||||||
|
climate_entity.setup();
|
||||||
|
|
||||||
|
ctx.select.control(6);
|
||||||
|
EXPECT_EQ(ctx.select.active_index(), std::optional<size_t>{6});
|
||||||
|
EXPECT_EQ(climate_entity.swing_mode, climate::CLIMATE_SWING_VERTICAL);
|
||||||
|
|
||||||
|
ctx.select.control(3);
|
||||||
|
EXPECT_EQ(ctx.select.active_index(), std::optional<size_t>{3});
|
||||||
|
EXPECT_EQ(climate_entity.swing_mode, climate::CLIMATE_SWING_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105VerticalVaneDirectionSelectTests, ClimateControlPublishesSelectThroughHub) {
|
||||||
|
VerticalVaneDirectionSelectTestContext ctx;
|
||||||
|
MitsubishiCN105Climate climate_entity;
|
||||||
|
climate_entity.set_parent(&ctx.hub);
|
||||||
|
climate_entity.set_supported_swing_mode(climate::CLIMATE_SWING_VERTICAL);
|
||||||
|
|
||||||
|
ctx.hub.mutable_status().room_temperature = 20.0f;
|
||||||
|
climate_entity.setup();
|
||||||
|
|
||||||
|
climate_entity.make_call().set_swing_mode(climate::CLIMATE_SWING_VERTICAL).perform();
|
||||||
|
EXPECT_EQ(ctx.select.active_index(), std::optional<size_t>{6});
|
||||||
|
|
||||||
|
climate_entity.make_call().set_swing_mode(climate::CLIMATE_SWING_OFF).perform();
|
||||||
|
EXPECT_EQ(ctx.select.active_index(), std::optional<size_t>{0});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MitsubishiCN105VerticalVaneDirectionSelectTests, BeforeInitializationDoesNotPublishSelectState) {
|
||||||
|
VerticalVaneDirectionSelectTestContext ctx;
|
||||||
|
|
||||||
|
ctx.select.control(3);
|
||||||
|
|
||||||
|
EXPECT_EQ(ctx.hub.status().vane_mode, MitsubishiCN105::VaneMode::POSITION_3);
|
||||||
|
EXPECT_FALSE(ctx.select.has_state());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace esphome::mitsubishi_cn105::testing
|
||||||
Reference in New Issue
Block a user