[ld2420][ld2450] Use Apply numbers for hub forwarding numbers (#21146)

This commit is contained in:
J. Nick Koston
2026-10-20 09:06:58 -04:00
committed by GitHub
parent 442bd4975e
commit 89eb58edce
14 changed files with 261 additions and 193 deletions
+11
View File
@@ -917,6 +917,17 @@ void LD2420Component::init_gate_config_numbers() {
}
}
void LD2420Component::set_gate_threshold_value(number::Number *n, float value) {
for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) {
const bool move = this->gate_move_threshold_numbers_[gate] == n;
if (!move && this->gate_still_threshold_numbers_[gate] != n)
continue;
const uint8_t target = this->is_gate_select() ? this->get_gate_select_value() : gate;
(move ? this->new_config.move_thresh : this->new_config.still_thresh)[target] = value;
return;
}
}
void LD2420Component::refresh_gate_config_numbers() {
this->gate_timeout_number_->publish_state(this->new_config.timeout);
this->min_gate_distance_number_->publish_state(this->new_config.min_gate);
+2
View File
@@ -89,6 +89,8 @@ class LD2420Component final : public Component, public uart::UARTDevice {
void publish_gate_still_threshold(uint8_t gate) {
this->gate_still_threshold_numbers_[0]->publish_state(this->new_config.still_thresh[gate]);
};
// Stores a threshold number's value for its gate, or for the selected gate with gate_select
void set_gate_threshold_value(number::Number *n, float value);
void init_gate_config_numbers();
void refresh_gate_config_numbers();
#endif
+41 -48
View File
@@ -1,8 +1,9 @@
from functools import partial
import esphome.codegen as cg
from esphome.components import number
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
CONF_MOVE_THRESHOLD,
CONF_STILL_THRESHOLD,
DEVICE_CLASS_DISTANCE,
@@ -16,22 +17,9 @@ from esphome.types import ConfigType
from .. import CONF_LD2420_ID, LD2420Component, ld2420_ns
LD2420TimeoutNumber = ld2420_ns.class_("LD2420TimeoutNumber", number.Number)
LD2420MoveSensFactorNumber = ld2420_ns.class_(
"LD2420MoveSensFactorNumber", number.Number
)
LD2420StillSensFactorNumber = ld2420_ns.class_(
"LD2420StillSensFactorNumber", number.Number
)
LD2420MinDistanceNumber = ld2420_ns.class_("LD2420MinDistanceNumber", number.Number)
LD2420MaxDistanceNumber = ld2420_ns.class_("LD2420MaxDistanceNumber", number.Number)
LD2420GateSelectNumber = ld2420_ns.class_("LD2420GateSelectNumber", number.Number)
LD2420MoveThresholdNumbers = ld2420_ns.class_(
"LD2420MoveThresholdNumbers", number.Number
)
LD2420StillThresholdNumbers = ld2420_ns.class_(
"LD2420StillThresholdNumbers", number.Number
)
CONF_MIN_GATE_DISTANCE = "min_gate_distance"
CONF_MAX_GATE_DISTANCE = "max_gate_distance"
CONF_GATE_MOVE_SENSITIVITY = "gate_move_sensitivity"
@@ -46,7 +34,7 @@ CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_LD2420_ID): cv.use_id(LD2420Component),
cv.Inclusive(CONF_PRESENCE_TIMEOUT, TIMEOUT_GROUP): number.number_schema(
LD2420TimeoutNumber,
number.ApplyNumber,
unit_of_measurement=UNIT_SECOND,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_TIMELAPSE,
@@ -70,23 +58,23 @@ CONFIG_SCHEMA = cv.Schema(
icon=ICON_MOTION_SENSOR,
),
cv.Inclusive(CONF_STILL_THRESHOLD, GATE_GROUP): number.number_schema(
LD2420StillThresholdNumbers,
number.ApplyNumber,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_MOTION_SENSOR,
),
cv.Inclusive(CONF_MOVE_THRESHOLD, GATE_GROUP): number.number_schema(
LD2420MoveThresholdNumbers,
number.ApplyNumber,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_MOTION_SENSOR,
),
cv.Optional(CONF_GATE_MOVE_SENSITIVITY): number.number_schema(
LD2420MoveSensFactorNumber,
number.ApplyNumber,
device_class=DEVICE_CLASS_DISTANCE,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SCALE,
),
cv.Optional(CONF_GATE_STILL_SENSITIVITY): number.number_schema(
LD2420StillSensFactorNumber,
number.ApplyNumber,
device_class=DEVICE_CLASS_DISTANCE,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SCALE,
@@ -98,12 +86,12 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend(
cv.Optional(f"gate_{x}"): (
{
cv.Required(CONF_MOVE_THRESHOLD): number.number_schema(
LD2420MoveThresholdNumbers,
number.ApplyNumber,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_MOTION_SENSOR,
),
cv.Required(CONF_STILL_THRESHOLD): number.number_schema(
LD2420StillThresholdNumbers,
number.ApplyNumber,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_MOTION_SENSOR,
),
@@ -123,6 +111,8 @@ async def to_code(config: ConfigType) -> None:
min_value=0,
max_value=255,
step=5,
apply="new_config.timeout = value",
publish="before",
)
await numbers(
CONF_MIN_GATE_DISTANCE,
@@ -144,6 +134,8 @@ async def to_code(config: ConfigType) -> None:
min_value=0.05,
max_value=1,
step=0.025,
apply="gate_move_sensitivity_factor = value",
publish="before",
)
await numbers(
CONF_GATE_STILL_SENSITIVITY,
@@ -151,7 +143,16 @@ async def to_code(config: ConfigType) -> None:
min_value=0.05,
max_value=1,
step=0.025,
apply="gate_still_sensitivity_factor = value",
publish="before",
)
threshold = {
"min_value": 0,
"max_value": 65535,
"step": 25,
"apply": "set_gate_threshold_value(entity, value)",
"publish": "before",
}
if config.get(CONF_GATE_SELECT):
await numbers(
CONF_GATE_SELECT,
@@ -160,35 +161,27 @@ async def to_code(config: ConfigType) -> None:
max_value=15,
step=1,
)
if gate_still_threshold := config.get(CONF_STILL_THRESHOLD):
n = cg.new_Pvariable(gate_still_threshold[CONF_ID])
await number.register_number(
n, gate_still_threshold, min_value=0, max_value=65535, step=25
)
await cg.register_parented(n, hub)
cg.add(hub.set_gate_still_threshold_numbers(0, n))
if gate_move_threshold := config.get(CONF_MOVE_THRESHOLD):
n = cg.new_Pvariable(gate_move_threshold[CONF_ID])
await number.register_number(
n, gate_move_threshold, min_value=0, max_value=65535, step=25
)
await cg.register_parented(n, hub)
cg.add(hub.set_gate_move_threshold_numbers(0, n))
# With gate_select one pair of numbers sits at index 0 and edits the selected gate
await numbers(
CONF_STILL_THRESHOLD,
partial(hub.set_gate_still_threshold_numbers, 0),
**threshold,
)
await numbers(
CONF_MOVE_THRESHOLD,
partial(hub.set_gate_move_threshold_numbers, 0),
**threshold,
)
else:
for x in range(16):
if gate_conf := config.get(f"gate_{x}"):
move_config = gate_conf[CONF_MOVE_THRESHOLD]
n = cg.new_Pvariable(move_config[CONF_ID], x)
await number.register_number(
n, move_config, min_value=0, max_value=65535, step=25
await numbers.create(
gate_conf[CONF_MOVE_THRESHOLD],
partial(hub.set_gate_move_threshold_numbers, x),
**threshold,
)
await cg.register_parented(n, hub)
cg.add(hub.set_gate_move_threshold_numbers(x, n))
still_config = gate_conf[CONF_STILL_THRESHOLD]
n = cg.new_Pvariable(still_config[CONF_ID], x)
await number.register_number(
n, still_config, min_value=0, max_value=65535, step=25
await numbers.create(
gate_conf[CONF_STILL_THRESHOLD],
partial(hub.set_gate_still_threshold_numbers, x),
**threshold,
)
await cg.register_parented(n, hub)
cg.add(hub.set_gate_still_threshold_numbers(x, n))
@@ -6,11 +6,6 @@ ESPHOME_LOG_TAG(TAG, "ld2420.number");
namespace esphome::ld2420 {
void LD2420TimeoutNumber::control(float timeout) {
this->publish_state(timeout);
this->parent_->new_config.timeout = timeout;
}
void LD2420MinDistanceNumber::control(float min_gate) {
if ((uint16_t) min_gate > this->parent_->new_config.max_gate) {
min_gate = this->parent_->get_min_gate_distance_value();
@@ -36,36 +31,4 @@ void LD2420GateSelectNumber::control(float gate_select) {
this->parent_->publish_gate_still_threshold(gate);
}
void LD2420MoveSensFactorNumber::control(float move_factor) {
this->publish_state(move_factor);
this->parent_->gate_move_sensitivity_factor = move_factor;
}
void LD2420StillSensFactorNumber::control(float still_factor) {
this->publish_state(still_factor);
this->parent_->gate_still_sensitivity_factor = still_factor;
}
LD2420MoveThresholdNumbers::LD2420MoveThresholdNumbers(uint8_t gate) : gate_(gate) {}
void LD2420MoveThresholdNumbers::control(float move_threshold) {
this->publish_state(move_threshold);
if (!this->parent_->is_gate_select()) {
this->parent_->new_config.move_thresh[this->gate_] = move_threshold;
} else {
this->parent_->new_config.move_thresh[this->parent_->get_gate_select_value()] = move_threshold;
}
}
LD2420StillThresholdNumbers::LD2420StillThresholdNumbers(uint8_t gate) : gate_(gate) {}
void LD2420StillThresholdNumbers::control(float still_threshold) {
this->publish_state(still_threshold);
if (!this->parent_->is_gate_select()) {
this->parent_->new_config.still_thresh[this->gate_] = still_threshold;
} else {
this->parent_->new_config.still_thresh[this->parent_->get_gate_select_value()] = still_threshold;
}
}
} // namespace esphome::ld2420
@@ -5,14 +5,6 @@
namespace esphome::ld2420 {
class LD2420TimeoutNumber final : public number::Number, public Parented<LD2420Component> {
public:
LD2420TimeoutNumber() = default;
protected:
void control(float timeout) override;
};
class LD2420MinDistanceNumber final : public number::Number, public Parented<LD2420Component> {
public:
LD2420MinDistanceNumber() = default;
@@ -37,40 +29,4 @@ class LD2420GateSelectNumber final : public number::Number, public Parented<LD24
void control(float gate_select) override;
};
class LD2420MoveSensFactorNumber final : public number::Number, public Parented<LD2420Component> {
public:
LD2420MoveSensFactorNumber() = default;
protected:
void control(float move_factor) override;
};
class LD2420StillSensFactorNumber final : public number::Number, public Parented<LD2420Component> {
public:
LD2420StillSensFactorNumber() = default;
protected:
void control(float still_factor) override;
};
class LD2420StillThresholdNumbers final : public number::Number, public Parented<LD2420Component> {
public:
LD2420StillThresholdNumbers() = default;
LD2420StillThresholdNumbers(uint8_t gate);
protected:
uint8_t gate_;
void control(float still_threshold) override;
};
class LD2420MoveThresholdNumbers final : public number::Number, public Parented<LD2420Component> {
public:
LD2420MoveThresholdNumbers() = default;
LD2420MoveThresholdNumbers(uint8_t gate);
protected:
uint8_t gate_;
void control(float move_threshold) override;
};
} // namespace esphome::ld2420
+7 -1
View File
@@ -957,7 +957,13 @@ void LD2450Component::set_direction_text_sensor(uint8_t target, text_sensor::Tex
// Send Zone coordinates data to LD2450
#ifdef USE_NUMBER
void LD2450Component::set_zone_coordinate(uint8_t zone) {
void LD2450Component::set_zone_coordinate(number::Number *n) {
uint8_t zone = 0;
while (zone < MAX_ZONES && this->zone_numbers_[zone].x1 != n && this->zone_numbers_[zone].y1 != n &&
this->zone_numbers_[zone].x2 != n && this->zone_numbers_[zone].y2 != n)
zone++;
if (zone == MAX_ZONES)
return;
number::Number *x1sens = this->zone_numbers_[zone].x1;
number::Number *y1sens = this->zone_numbers_[zone].y1;
number::Number *x2sens = this->zone_numbers_[zone].x2;
+1 -1
View File
@@ -128,7 +128,7 @@ class LD2450Component : public Component, public uart::UARTDevice {
void set_direction_text_sensor(uint8_t target, text_sensor::TextSensor *s);
#endif
#ifdef USE_NUMBER
void set_zone_coordinate(uint8_t zone);
void set_zone_coordinate(number::Number *n);
void set_zone_numbers(uint8_t zone, number::Number *x1, number::Number *y1, number::Number *x2, number::Number *y2);
#endif
#ifdef USE_SENSOR
+21 -33
View File
@@ -25,7 +25,6 @@ ICON_ARROW_TOP_LEFT_BOLD_BOX_OUTLINE = "mdi:arrow-top-left-bold-box-outline"
MAX_ZONES = 3
PresenceTimeoutNumber = ld2450_ns.class_("PresenceTimeoutNumber", number.Number)
ZoneCoordinateNumber = ld2450_ns.class_("ZoneCoordinateNumber", number.Number)
CONFIG_SCHEMA = cv.Schema(
{
@@ -45,28 +44,28 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend(
cv.Optional(f"zone_{n + 1}"): cv.Schema(
{
cv.Required(CONF_X1): number.number_schema(
ZoneCoordinateNumber,
number.ApplyNumber,
device_class=DEVICE_CLASS_DISTANCE,
unit_of_measurement=UNIT_MILLIMETER,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_ARROW_TOP_LEFT_BOLD_BOX_OUTLINE,
),
cv.Required(CONF_Y1): number.number_schema(
ZoneCoordinateNumber,
number.ApplyNumber,
device_class=DEVICE_CLASS_DISTANCE,
unit_of_measurement=UNIT_MILLIMETER,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_ARROW_TOP_LEFT,
),
cv.Required(CONF_X2): number.number_schema(
ZoneCoordinateNumber,
number.ApplyNumber,
device_class=DEVICE_CLASS_DISTANCE,
unit_of_measurement=UNIT_MILLIMETER,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_ARROW_BOTTOM_RIGHT_BOLD_BOX_OUTLINE,
),
cv.Required(CONF_Y2): number.number_schema(
ZoneCoordinateNumber,
number.ApplyNumber,
device_class=DEVICE_CLASS_DISTANCE,
unit_of_measurement=UNIT_MILLIMETER,
entity_category=ENTITY_CATEGORY_CONFIG,
@@ -91,32 +90,21 @@ async def to_code(config: ConfigType) -> None:
)
for zone_num in range(MAX_ZONES):
if zone_conf := config.get(f"zone_{zone_num + 1}"):
zone_x1_config = zone_conf.get(CONF_X1)
x1 = cg.new_Pvariable(zone_x1_config[CONF_ID], zone_num)
await number.register_number(
x1, zone_x1_config, min_value=-4860, max_value=4860, step=1
)
await cg.register_parented(x1, hub)
zone_y1_config = zone_conf.get(CONF_Y1)
y1 = cg.new_Pvariable(zone_y1_config[CONF_ID], zone_num)
await number.register_number(
y1, zone_y1_config, min_value=0, max_value=7560, step=1
)
await cg.register_parented(y1, hub)
zone_x2_config = zone_conf.get(CONF_X2)
x2 = cg.new_Pvariable(zone_x2_config[CONF_ID], zone_num)
await number.register_number(
x2, zone_x2_config, min_value=-4860, max_value=4860, step=1
)
await cg.register_parented(x2, hub)
zone_y2_config = zone_conf.get(CONF_Y2)
y2 = cg.new_Pvariable(zone_y2_config[CONF_ID], zone_num)
await number.register_number(
y2, zone_y2_config, min_value=0, max_value=7560, step=1
)
await cg.register_parented(y2, hub)
x1, y1, x2, y2 = [
await numbers.create(
zone_conf[key],
None,
min_value=lo,
max_value=hi,
step=1,
apply="set_zone_coordinate(entity)",
publish="before",
)
for key, lo, hi in (
(CONF_X1, -4860, 4860),
(CONF_Y1, 0, 7560),
(CONF_X2, -4860, 4860),
(CONF_Y2, 0, 7560),
)
]
cg.add(hub.set_zone_numbers(zone_num, x1, y1, x2, y2))
@@ -1,12 +0,0 @@
#include "zone_coordinate_number.h"
namespace esphome::ld2450 {
ZoneCoordinateNumber::ZoneCoordinateNumber(uint8_t zone) : zone_(zone) {}
void ZoneCoordinateNumber::control(float value) {
this->publish_state(value);
this->parent_->set_zone_coordinate(this->zone_);
}
} // namespace esphome::ld2450
@@ -1,17 +0,0 @@
#pragma once
#include "esphome/components/number/number.h"
#include "../ld2450.h"
namespace esphome::ld2450 {
class ZoneCoordinateNumber : public number::Number, public Parented<LD2450Component> {
public:
ZoneCoordinateNumber(uint8_t zone);
protected:
uint8_t zone_;
void control(float value) override;
};
} // namespace esphome::ld2450
@@ -0,0 +1,71 @@
#include <gtest/gtest.h>
#include "esphome/components/ld2420/ld2420.h"
namespace esphome::ld2420::testing {
class TestNumber : public number::Number {
protected:
void control(float value) override {}
};
class LD2420GateThresholdTest : public ::testing::Test {
protected:
void SetUp() override {
for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) {
this->ld2420_.new_config.move_thresh[gate] = 1000 + gate;
this->ld2420_.new_config.still_thresh[gate] = 2000 + gate;
}
}
void expect_untouched_except_(const uint32_t *thresh, uint32_t base, int skip) {
for (int gate = 0; gate < TOTAL_GATES; gate++) {
if (gate != skip)
EXPECT_EQ(thresh[gate], base + gate) << "gate " << gate;
}
}
LD2420Component ld2420_;
TestNumber move_;
TestNumber still_;
};
TEST_F(LD2420GateThresholdTest, PerGateNumbersWriteTheirOwnGate) {
this->ld2420_.set_gate_move_threshold_numbers(3, &this->move_);
this->ld2420_.set_gate_still_threshold_numbers(3, &this->still_);
this->ld2420_.set_gate_threshold_value(&this->move_, 500);
EXPECT_EQ(this->ld2420_.new_config.move_thresh[3], 500u);
this->expect_untouched_except_(this->ld2420_.new_config.move_thresh, 1000, 3);
this->expect_untouched_except_(this->ld2420_.new_config.still_thresh, 2000, -1);
this->ld2420_.set_gate_threshold_value(&this->still_, 750);
EXPECT_EQ(this->ld2420_.new_config.still_thresh[3], 750u);
EXPECT_EQ(this->ld2420_.new_config.move_thresh[3], 500u);
this->expect_untouched_except_(this->ld2420_.new_config.still_thresh, 2000, 3);
}
TEST_F(LD2420GateThresholdTest, GateSelectWritesTheSelectedGate) {
TestNumber select;
this->ld2420_.set_gate_select_number(&select);
this->ld2420_.set_gate_move_threshold_numbers(0, &this->move_);
this->ld2420_.set_gate_still_threshold_numbers(0, &this->still_);
select.publish_state(5);
this->ld2420_.set_gate_threshold_value(&this->move_, 300);
this->ld2420_.set_gate_threshold_value(&this->still_, 400);
EXPECT_EQ(this->ld2420_.new_config.move_thresh[5], 300u);
EXPECT_EQ(this->ld2420_.new_config.still_thresh[5], 400u);
this->expect_untouched_except_(this->ld2420_.new_config.move_thresh, 1000, 5);
this->expect_untouched_except_(this->ld2420_.new_config.still_thresh, 2000, 5);
}
TEST_F(LD2420GateThresholdTest, UnregisteredNumberChangesNothing) {
this->ld2420_.set_gate_move_threshold_numbers(3, &this->move_);
this->ld2420_.set_gate_still_threshold_numbers(3, &this->still_);
TestNumber other;
this->ld2420_.set_gate_threshold_value(&other, 123);
this->expect_untouched_except_(this->ld2420_.new_config.move_thresh, 1000, -1);
this->expect_untouched_except_(this->ld2420_.new_config.still_thresh, 2000, -1);
}
} // namespace esphome::ld2420::testing
@@ -0,0 +1,12 @@
from esphome.core import CORE
from esphome.types import ConfigType
from tests.testing_helpers import ComponentManifestOverride
def override_manifest(manifest: ComponentManifestOverride) -> None:
# Turns on USE_NUMBER so the hub's number forwarding code is in the host test build
async def to_code_testing(config: ConfigType) -> None:
CORE.testing_ensure_platform_registered("number")
manifest.to_code = to_code_testing
manifest.dependencies = manifest.dependencies + ["number"]
@@ -0,0 +1,83 @@
#include <algorithm>
#include "common.h"
namespace esphome::ld2450::testing {
namespace {
class CapturingUARTComponent : public MockUARTComponent {
public:
void write_array(const uint8_t *data, size_t len) override {
this->written.insert(this->written.end(), data, data + len);
}
std::vector<uint8_t> written;
};
class TestNumber : public number::Number {
protected:
void control(float value) override {}
};
// Header, length 28, command 0xC2 (set zone): the coordinate payload follows two zone type bytes.
constexpr uint8_t SET_ZONE_PREFIX[] = {0xFD, 0xFC, 0xFB, 0xFA, 0x1C, 0x00, 0xC2, 0x00};
} // namespace
class LD2450ZoneNumberTest : public ::testing::Test {
protected:
void SetUp() override {
this->ld2450_.set_uart_parent(&this->uart_);
for (auto &zone : this->ld2450_.zone_config_) {
zone = {1, 2, 3, 4};
}
// Only the third zone has numbers, so the lookup must walk past the empty slots.
this->ld2450_.set_zone_numbers(2, &this->x1_, &this->y1_, &this->x2_, &this->y2_);
this->x1_.publish_state(-100);
this->y1_.publish_state(200);
this->x2_.publish_state(1500);
this->y2_.publish_state(3000);
}
CapturingUARTComponent uart_;
TestableLD2450 ld2450_;
TestNumber x1_, y1_, x2_, y2_;
};
TEST_F(LD2450ZoneNumberTest, EachCoordinateNumberUpdatesItsZoneAndSendsCommand) {
for (TestNumber *n : {&this->x1_, &this->y1_, &this->x2_, &this->y2_}) {
this->uart_.written.clear();
this->ld2450_.zone_config_[2] = {0, 0, 0, 0};
this->ld2450_.set_zone_coordinate(n);
EXPECT_EQ(this->ld2450_.zone_config_[2].x1, -100);
EXPECT_EQ(this->ld2450_.zone_config_[2].y1, 200);
EXPECT_EQ(this->ld2450_.zone_config_[2].x2, 1500);
EXPECT_EQ(this->ld2450_.zone_config_[2].y2, 3000);
for (size_t i = 0; i < 2; i++) {
EXPECT_EQ(this->ld2450_.zone_config_[i].x1, 1) << "zone " << i;
EXPECT_EQ(this->ld2450_.zone_config_[i].y2, 4) << "zone " << i;
}
const auto &w = this->uart_.written;
auto it = std::search(w.begin(), w.end(), std::begin(SET_ZONE_PREFIX), std::end(SET_ZONE_PREFIX));
ASSERT_NE(it, w.end());
ASSERT_GE(static_cast<size_t>(w.end() - it), sizeof(SET_ZONE_PREFIX) + 26 + 4);
const uint8_t *zone2 = &*it + sizeof(SET_ZONE_PREFIX) + 2 + 2 * 8;
const std::vector<uint8_t> expected = {0x9C, 0xFF, 0xC8, 0x00, 0xDC, 0x05, 0xB8, 0x0B};
EXPECT_EQ(std::vector<uint8_t>(zone2, zone2 + 8), expected);
}
}
TEST_F(LD2450ZoneNumberTest, UnregisteredNumberChangesNothing) {
TestNumber other;
other.publish_state(42);
this->ld2450_.set_zone_coordinate(&other);
for (size_t i = 0; i < MAX_ZONES; i++) {
EXPECT_EQ(this->ld2450_.zone_config_[i].x1, 1) << "zone " << i;
EXPECT_EQ(this->ld2450_.zone_config_[i].y1, 2) << "zone " << i;
EXPECT_EQ(this->ld2450_.zone_config_[i].x2, 3) << "zone " << i;
EXPECT_EQ(this->ld2450_.zone_config_[i].y2, 4) << "zone " << i;
}
EXPECT_TRUE(this->uart_.written.empty());
}
} // namespace esphome::ld2450::testing
@@ -0,0 +1,12 @@
from esphome.core import CORE
from esphome.types import ConfigType
from tests.testing_helpers import ComponentManifestOverride
def override_manifest(manifest: ComponentManifestOverride) -> None:
# Turns on USE_NUMBER so the hub's number forwarding code is in the host test build
async def to_code_testing(config: ConfigType) -> None:
CORE.testing_ensure_platform_registered("number")
manifest.to_code = to_code_testing
manifest.dependencies = manifest.dependencies + ["number"]