mirror of
https://github.com/esphome/esphome.git
synced 2026-10-22 22:06:12 +00:00
Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e1542d197 | ||
|
|
3212a61a3c | ||
|
|
ce428e0c88 | ||
|
|
5ea7e5fd70 | ||
|
|
1d280bebac | ||
|
|
97c732319d | ||
|
|
d707402ef3 | ||
|
|
611e804e52 | ||
|
|
f308fd9655 | ||
|
|
754a960ed1 | ||
|
|
33e51b76dc | ||
|
|
f7a60f5859 | ||
|
|
aad0c59855 | ||
|
|
482a46489b | ||
|
|
116ae120dc | ||
|
|
d65620c4d1 | ||
|
|
b8a0de91db | ||
|
|
2937d81216 | ||
|
|
05a4b256db | ||
|
|
d0427c36eb | ||
|
|
a990231342 |
@@ -459,6 +459,15 @@ void DFRobotSEN0609Component::control_number(NumberSetting setting, float value)
|
||||
this->request_write_(static_cast<Param>(progmem_read_byte(&NUMBER_PARAMS[setting])));
|
||||
}
|
||||
|
||||
void DFRobotSEN0609Component::control_number(number::Number *number, float value) {
|
||||
for (uint8_t i = 0; i < NUMBER_COUNT; i++) {
|
||||
if (this->numbers_[i] == number) {
|
||||
this->control_number(static_cast<NumberSetting>(i), value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DFRobotSEN0609Component::forget_number_changes_(Param param, bool unknown) {
|
||||
for (uint8_t i = 0; i < NUMBER_COUNT; i++) {
|
||||
if (progmem_read_byte(&NUMBER_PARAMS[i]) != param)
|
||||
|
||||
@@ -130,6 +130,8 @@ class DFRobotSEN0609Component final : public Component, public uart::UARTDevice
|
||||
#ifdef USE_NUMBER
|
||||
void set_number(NumberSetting setting, number::Number *number) { this->numbers_[setting] = number; }
|
||||
void control_number(NumberSetting setting, float value);
|
||||
// Finds the setting by pointer so every number shares one Apply function
|
||||
void control_number(number::Number *number, float value);
|
||||
#endif
|
||||
#ifdef USE_SWITCH
|
||||
void set_switch(SwitchSetting setting, switch_::Switch *sw) { this->switches_[setting] = sw; }
|
||||
|
||||
@@ -31,7 +31,6 @@ from .. import (
|
||||
get_hub_config,
|
||||
)
|
||||
|
||||
DFRobotSEN0609Number = dfrobot_sen0609_ns.class_("DFRobotSEN0609Number", number.Number)
|
||||
NumberSetting = dfrobot_sen0609_ns.enum("NumberSetting")
|
||||
|
||||
CONF_HOLD_SENSITIVITY = "hold_sensitivity"
|
||||
@@ -55,7 +54,7 @@ class Setting(NamedTuple):
|
||||
|
||||
def _distance(icon: str = ICON_RULER) -> cv.Schema:
|
||||
return number.number_schema(
|
||||
DFRobotSEN0609Number,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=icon,
|
||||
@@ -65,7 +64,7 @@ def _distance(icon: str = ICON_RULER) -> cv.Schema:
|
||||
|
||||
def _duration() -> cv.Schema:
|
||||
return number.number_schema(
|
||||
DFRobotSEN0609Number,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_DURATION,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_TIMELAPSE,
|
||||
@@ -75,7 +74,7 @@ def _duration() -> cv.Schema:
|
||||
|
||||
def _plain() -> cv.Schema:
|
||||
return number.number_schema(
|
||||
DFRobotSEN0609Number,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
)
|
||||
@@ -187,8 +186,8 @@ async def to_code(config: ConfigType) -> None:
|
||||
await numbers(
|
||||
s.key,
|
||||
lambda n, setting=s.setting: hub.set_number(setting, n),
|
||||
s.setting,
|
||||
min_value=s.min_value,
|
||||
max_value=max_range if s.max_value is None else s.max_value,
|
||||
step=s.step,
|
||||
apply="control_number(entity, value)",
|
||||
)
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../dfrobot_sen0609.h"
|
||||
|
||||
namespace esphome::dfrobot_sen0609 {
|
||||
|
||||
class DFRobotSEN0609Number final : public number::Number, public Parented<DFRobotSEN0609Component> {
|
||||
public:
|
||||
explicit DFRobotSEN0609Number(NumberSetting setting) : setting_(setting) {}
|
||||
|
||||
protected:
|
||||
void control(float value) override { this->parent_->control_number(this->setting_, value); }
|
||||
|
||||
NumberSetting setting_;
|
||||
};
|
||||
|
||||
} // namespace esphome::dfrobot_sen0609
|
||||
@@ -725,7 +725,16 @@ void LD2410Component::set_max_distances_timeout() {
|
||||
this->set_config_mode_(false);
|
||||
}
|
||||
|
||||
void LD2410Component::set_gate_threshold(uint8_t gate) {
|
||||
void LD2410Component::set_gate_threshold(number::Number *n) {
|
||||
// Found by pointer: up to 18 compares per write beat storing the gate in each number
|
||||
uint8_t gate = 0;
|
||||
while (gate < TOTAL_GATES && this->gate_move_threshold_numbers_[gate] != n &&
|
||||
this->gate_still_threshold_numbers_[gate] != n)
|
||||
gate++;
|
||||
if (gate == TOTAL_GATES) {
|
||||
ESP_LOGW(TAG, "Threshold number is not a known gate");
|
||||
return;
|
||||
}
|
||||
number::Number *motionsens = this->gate_move_threshold_numbers_[gate];
|
||||
number::Number *stillsens = this->gate_still_threshold_numbers_[gate];
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class LD2410Component final : public Component, public uart::UARTDevice {
|
||||
void set_gate_still_threshold_number(uint8_t gate, number::Number *n);
|
||||
void set_gate_move_threshold_number(uint8_t gate, number::Number *n);
|
||||
void set_max_distances_timeout();
|
||||
void set_gate_threshold(uint8_t gate);
|
||||
void set_gate_threshold(number::Number *n);
|
||||
#endif
|
||||
#ifdef USE_SENSOR
|
||||
void set_gate_move_sensor(uint8_t gate, sensor::Sensor *s);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from functools import partial
|
||||
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import number
|
||||
import esphome.config_validation as cv
|
||||
@@ -18,11 +20,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2410_ID, LD2410Component, ld2410_ns
|
||||
|
||||
GateThresholdNumber = ld2410_ns.class_("GateThresholdNumber", number.Number)
|
||||
LightThresholdNumber = ld2410_ns.class_("LightThresholdNumber", number.Number)
|
||||
MaxDistanceTimeoutNumber = ld2410_ns.class_("MaxDistanceTimeoutNumber", number.Number)
|
||||
from .. import CONF_LD2410_ID, LD2410Component
|
||||
|
||||
CONF_MAX_MOVE_DISTANCE_GATE = "max_move_distance_gate"
|
||||
CONF_MAX_STILL_DISTANCE_GATE = "max_still_distance_gate"
|
||||
@@ -35,25 +33,25 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(cg.EntityBase),
|
||||
cv.GenerateID(CONF_LD2410_ID): cv.use_id(LD2410Component),
|
||||
cv.Inclusive(CONF_TIMEOUT, TIMEOUT_GROUP): number.number_schema(
|
||||
MaxDistanceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
unit_of_measurement=UNIT_SECOND,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_TIMELAPSE,
|
||||
),
|
||||
cv.Inclusive(CONF_MAX_MOVE_DISTANCE_GATE, TIMEOUT_GROUP): number.number_schema(
|
||||
MaxDistanceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
),
|
||||
cv.Inclusive(CONF_MAX_STILL_DISTANCE_GATE, TIMEOUT_GROUP): number.number_schema(
|
||||
MaxDistanceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
),
|
||||
cv.Optional(CONF_LIGHT_THRESHOLD): number.number_schema(
|
||||
LightThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_ILLUMINANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_LIGHTBULB,
|
||||
@@ -66,14 +64,14 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend(
|
||||
cv.Optional(f"g{x}"): cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MOVE_THRESHOLD): number.number_schema(
|
||||
GateThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
),
|
||||
cv.Required(CONF_STILL_THRESHOLD): number.number_schema(
|
||||
GateThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
@@ -89,8 +87,14 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend(
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
hub = await cg.get_variable(config[CONF_LD2410_ID])
|
||||
numbers = number.sub_numbers(config, parent=hub)
|
||||
timeouts = {"apply": "set_max_distances_timeout()", "publish": "before"}
|
||||
await numbers(
|
||||
CONF_TIMEOUT, hub.set_timeout_number, min_value=0, max_value=65535, step=1
|
||||
CONF_TIMEOUT,
|
||||
hub.set_timeout_number,
|
||||
min_value=0,
|
||||
max_value=65535,
|
||||
step=1,
|
||||
**timeouts,
|
||||
)
|
||||
await numbers(
|
||||
CONF_MAX_MOVE_DISTANCE_GATE,
|
||||
@@ -98,6 +102,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=2,
|
||||
max_value=8,
|
||||
step=1,
|
||||
**timeouts,
|
||||
)
|
||||
await numbers(
|
||||
CONF_MAX_STILL_DISTANCE_GATE,
|
||||
@@ -105,6 +110,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=2,
|
||||
max_value=8,
|
||||
step=1,
|
||||
**timeouts,
|
||||
)
|
||||
await numbers(
|
||||
CONF_LIGHT_THRESHOLD,
|
||||
@@ -112,21 +118,25 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=255,
|
||||
step=1,
|
||||
apply="set_light_out_control()",
|
||||
publish="before",
|
||||
)
|
||||
threshold = {
|
||||
"min_value": 0,
|
||||
"max_value": 100,
|
||||
"step": 1,
|
||||
"apply": "set_gate_threshold(entity)",
|
||||
"publish": "before",
|
||||
}
|
||||
for x in range(9):
|
||||
if gate_conf := config.get(f"g{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=100, step=1
|
||||
await numbers.create(
|
||||
gate_conf[CONF_MOVE_THRESHOLD],
|
||||
partial(hub.set_gate_move_threshold_number, x),
|
||||
**threshold,
|
||||
)
|
||||
await cg.register_parented(n, hub)
|
||||
cg.add(hub.set_gate_move_threshold_number(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=100, step=1
|
||||
await numbers.create(
|
||||
gate_conf[CONF_STILL_THRESHOLD],
|
||||
partial(hub.set_gate_still_threshold_number, x),
|
||||
**threshold,
|
||||
)
|
||||
await cg.register_parented(n, hub)
|
||||
cg.add(hub.set_gate_still_threshold_number(x, n))
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#include "gate_threshold_number.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
GateThresholdNumber::GateThresholdNumber(uint8_t gate) : gate_(gate) {}
|
||||
|
||||
void GateThresholdNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_gate_threshold(this->gate_);
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2410.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
class GateThresholdNumber final : public number::Number, public Parented<LD2410Component> {
|
||||
public:
|
||||
GateThresholdNumber(uint8_t gate);
|
||||
|
||||
protected:
|
||||
uint8_t gate_;
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "light_threshold_number.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
void LightThresholdNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_light_out_control();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2410.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
class LightThresholdNumber final : public number::Number, public Parented<LD2410Component> {
|
||||
public:
|
||||
LightThresholdNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "max_distance_timeout_number.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
void MaxDistanceTimeoutNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_max_distances_timeout();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2410.h"
|
||||
|
||||
namespace esphome::ld2410 {
|
||||
|
||||
class MaxDistanceTimeoutNumber final : public number::Number, public Parented<LD2410Component> {
|
||||
public:
|
||||
MaxDistanceTimeoutNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2410
|
||||
@@ -1,3 +1,5 @@
|
||||
from functools import partial
|
||||
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import number
|
||||
import esphome.config_validation as cv
|
||||
@@ -18,11 +20,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2412_ID, LD2412_ns, LD2412Component
|
||||
|
||||
GateThresholdNumber = LD2412_ns.class_("GateThresholdNumber", number.Number)
|
||||
LightThresholdNumber = LD2412_ns.class_("LightThresholdNumber", number.Number)
|
||||
MaxDistanceTimeoutNumber = LD2412_ns.class_("MaxDistanceTimeoutNumber", number.Number)
|
||||
from .. import CONF_LD2412_ID, LD2412Component
|
||||
|
||||
CONF_LIGHT_THRESHOLD = "light_threshold"
|
||||
CONF_MAX_DISTANCE_GATE = "max_distance_gate"
|
||||
@@ -35,25 +33,25 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(cg.EntityBase),
|
||||
cv.GenerateID(CONF_LD2412_ID): cv.use_id(LD2412Component),
|
||||
cv.Optional(CONF_LIGHT_THRESHOLD): number.number_schema(
|
||||
LightThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_ILLUMINANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_LIGHTBULB,
|
||||
),
|
||||
cv.Optional(CONF_MAX_DISTANCE_GATE): number.number_schema(
|
||||
MaxDistanceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
),
|
||||
cv.Optional(CONF_MIN_DISTANCE_GATE): number.number_schema(
|
||||
MaxDistanceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
),
|
||||
cv.Optional(CONF_TIMEOUT): number.number_schema(
|
||||
MaxDistanceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_TIMELAPSE,
|
||||
unit_of_measurement=UNIT_SECOND,
|
||||
@@ -66,14 +64,14 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend(
|
||||
cv.Optional(f"gate_{x}"): (
|
||||
{
|
||||
cv.Required(CONF_MOVE_THRESHOLD): number.number_schema(
|
||||
GateThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
),
|
||||
cv.Required(CONF_STILL_THRESHOLD): number.number_schema(
|
||||
GateThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_MOTION_SENSOR,
|
||||
@@ -95,13 +93,17 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=255,
|
||||
step=1,
|
||||
apply="set_light_out_control()",
|
||||
publish="before",
|
||||
)
|
||||
basic = {"apply": "set_basic_config()", "publish": "before"}
|
||||
await numbers(
|
||||
CONF_MAX_DISTANCE_GATE,
|
||||
hub.set_max_distance_gate_number,
|
||||
min_value=2,
|
||||
max_value=13,
|
||||
step=1,
|
||||
**basic,
|
||||
)
|
||||
await numbers(
|
||||
CONF_MIN_DISTANCE_GATE,
|
||||
@@ -109,23 +111,32 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=1,
|
||||
max_value=12,
|
||||
step=1,
|
||||
**basic,
|
||||
)
|
||||
threshold = {
|
||||
"min_value": 0,
|
||||
"max_value": 100,
|
||||
"step": 1,
|
||||
"apply": "set_gate_threshold(entity)",
|
||||
"publish": "before",
|
||||
}
|
||||
for x in range(14):
|
||||
if gate_conf := config.get(f"gate_{x}"):
|
||||
move_config = gate_conf[CONF_MOVE_THRESHOLD]
|
||||
n = await number.new_number(move_config, min_value=0, max_value=100, step=1)
|
||||
await cg.register_parented(n, hub)
|
||||
cg.add(hub.set_gate_move_threshold_number(x, n))
|
||||
still_config = gate_conf[CONF_STILL_THRESHOLD]
|
||||
n = await number.new_number(
|
||||
still_config, min_value=0, max_value=100, step=1
|
||||
await numbers.create(
|
||||
gate_conf[CONF_MOVE_THRESHOLD],
|
||||
partial(hub.set_gate_move_threshold_number, x),
|
||||
**threshold,
|
||||
)
|
||||
await numbers.create(
|
||||
gate_conf[CONF_STILL_THRESHOLD],
|
||||
partial(hub.set_gate_still_threshold_number, x),
|
||||
**threshold,
|
||||
)
|
||||
await cg.register_parented(n, hub)
|
||||
cg.add(hub.set_gate_still_threshold_number(x, n))
|
||||
await numbers(
|
||||
CONF_TIMEOUT,
|
||||
hub.set_timeout_number,
|
||||
min_value=0,
|
||||
max_value=900,
|
||||
step=1,
|
||||
**basic,
|
||||
)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "gate_threshold_number.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
void GateThresholdNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_gate_threshold(this);
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2412.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
class GateThresholdNumber final : public number::Number, public Parented<LD2412Component> {
|
||||
public:
|
||||
// Not "= default": that makes new(p) T() zero-fill the object at every codegen site before the ctor runs.
|
||||
GateThresholdNumber() {}
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "light_threshold_number.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
void LightThresholdNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_light_out_control();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2412.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
class LightThresholdNumber final : public number::Number, public Parented<LD2412Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) LightThresholdNumber()` would zero-fill .bss that is already zero.
|
||||
LightThresholdNumber() {}
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "max_distance_timeout_number.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
void MaxDistanceTimeoutNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_basic_config();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2412.h"
|
||||
|
||||
namespace esphome::ld2412 {
|
||||
|
||||
class MaxDistanceTimeoutNumber final : public number::Number, public Parented<LD2412Component> {
|
||||
public:
|
||||
MaxDistanceTimeoutNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2412
|
||||
@@ -11,7 +11,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_LD2450_ID, LD2450Component, ld2450_ns
|
||||
from .. import CONF_LD2450_ID, LD2450Component
|
||||
|
||||
CONF_PRESENCE_TIMEOUT = "presence_timeout"
|
||||
CONF_X1 = "x1"
|
||||
@@ -24,14 +24,13 @@ ICON_ARROW_TOP_LEFT = "mdi:arrow-top-left"
|
||||
ICON_ARROW_TOP_LEFT_BOLD_BOX_OUTLINE = "mdi:arrow-top-left-bold-box-outline"
|
||||
MAX_ZONES = 3
|
||||
|
||||
PresenceTimeoutNumber = ld2450_ns.class_("PresenceTimeoutNumber", number.Number)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_ID): cv.declare_id(cg.EntityBase),
|
||||
cv.GenerateID(CONF_LD2450_ID): cv.use_id(LD2450Component),
|
||||
cv.Required(CONF_PRESENCE_TIMEOUT): number.number_schema(
|
||||
PresenceTimeoutNumber,
|
||||
number.ApplyNumber,
|
||||
unit_of_measurement=UNIT_SECOND,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_TIMELAPSE,
|
||||
@@ -87,6 +86,8 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=3600,
|
||||
step=1,
|
||||
apply="set_presence_timeout()",
|
||||
publish="before",
|
||||
)
|
||||
for zone_num in range(MAX_ZONES):
|
||||
if zone_conf := config.get(f"zone_{zone_num + 1}"):
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "presence_timeout_number.h"
|
||||
|
||||
namespace esphome::ld2450 {
|
||||
|
||||
void PresenceTimeoutNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_presence_timeout();
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2450
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld2450.h"
|
||||
|
||||
namespace esphome::ld2450 {
|
||||
|
||||
class PresenceTimeoutNumber : public number::Number, public Parented<LD2450Component> {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) PresenceTimeoutNumber()` would zero-fill .bss that is already zero.
|
||||
PresenceTimeoutNumber() {}
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld2450
|
||||
@@ -4,15 +4,7 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_SENSITIVITY, ENTITY_CATEGORY_CONFIG
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_MR24HPC1_ID, MR24HPC1Component, mr24hpc1_ns
|
||||
|
||||
SensitivityNumber = mr24hpc1_ns.class_("SensitivityNumber", number.Number)
|
||||
CustomModeNumber = mr24hpc1_ns.class_("CustomModeNumber", number.Number)
|
||||
ExistenceThresholdNumber = mr24hpc1_ns.class_("ExistenceThresholdNumber", number.Number)
|
||||
MotionThresholdNumber = mr24hpc1_ns.class_("MotionThresholdNumber", number.Number)
|
||||
MotionTriggerTimeNumber = mr24hpc1_ns.class_("MotionTriggerTimeNumber", number.Number)
|
||||
MotionToRestTimeNumber = mr24hpc1_ns.class_("MotionToRestTimeNumber", number.Number)
|
||||
CustomUnmanTimeNumber = mr24hpc1_ns.class_("CustomUnmanTimeNumber", number.Number)
|
||||
from .. import CONF_MR24HPC1_ID, MR24HPC1Component
|
||||
|
||||
CONF_CUSTOM_MODE = "custom_mode"
|
||||
CONF_EXISTENCE_THRESHOLD = "existence_threshold"
|
||||
@@ -25,37 +17,37 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component),
|
||||
cv.Optional(CONF_SENSITIVITY): number.number_schema(
|
||||
SensitivityNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:archive-check-outline",
|
||||
),
|
||||
cv.Optional(CONF_CUSTOM_MODE): number.number_schema(
|
||||
CustomModeNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:cog",
|
||||
),
|
||||
cv.Optional(CONF_EXISTENCE_THRESHOLD): number.number_schema(
|
||||
ExistenceThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_MOTION_THRESHOLD): number.number_schema(
|
||||
MotionThresholdNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_MOTION_TRIGGER): number.number_schema(
|
||||
MotionTriggerTimeNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:camera-timer",
|
||||
unit_of_measurement="ms",
|
||||
),
|
||||
cv.Optional(CONF_MOTION_TO_REST): number.number_schema(
|
||||
MotionToRestTimeNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:camera-timer",
|
||||
unit_of_measurement="ms",
|
||||
),
|
||||
cv.Optional(CONF_CUSTOM_UNMAN_TIME): number.number_schema(
|
||||
CustomUnmanTimeNumber,
|
||||
number.ApplyNumber,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon="mdi:camera-timer",
|
||||
unit_of_measurement="s",
|
||||
@@ -68,10 +60,21 @@ async def to_code(config: ConfigType) -> None:
|
||||
hub = await cg.get_variable(config[CONF_MR24HPC1_ID])
|
||||
numbers = number.sub_numbers(config, parent=hub)
|
||||
await numbers(
|
||||
CONF_SENSITIVITY, hub.set_sensitivity_number, min_value=0, max_value=3, step=1
|
||||
CONF_SENSITIVITY,
|
||||
hub.set_sensitivity_number,
|
||||
min_value=0,
|
||||
max_value=3,
|
||||
step=1,
|
||||
apply="set_sensitivity(value)",
|
||||
)
|
||||
await numbers(
|
||||
CONF_CUSTOM_MODE, hub.set_custom_mode_number, min_value=0, max_value=4, step=1
|
||||
CONF_CUSTOM_MODE,
|
||||
hub.set_custom_mode_number,
|
||||
min_value=0,
|
||||
max_value=4,
|
||||
step=1,
|
||||
apply="set_custom_mode(value)",
|
||||
publish="before",
|
||||
)
|
||||
await numbers(
|
||||
CONF_EXISTENCE_THRESHOLD,
|
||||
@@ -79,6 +82,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=250,
|
||||
step=1,
|
||||
apply="set_existence_threshold(value)",
|
||||
)
|
||||
await numbers(
|
||||
CONF_MOTION_THRESHOLD,
|
||||
@@ -86,6 +90,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=250,
|
||||
step=1,
|
||||
apply="set_motion_threshold(value)",
|
||||
)
|
||||
await numbers(
|
||||
CONF_MOTION_TRIGGER,
|
||||
@@ -93,6 +98,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=150,
|
||||
step=1,
|
||||
apply="set_motion_trigger_time(value)",
|
||||
)
|
||||
await numbers(
|
||||
CONF_MOTION_TO_REST,
|
||||
@@ -100,6 +106,7 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=3000,
|
||||
step=1,
|
||||
apply="set_motion_to_rest_time(value)",
|
||||
)
|
||||
await numbers(
|
||||
CONF_CUSTOM_UNMAN_TIME,
|
||||
@@ -107,4 +114,5 @@ async def to_code(config: ConfigType) -> None:
|
||||
min_value=0,
|
||||
max_value=3600,
|
||||
step=1,
|
||||
apply="set_custom_unman_time(value)",
|
||||
)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "custom_mode_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void CustomModeNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_custom_mode(value);
|
||||
}
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class CustomModeNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
CustomModeNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "custom_unman_time_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void CustomUnmanTimeNumber::control(float value) { this->parent_->set_custom_unman_time(value); }
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class CustomUnmanTimeNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
CustomUnmanTimeNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "existence_threshold_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void ExistenceThresholdNumber::control(float value) { this->parent_->set_existence_threshold(value); }
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class ExistenceThresholdNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
ExistenceThresholdNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "motion_threshold_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void MotionThresholdNumber::control(float value) { this->parent_->set_motion_threshold(value); }
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class MotionThresholdNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
MotionThresholdNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "motion_trigger_time_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void MotionTriggerTimeNumber::control(float value) { this->parent_->set_motion_trigger_time(value); }
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class MotionTriggerTimeNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
MotionTriggerTimeNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "motiontorest_time_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void MotionToRestTimeNumber::control(float value) { this->parent_->set_motion_to_rest_time(value); }
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class MotionToRestTimeNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
MotionToRestTimeNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "sensitivity_number.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
void SensitivityNumber::control(float value) { this->parent_->set_sensitivity(value); }
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../seeed_mr24hpc1.h"
|
||||
|
||||
namespace esphome::seeed_mr24hpc1 {
|
||||
|
||||
class SensitivityNumber final : public number::Number, public Parented<MR24HPC1Component> {
|
||||
public:
|
||||
SensitivityNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace esphome::seeed_mr24hpc1
|
||||
@@ -54,6 +54,35 @@ TEST_F(SEN0609SequencerTest, ChangesMadeTogetherShareOneSave) {
|
||||
EXPECT_EQ(this->next_command_(), "");
|
||||
}
|
||||
|
||||
// The Apply numbers pass themselves; the hub finds the setting by pointer
|
||||
TEST_F(SEN0609SequencerTest, NumberPointerFindsLaterSetting) {
|
||||
this->boot_();
|
||||
// Hold sensitivity sits after unregistered slots in the number array
|
||||
this->hub_.control_number(&this->hold_sensitivity_, 3.0f);
|
||||
EXPECT_FLOAT_EQ(this->hold_sensitivity_.state, 3.0f);
|
||||
this->expect_and_answer_("sensorStop");
|
||||
this->expect_and_answer_("setSensitivity 3 5");
|
||||
this->expect_and_answer_("saveConfig");
|
||||
this->expect_and_answer_("sensorStart");
|
||||
EXPECT_EQ(this->next_command_(), "");
|
||||
}
|
||||
|
||||
TEST_F(SEN0609SequencerTest, NumberPointerInvalidRangeKeepsState) {
|
||||
this->boot_();
|
||||
this->hub_.control_number(&this->min_range_, 20.0f);
|
||||
EXPECT_FLOAT_EQ(this->min_range_.state, 0.6f);
|
||||
EXPECT_EQ(this->next_command_(), "");
|
||||
}
|
||||
|
||||
TEST_F(SEN0609SequencerTest, UnregisteredNumberPointerWritesNothing) {
|
||||
this->boot_();
|
||||
TestNumber other;
|
||||
this->hub_.control_number(&other, 5.0f);
|
||||
EXPECT_FLOAT_EQ(this->min_range_.state, 0.6f);
|
||||
EXPECT_FLOAT_EQ(this->hold_sensitivity_.state, 7.0f);
|
||||
EXPECT_EQ(this->next_command_(), "");
|
||||
}
|
||||
|
||||
TEST_F(SEN0609SequencerTest, WriteWaitsBeforeStarting) {
|
||||
this->boot_();
|
||||
this->hub_.control_number(NUMBER_MIN_RANGE, 1.0f);
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "esphome/components/ld2410/ld2410.h"
|
||||
#include "esphome/components/uart/uart_component.h"
|
||||
|
||||
namespace esphome::ld2410::testing {
|
||||
|
||||
namespace {
|
||||
class CapturingUARTComponent : public uart::UARTComponent {
|
||||
public:
|
||||
void write_array(const uint8_t *data, size_t len) override {
|
||||
this->written.insert(this->written.end(), data, data + len);
|
||||
}
|
||||
MOCK_METHOD(bool, read_array, (uint8_t * data, size_t len), (override));
|
||||
MOCK_METHOD(bool, peek_byte, (uint8_t * data), (override));
|
||||
MOCK_METHOD(size_t, available, (), (override));
|
||||
MOCK_METHOD(uart::UARTFlushResult, flush, (), (override));
|
||||
MOCK_METHOD(void, check_logger_conflict, (), (override));
|
||||
#if defined(USE_ESP8266) || defined(USE_ESP32)
|
||||
void load_settings(bool dump_config) override {}
|
||||
#endif // USE_ESP8266 || USE_ESP32
|
||||
std::vector<uint8_t> written;
|
||||
};
|
||||
|
||||
LD2410Component *hub = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
// Same body codegen emits for publish="before": publish the new value, then hand the number to the hub.
|
||||
void apply_threshold(number::Number *entity, float value) {
|
||||
entity->publish_state(value);
|
||||
hub->set_gate_threshold(entity);
|
||||
}
|
||||
using ThresholdNumber = number::ApplyNumber<apply_threshold>;
|
||||
|
||||
// Only these gates get numbers; gate 8 is the last one.
|
||||
constexpr uint8_t GATES[] = {4, 8};
|
||||
|
||||
// Header, length 20, command 0x64 (set gate sensitivity): the 18 byte payload follows.
|
||||
constexpr uint8_t GATE_SENS_PREFIX[] = {0xFD, 0xFC, 0xFB, 0xFA, 0x14, 0x00, 0x64, 0x00};
|
||||
|
||||
std::vector<uint8_t> gate_sens_payload(uint8_t gate, uint8_t move, uint8_t still) {
|
||||
return {0x00, 0x00, gate, 0x00, 0x00, 0x00, 0x01, 0x00, move, 0x00, 0x00, 0x00, 0x02, 0x00, still, 0x00, 0x00, 0x00};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class LD2410GateThresholdTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
hub = &this->ld2410_;
|
||||
this->ld2410_.set_uart_parent(&this->uart_);
|
||||
// Gates 0 to 3 and 5 to 7 have no numbers, so the lookup must walk past the empty slots.
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
const uint8_t gate = GATES[i];
|
||||
this->ld2410_.set_gate_move_threshold_number(gate, &this->move_[i]);
|
||||
this->ld2410_.set_gate_still_threshold_number(gate, &this->still_[i]);
|
||||
for (ThresholdNumber *n : {&this->move_[i], &this->still_[i]}) {
|
||||
n->traits.set_min_value(0);
|
||||
n->traits.set_max_value(100);
|
||||
n->traits.set_step(1);
|
||||
}
|
||||
this->move_[i].publish_state(10 + gate);
|
||||
this->still_[i].publish_state(20 + gate);
|
||||
}
|
||||
}
|
||||
void TearDown() override { hub = nullptr; }
|
||||
|
||||
// Every gate sensitivity command written since the last clear, as its payload.
|
||||
std::vector<std::vector<uint8_t>> sent_gate_commands_() const {
|
||||
std::vector<std::vector<uint8_t>> out;
|
||||
const auto &w = this->uart_.written;
|
||||
auto it = w.begin();
|
||||
while ((it = std::search(it, w.end(), std::begin(GATE_SENS_PREFIX), std::end(GATE_SENS_PREFIX))) != w.end()) {
|
||||
it += sizeof(GATE_SENS_PREFIX);
|
||||
if (static_cast<size_t>(w.end() - it) < 18)
|
||||
break;
|
||||
out.emplace_back(it, it + 18);
|
||||
it += 18;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
CapturingUARTComponent uart_;
|
||||
LD2410Component ld2410_;
|
||||
ThresholdNumber move_[2];
|
||||
ThresholdNumber still_[2];
|
||||
};
|
||||
|
||||
TEST_F(LD2410GateThresholdTest, DirectCallSendsTheNumbersGateWithBothValues) {
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
for (ThresholdNumber *n : {&this->move_[i], &this->still_[i]}) {
|
||||
this->uart_.written.clear();
|
||||
this->ld2410_.set_gate_threshold(n);
|
||||
auto sent = this->sent_gate_commands_();
|
||||
ASSERT_EQ(sent.size(), 1u) << "gate " << +GATES[i];
|
||||
EXPECT_EQ(sent[0], gate_sens_payload(GATES[i], 10 + GATES[i], 20 + GATES[i])) << "gate " << +GATES[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LD2410GateThresholdTest, PublishBeforeApplySendsTheNewValue) {
|
||||
this->move_[1].make_call().set_value(55).perform();
|
||||
auto sent = this->sent_gate_commands_();
|
||||
ASSERT_EQ(sent.size(), 1u);
|
||||
EXPECT_EQ(sent[0], gate_sens_payload(8, 55, 28));
|
||||
|
||||
this->uart_.written.clear();
|
||||
this->still_[0].make_call().set_value(66).perform();
|
||||
sent = this->sent_gate_commands_();
|
||||
ASSERT_EQ(sent.size(), 1u);
|
||||
EXPECT_EQ(sent[0], gate_sens_payload(4, 14, 66));
|
||||
}
|
||||
|
||||
TEST_F(LD2410GateThresholdTest, UnregisteredNumberSendsNothing) {
|
||||
ThresholdNumber other;
|
||||
other.publish_state(42);
|
||||
this->ld2410_.set_gate_threshold(&other);
|
||||
EXPECT_TRUE(this->uart_.written.empty());
|
||||
}
|
||||
|
||||
} // namespace esphome::ld2410::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"]
|
||||
Reference in New Issue
Block a user