Merge branch 'dev' into store-yaml-firmware

This commit is contained in:
J. Nick Koston
2026-05-26 09:17:39 -05:00
committed by GitHub
243 changed files with 6371 additions and 1686 deletions
+14 -14
View File
@@ -120,12 +120,12 @@ api:
lambda: 'return condition;'
then:
- logger.log:
format: "Condition true, value: %d"
args: ['value']
format: "Condition true, value: %ld"
args: ['(long) value']
else:
- logger.log:
format: "Condition false, value: %d"
args: ['value']
format: "Condition false, value: %ld"
args: ['(long) value']
- logger.log: "After if/else"
# Test nested IfAction (multiple ContinuationAction instances)
- action: test_nested_if
@@ -171,8 +171,8 @@ api:
count: !lambda 'return count;'
then:
- logger.log:
format: "Repeat iteration: %d"
args: ['iteration']
format: "Repeat iteration: %lu"
args: ['(unsigned long) iteration']
- logger.log: "After repeat"
# Test combined continuations (if + while + repeat)
- action: test_combined_continuations
@@ -193,8 +193,8 @@ api:
lambda: 'return id(api_continuation_test_counter) > 0;'
then:
- logger.log:
format: "Combined: repeat=%d, while=%d"
args: ['iteration', 'id(api_continuation_test_counter)']
format: "Combined: repeat=%lu, while=%d"
args: ['(unsigned long) iteration', 'id(api_continuation_test_counter)']
- lambda: 'id(api_continuation_test_counter)--;'
else:
- logger.log: "Skipped loops"
@@ -208,8 +208,8 @@ api:
- api.respond:
success: true
- logger.log:
format: "Status response sent (call_id=%d)"
args: [call_id]
format: "Status response sent (call_id=%lu)"
args: ['(unsigned long) call_id']
- action: test_respond_status_error
variables:
@@ -229,8 +229,8 @@ api:
value: float
then:
- logger.log:
format: "Optional response (call_id=%d, return_response=%d)"
args: [call_id, return_response]
format: "Optional response (call_id=%lu, return_response=%lu)"
args: ['(unsigned long) call_id', '(unsigned long) return_response']
- api.respond:
data: !lambda |-
root["sensor"] = sensor_name;
@@ -264,8 +264,8 @@ api:
input: string
then:
- logger.log:
format: "Only response (call_id=%d)"
args: [call_id]
format: "Only response (call_id=%lu)"
args: ['(unsigned long) call_id']
- api.respond:
data: !lambda |-
root["input"] = input;
@@ -0,0 +1,11 @@
audio_file:
- id: test_audio
file:
type: local
path: $component_dir/test.wav
media_source:
- platform: audio_file
id: audio_file_source
# task_stack_in_psram: false must validate without a psram: component
task_stack_in_psram: false
@@ -1,6 +1,8 @@
<<: !include common.yaml
esp32_ble_tracker:
esp32_ble:
max_connections: 9
bluetooth_proxy:
@@ -3,6 +3,7 @@ esp32_hosted:
slot: 1
active_high: true
reset_pin: GPIO15
use_psram: true
cmd_pin: GPIO13
clk_pin: GPIO12
d0_pin: GPIO11
+2
View File
@@ -2,6 +2,8 @@ esphome:
debug_scheduler: true
platformio_options:
board_build.flash_mode: dio
build_flags:
- "-DESPHOME_TEST_BUILD_FLAG"
environment_variables:
TEST_ENV_VAR: "test_value"
BUILD_NUMBER: "12345"
@@ -1,13 +1,3 @@
substitutions:
i2s_bclk_pin: GPIO27
i2s_lrclk_pin: GPIO26
i2s_mclk_pin: GPIO25
i2s_dout_pin: GPIO12
spdif_data_pin: GPIO4
packages:
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
i2s_audio:
- id: i2s_output
@@ -20,6 +10,5 @@ speaker:
use_apll: true
timeout: 2s
sample_rate: 48000
bits_per_sample: 16bit
channel: stereo
i2s_mode: primary
@@ -0,0 +1,8 @@
substitutions:
i2s_bclk_pin: GPIO27
i2s_lrclk_pin: GPIO26
i2s_mclk_pin: GPIO25
i2s_dout_pin: GPIO12
spdif_data_pin: GPIO4
<<: !include common-spdif_mode.yaml
+10
View File
@@ -103,6 +103,16 @@ esphome:
- light.turn_on:
id: test_monochromatic_light
effect: !lambda 'return iteration > 1 ? "Strobe" : "none";'
# Cycle through configured effects (skip "None")
- light.effect.next: test_monochromatic_light
- light.effect.previous: test_monochromatic_light
# Cycle through effects including "None"
- light.effect.next:
id: test_monochromatic_light
include_none: true
- light.effect.previous:
id: test_monochromatic_light
include_none: true
- light.dim_relative:
id: test_monochromatic_light
relative_brightness: 5%
@@ -1,3 +1,6 @@
psram:
mode: quad
i2s_audio:
i2s_lrclk_pin: GPIO18
i2s_bclk_pin: GPIO19
@@ -12,6 +15,7 @@ microphone:
micro_wake_word:
microphone: echo_microphone
task_stack_in_psram: true
on_wake_word_detected:
- logger.log: "Wake word detected"
- micro_wake_word.stop:
@@ -0,0 +1,165 @@
#include "../common.h"
namespace esphome::mitsubishi_cn105::testing {
TEST(MitsubishiCN105ClimateTests, SupportedSwingModeOffLeavesTraitsEmpty) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_OFF);
EXPECT_FALSE(sut.traits().get_supports_swing_modes());
}
TEST(MitsubishiCN105ClimateTests, SupportedSwingModeVerticalExposesOffAndVertical) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_VERTICAL);
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_OFF));
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_VERTICAL));
EXPECT_FALSE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_HORIZONTAL));
EXPECT_FALSE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_BOTH));
}
TEST(MitsubishiCN105ClimateTests, SupportedSwingModeHorizontalExposesOffAndHorizontal) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_HORIZONTAL);
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_OFF));
EXPECT_FALSE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_VERTICAL));
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_HORIZONTAL));
EXPECT_FALSE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_BOTH));
}
TEST(MitsubishiCN105ClimateTests, SupportedSwingModeBothExposesAllExpectedModes) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_BOTH);
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_OFF));
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_VERTICAL));
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_HORIZONTAL));
EXPECT_TRUE(sut.traits().supports_swing_mode(climate::CLIMATE_SWING_BOTH));
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesMapsVerticalSwingWhenSupported) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_VERTICAL);
sut.status().vane_mode = MitsubishiCN105::VaneMode::SWING;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::CENTER;
sut.apply_values_();
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_VERTICAL);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesMapsHorizontalSwingWhenSupported) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_HORIZONTAL);
sut.status().vane_mode = MitsubishiCN105::VaneMode::AUTO;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::SWING;
sut.apply_values_();
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_HORIZONTAL);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesMapsBothSwingWhenSupported) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_BOTH);
sut.status().vane_mode = MitsubishiCN105::VaneMode::SWING;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::SWING;
sut.apply_values_();
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_BOTH);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesMapsSwingOffWhenNoSwingActive) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_BOTH);
sut.status().vane_mode = MitsubishiCN105::VaneMode::POSITION_3;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::CENTER;
sut.apply_values_();
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_OFF);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesRemembersLastNonSwingPositions) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_BOTH);
sut.status().vane_mode = MitsubishiCN105::VaneMode::POSITION_4;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::RIGHT;
sut.apply_values_();
EXPECT_EQ(sut.last_non_swing_vane_mode_, MitsubishiCN105::VaneMode::POSITION_4);
EXPECT_EQ(sut.last_non_swing_wide_vane_mode_, MitsubishiCN105::WideVaneMode::RIGHT);
sut.status().vane_mode = MitsubishiCN105::VaneMode::SWING;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::SWING;
sut.apply_values_();
EXPECT_EQ(sut.last_non_swing_vane_mode_, MitsubishiCN105::VaneMode::POSITION_4);
EXPECT_EQ(sut.last_non_swing_wide_vane_mode_, MitsubishiCN105::WideVaneMode::RIGHT);
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_BOTH);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesDoesNotOverwriteRememberedPositionWithUnknownValues) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_BOTH);
sut.last_non_swing_vane_mode_ = MitsubishiCN105::VaneMode::POSITION_2;
sut.last_non_swing_wide_vane_mode_ = MitsubishiCN105::WideVaneMode::LEFT;
sut.status().vane_mode = MitsubishiCN105::VaneMode::UNKNOWN;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::UNKNOWN;
sut.apply_values_();
EXPECT_EQ(sut.last_non_swing_vane_mode_, MitsubishiCN105::VaneMode::POSITION_2);
EXPECT_EQ(sut.last_non_swing_wide_vane_mode_, MitsubishiCN105::WideVaneMode::LEFT);
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_OFF);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesIgnoresUnsupportedVerticalSwingState) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_HORIZONTAL);
sut.status().vane_mode = MitsubishiCN105::VaneMode::SWING;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::CENTER;
sut.apply_values_();
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_OFF);
}
TEST(MitsubishiCN105ClimateTests, ApplyValuesIgnoresUnsupportedHorizontalSwingState) {
TestableMitsubishiCN105Climate sut;
sut.set_supported_swing_mode(climate::CLIMATE_SWING_VERTICAL);
sut.status().vane_mode = MitsubishiCN105::VaneMode::AUTO;
sut.status().wide_vane_mode = MitsubishiCN105::WideVaneMode::SWING;
sut.apply_values_();
EXPECT_EQ(sut.swing_mode, climate::CLIMATE_SWING_OFF);
}
} // namespace esphome::mitsubishi_cn105::testing
@@ -8,6 +8,7 @@
#include <vector>
#include "esphome/components/uart/uart_component.h"
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105.h"
#include "esphome/components/mitsubishi_cn105/mitsubishi_cn105_climate.h"
namespace esphome::mitsubishi_cn105::testing {
@@ -44,6 +45,7 @@ class TestableMitsubishiCN105 : public MitsubishiCN105 {
using MitsubishiCN105::State;
using MitsubishiCN105::UpdateFlag;
using MitsubishiCN105::state_;
using MitsubishiCN105::status_;
using MitsubishiCN105::operation_start_ms_;
using MitsubishiCN105::use_temperature_encoding_b_;
using MitsubishiCN105::set_wide_vane_high_bit_;
@@ -58,4 +60,13 @@ class TestableMitsubishiCN105 : public MitsubishiCN105 {
void set_current_time(uint32_t ms) { test_loop_time_ms = ms; }
};
class TestableMitsubishiCN105Climate : public MitsubishiCN105Climate {
public:
using MitsubishiCN105Climate::apply_values_;
using MitsubishiCN105Climate::last_non_swing_vane_mode_;
using MitsubishiCN105Climate::last_non_swing_wide_vane_mode_;
MitsubishiCN105::Status &status() { return static_cast<TestableMitsubishiCN105 &>(this->hp_).status_; }
};
} // namespace esphome::mitsubishi_cn105::testing
@@ -3,6 +3,9 @@ climate:
id: ac
name: "AC Test"
uart_id: uart_bus
update_interval: 30s
current_temperature_min_interval: 120s
supported_swing_modes: BOTH
esphome:
on_boot:
+4
View File
@@ -16,8 +16,12 @@ speaker:
id: speaker_id
dac_type: external
i2s_dout_pin: ${dout_pin}
bits_per_sample: 32bit
channel: stereo
- platform: mixer
output_speaker: speaker_id
bits_per_sample: 32
num_channels: 2
source_speakers:
- id: source_speaker_1_id
- id: source_speaker_2_id
+40
View File
@@ -0,0 +1,40 @@
esphome:
on_boot:
then:
- router.speaker.switch_output:
id: router_id
target_speaker: speaker_b_id
# id omitted: auto-resolved since there's a single router instance
- router.speaker.switch_output:
target_speaker: !lambda return id(speaker_a_id);
i2s_audio:
i2s_lrclk_pin: ${a_lrclk_pin}
i2s_bclk_pin: ${a_bclk_pin}
speaker:
- platform: i2s_audio
id: speaker_a_id
dac_type: external
i2s_dout_pin: ${a_dout_pin}
sample_rate: 48000
bits_per_sample: 16bit
channel: stereo
- platform: i2s_audio
id: speaker_b_id
dac_type: external
i2s_dout_pin: ${b_dout_pin}
spdif_mode: true
use_apll: true
sample_rate: 48000
bits_per_sample: 16bit
channel: stereo
i2s_mode: primary
- platform: router
id: router_id
output_speakers:
- speaker_a_id
- speaker_b_id
sample_rate: 48000
bits_per_sample: 16
num_channels: 2
@@ -0,0 +1,7 @@
substitutions:
a_lrclk_pin: GPIO4
a_bclk_pin: GPIO5
a_dout_pin: GPIO14
b_dout_pin: GPIO19
<<: !include common.yaml
@@ -1,4 +1,5 @@
rp2040:
variant: rp2040
enable_full_printf: false
logger:
@@ -0,0 +1,6 @@
rp2040:
variant: rp2350
enable_full_printf: false
logger:
level: VERBOSE