mirror of
https://github.com/esphome/esphome.git
synced 2026-08-17 10:52:56 +08:00
[ld6002b] Add switch, number and text sensor platforms (3/5) (#17821)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
This commit is contained in:
co-authored by
Jonathan Swoboda
parent
1bbe8b415f
commit
b802740997
@@ -1,8 +1,18 @@
|
||||
CONF_AUTO_WAKE = "auto_wake"
|
||||
CONF_CLUSTER_ID = "cluster_id"
|
||||
CONF_DOPPLER_INDEX = "doppler_index"
|
||||
CONF_HOLD_DELAY = "hold_delay"
|
||||
CONF_LD6002B_ID = "ld6002b_id"
|
||||
CONF_LOW_POWER = "low_power"
|
||||
CONF_LOW_POWER_SLEEP_TIME = "low_power_sleep_time"
|
||||
CONF_OTA_VERSION = "ota_version"
|
||||
CONF_POINT_CLOUD = "point_cloud"
|
||||
CONF_POINT_COUNT = "point_count"
|
||||
CONF_TARGET_DISPLAY = "target_display"
|
||||
CONF_WAKEUP_PULSE = "wakeup_pulse"
|
||||
CONF_WORK_MODE = "work_mode"
|
||||
CONF_Z = "z"
|
||||
CONF_Z_MAX = "z_max"
|
||||
CONF_Z_MIN = "z_min"
|
||||
|
||||
MAX_TARGETS = 3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,16 +11,41 @@
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#endif
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#endif
|
||||
#ifdef USE_NUMBER
|
||||
#include "esphome/components/number/number.h"
|
||||
#endif
|
||||
#ifdef USE_SWITCH
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
namespace esphome::ld6002b {
|
||||
|
||||
static constexpr uint8_t MAX_TARGETS = 3;
|
||||
static constexpr size_t DEFAULT_MAX_DATA_LEN = 1024;
|
||||
static constexpr size_t DEFAULT_MAX_DATA_LEN_POINT_CLOUD = 4096;
|
||||
// Largest protocol payload is TYPE_SET_AREA: int32 area id + 6 floats = 28 bytes.
|
||||
static constexpr size_t CMD_MAX_DATA_LEN = 28;
|
||||
|
||||
enum class NumberType : uint8_t {
|
||||
HOLD_DELAY,
|
||||
Z_MIN,
|
||||
Z_MAX,
|
||||
LOW_POWER_SLEEP,
|
||||
};
|
||||
|
||||
enum class SwitchType : uint8_t {
|
||||
LOW_POWER,
|
||||
POINT_CLOUD,
|
||||
TARGET_DISPLAY,
|
||||
};
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
struct TargetSensors {
|
||||
sensor::Sensor *x{nullptr};
|
||||
@@ -32,6 +57,10 @@ struct TargetSensors {
|
||||
|
||||
#endif
|
||||
|
||||
struct VersionPref {
|
||||
char value[20];
|
||||
};
|
||||
|
||||
class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
@@ -45,6 +74,7 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
void set_target_count_sensor(sensor::Sensor *sensor) { this->target_count_sensor_ = sensor; }
|
||||
void set_point_count_sensor(sensor::Sensor *sensor) { this->point_count_sensor_ = sensor; }
|
||||
|
||||
void set_target_x_sensor(uint8_t target, sensor::Sensor *sensor) {
|
||||
if (target >= MAX_TARGETS)
|
||||
@@ -82,6 +112,27 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void set_work_mode_text_sensor(text_sensor::TextSensor *sensor) { this->work_mode_text_sensor_ = sensor; }
|
||||
void set_ota_version_text_sensor(text_sensor::TextSensor *sensor) { this->ota_version_text_sensor_ = sensor; }
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER
|
||||
void set_hold_delay_number(number::Number *number) { this->hold_delay_number_ = number; }
|
||||
void set_z_min_number(number::Number *number) { this->z_min_number_ = number; }
|
||||
void set_z_max_number(number::Number *number) { this->z_max_number_ = number; }
|
||||
void set_low_power_sleep_number(number::Number *number) { this->low_power_sleep_number_ = number; }
|
||||
#endif
|
||||
|
||||
#ifdef USE_SWITCH
|
||||
void set_low_power_switch(switch_::Switch *sw) { this->low_power_switch_ = sw; }
|
||||
void set_point_cloud_switch(switch_::Switch *sw) { this->point_cloud_switch_ = sw; }
|
||||
void set_target_display_switch(switch_::Switch *sw) { this->target_display_switch_ = sw; }
|
||||
#endif
|
||||
|
||||
void set_number_value(NumberType type, float value);
|
||||
void set_switch_state(SwitchType type, bool state);
|
||||
|
||||
protected:
|
||||
enum class ParseState : uint8_t { SOF, HEADER, HCK, DATA, DCK, DISCARD };
|
||||
|
||||
@@ -95,6 +146,25 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
void reset_parser_();
|
||||
void handle_frame_(uint16_t type, const uint8_t *data, uint16_t len);
|
||||
void handle_target_report_(const uint8_t *data, uint16_t len);
|
||||
void handle_point_cloud_(const uint8_t *data, uint16_t len);
|
||||
void handle_delay_report_(const uint8_t *data, uint16_t len);
|
||||
void handle_z_range_report_(const uint8_t *data, uint16_t len);
|
||||
void handle_low_power_report_(const uint8_t *data, uint16_t len);
|
||||
void handle_low_power_sleep_report_(const uint8_t *data, uint16_t len);
|
||||
void handle_work_mode_report_(const uint8_t *data, uint16_t len);
|
||||
void handle_version_report_(const uint8_t *data, uint16_t len);
|
||||
void update_work_mode_fallback_();
|
||||
void publish_work_mode_(bool low_power);
|
||||
// Drops every target-derived reading and the slot table they are indexed by.
|
||||
void clear_target_state_();
|
||||
#ifdef USE_SENSOR
|
||||
void clear_target_slot_(uint8_t index);
|
||||
#endif
|
||||
#ifdef USE_NUMBER
|
||||
void publish_number_clamped_(number::Number *number, float value);
|
||||
#endif
|
||||
void init_version_pref_();
|
||||
void save_version_pref_(const char *value);
|
||||
|
||||
void queue_command_(uint16_t type, const uint8_t *data, uint8_t len);
|
||||
void process_command_queue_();
|
||||
@@ -102,21 +172,41 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
void send_command_internal_(uint16_t type, const uint8_t *data, uint8_t len, bool track);
|
||||
void write_frame_(uint16_t type, const uint8_t *data, uint8_t len, bool track);
|
||||
void send_control_command_(uint32_t command);
|
||||
void send_z_range_();
|
||||
|
||||
static uint16_t read_u16_be(const uint8_t *data);
|
||||
static uint32_t read_u32_le(const uint8_t *data);
|
||||
static int32_t read_int32_le(const uint8_t *data);
|
||||
static float read_f32_le(const uint8_t *data);
|
||||
static void write_u32_le(uint8_t *data, uint32_t value);
|
||||
static void write_f32_le(uint8_t *data, float value);
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
std::array<TargetSensors, MAX_TARGETS> targets_{};
|
||||
sensor::Sensor *target_count_sensor_{nullptr};
|
||||
sensor::Sensor *point_count_sensor_{nullptr};
|
||||
#endif
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
binary_sensor::BinarySensor *presence_binary_sensor_{nullptr};
|
||||
std::array<binary_sensor::BinarySensor *, MAX_TARGETS> target_presence_{};
|
||||
#endif
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
text_sensor::TextSensor *work_mode_text_sensor_{nullptr};
|
||||
text_sensor::TextSensor *ota_version_text_sensor_{nullptr};
|
||||
ESPPreferenceObject version_pref_{};
|
||||
bool version_pref_initialized_{false};
|
||||
#endif
|
||||
#ifdef USE_NUMBER
|
||||
number::Number *hold_delay_number_{nullptr};
|
||||
number::Number *z_min_number_{nullptr};
|
||||
number::Number *z_max_number_{nullptr};
|
||||
number::Number *low_power_sleep_number_{nullptr};
|
||||
#endif
|
||||
#ifdef USE_SWITCH
|
||||
switch_::Switch *low_power_switch_{nullptr};
|
||||
switch_::Switch *point_cloud_switch_{nullptr};
|
||||
switch_::Switch *target_display_switch_{nullptr};
|
||||
#endif
|
||||
|
||||
GPIOPin *wakeup_pin_{nullptr};
|
||||
uint32_t wakeup_pulse_ms_{50};
|
||||
@@ -132,6 +222,7 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
uint8_t data_xor_{0};
|
||||
uint32_t discard_remaining_{0};
|
||||
bool frame_oversize_{false};
|
||||
size_t max_data_len_{0};
|
||||
uint8_t *data_buf_{nullptr};
|
||||
uint16_t next_frame_id_{0};
|
||||
|
||||
@@ -173,11 +264,24 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
// Bumped whenever the active command changes, so a deferred send can tell it was retired.
|
||||
uint8_t send_generation_{0};
|
||||
|
||||
float z_min_{NAN};
|
||||
float z_max_{NAN};
|
||||
|
||||
// Which person owns each target_N slot, so a slot survives the module re-sorting its array.
|
||||
std::array<int32_t, MAX_TARGETS> slot_cluster_{};
|
||||
std::array<bool, MAX_TARGETS> slot_occupied_{};
|
||||
|
||||
bool target_presence_any_{false};
|
||||
// What the switches and setup asked the module for, which is not the same as
|
||||
// what it is doing yet: a stream keeps sending until it acts on the command.
|
||||
// The report handlers read these and drop anything a stopped stream still emits.
|
||||
bool target_display_enabled_{false};
|
||||
bool point_cloud_enabled_{false};
|
||||
bool work_mode_reported_{false};
|
||||
bool low_power_enabled_{false};
|
||||
bool low_power_reported_{false};
|
||||
bool last_work_mode_valid_{false};
|
||||
bool last_work_mode_low_power_{false};
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
std::array<bool, MAX_TARGETS> last_target_presence_{}; // one-shot NAN clear for target sensors
|
||||
@@ -185,6 +289,7 @@ class LD6002BComponent : public Component, public uart::UARTDevice {
|
||||
std::array<int32_t, MAX_TARGETS> last_cluster_id_{};
|
||||
std::array<bool, MAX_TARGETS> last_cluster_id_valid_{};
|
||||
uint32_t last_target_count_{0xFFFFFFFF};
|
||||
uint32_t last_point_count_{0xFFFFFFFF};
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import number
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
DEVICE_CLASS_DISTANCE,
|
||||
DEVICE_CLASS_DURATION,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
UNIT_METER,
|
||||
UNIT_MILLISECOND,
|
||||
UNIT_SECOND,
|
||||
)
|
||||
|
||||
from .. import LD6002BComponent, ld6002b_ns
|
||||
from ..const import (
|
||||
CONF_HOLD_DELAY,
|
||||
CONF_LD6002B_ID,
|
||||
CONF_LOW_POWER_SLEEP_TIME,
|
||||
CONF_Z_MAX,
|
||||
CONF_Z_MIN,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["ld6002b"]
|
||||
|
||||
LD6002BNumber = ld6002b_ns.class_("LD6002BNumber", number.Number)
|
||||
NumberType = ld6002b_ns.enum("NumberType", is_class=True)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_LD6002B_ID): cv.use_id(LD6002BComponent),
|
||||
cv.Optional(CONF_HOLD_DELAY): number.number_schema(
|
||||
LD6002BNumber,
|
||||
unit_of_measurement=UNIT_SECOND,
|
||||
device_class=DEVICE_CLASS_DURATION,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_Z_MIN): number.number_schema(
|
||||
LD6002BNumber,
|
||||
unit_of_measurement=UNIT_METER,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_Z_MAX): number.number_schema(
|
||||
LD6002BNumber,
|
||||
unit_of_measurement=UNIT_METER,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_LOW_POWER_SLEEP_TIME): number.number_schema(
|
||||
LD6002BNumber,
|
||||
unit_of_measurement=UNIT_MILLISECOND,
|
||||
device_class=DEVICE_CLASS_DURATION,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
hub = await cg.get_variable(config[CONF_LD6002B_ID])
|
||||
|
||||
for key, number_type, setter, min_value, max_value, step in (
|
||||
(CONF_HOLD_DELAY, NumberType.HOLD_DELAY, "set_hold_delay_number", 0, 65535, 1),
|
||||
(CONF_Z_MIN, NumberType.Z_MIN, "set_z_min_number", -10, 10, 0.1),
|
||||
(CONF_Z_MAX, NumberType.Z_MAX, "set_z_max_number", -10, 10, 0.1),
|
||||
# 0x0205 carries a uint32 of milliseconds; the vendor documents 500 ms as
|
||||
# the default and no upper bound, so the range ends at a minute rather
|
||||
# than at a default the module is free to be sleeping past.
|
||||
(
|
||||
CONF_LOW_POWER_SLEEP_TIME,
|
||||
NumberType.LOW_POWER_SLEEP,
|
||||
"set_low_power_sleep_number",
|
||||
0,
|
||||
60000,
|
||||
100,
|
||||
),
|
||||
):
|
||||
if conf := config.get(key):
|
||||
n = await number.new_number(
|
||||
conf, number_type, min_value=min_value, max_value=max_value, step=step
|
||||
)
|
||||
await cg.register_parented(n, config[CONF_LD6002B_ID])
|
||||
cg.add(getattr(hub, setter)(n))
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "ld6002b_number.h"
|
||||
|
||||
namespace esphome::ld6002b {
|
||||
|
||||
void LD6002BNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_number_value(this->type_, value);
|
||||
}
|
||||
|
||||
} // namespace esphome::ld6002b
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../ld6002b.h"
|
||||
|
||||
namespace esphome::ld6002b {
|
||||
|
||||
class LD6002BNumber : public number::Number, public Parented<LD6002BComponent> {
|
||||
public:
|
||||
explicit LD6002BNumber(NumberType type) : type_(type) {}
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
|
||||
NumberType type_;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld6002b
|
||||
@@ -15,6 +15,7 @@ from .const import (
|
||||
CONF_CLUSTER_ID,
|
||||
CONF_DOPPLER_INDEX,
|
||||
CONF_LD6002B_ID,
|
||||
CONF_POINT_COUNT,
|
||||
CONF_Z,
|
||||
MAX_TARGETS,
|
||||
)
|
||||
@@ -75,6 +76,10 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
accuracy_decimals=0,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_POINT_COUNT): sensor.sensor_schema(
|
||||
accuracy_decimals=0,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
}
|
||||
).extend({cv.Optional(f"target_{i + 1}"): TARGET_SCHEMA for i in range(MAX_TARGETS)})
|
||||
|
||||
@@ -86,6 +91,10 @@ async def to_code(config):
|
||||
sens = await sensor.new_sensor(target_count_config)
|
||||
cg.add(hub.set_target_count_sensor(sens))
|
||||
|
||||
if point_count_config := config.get(CONF_POINT_COUNT):
|
||||
sens = await sensor.new_sensor(point_count_config)
|
||||
cg.add(hub.set_point_count_sensor(sens))
|
||||
|
||||
for i in range(MAX_TARGETS):
|
||||
if target_config := config.get(f"target_{i + 1}"):
|
||||
if x_config := target_config.get(CONF_X):
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import switch
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import DEVICE_CLASS_SWITCH, ENTITY_CATEGORY_CONFIG
|
||||
|
||||
from .. import LD6002BComponent, ld6002b_ns
|
||||
from ..const import (
|
||||
CONF_LD6002B_ID,
|
||||
CONF_LOW_POWER,
|
||||
CONF_POINT_CLOUD,
|
||||
CONF_TARGET_DISPLAY,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["ld6002b"]
|
||||
|
||||
LD6002BSwitch = ld6002b_ns.class_("LD6002BSwitch", switch.Switch)
|
||||
SwitchType = ld6002b_ns.enum("SwitchType", is_class=True)
|
||||
|
||||
# None of these three carry an inversion. They name what the module is doing, not
|
||||
# how something is wired to it, so an inverted one would only report the opposite
|
||||
# of the truth -- and the boot restore, which applies a state nothing reports back,
|
||||
# is where that would be hardest to spot.
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_LD6002B_ID): cv.use_id(LD6002BComponent),
|
||||
cv.Optional(CONF_LOW_POWER): switch.switch_schema(
|
||||
LD6002BSwitch,
|
||||
block_inverted=True,
|
||||
device_class=DEVICE_CLASS_SWITCH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_POINT_CLOUD): switch.switch_schema(
|
||||
LD6002BSwitch,
|
||||
block_inverted=True,
|
||||
device_class=DEVICE_CLASS_SWITCH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
cv.Optional(CONF_TARGET_DISPLAY): switch.switch_schema(
|
||||
LD6002BSwitch,
|
||||
block_inverted=True,
|
||||
device_class=DEVICE_CLASS_SWITCH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
default_restore_mode="RESTORE_DEFAULT_ON",
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
hub = await cg.get_variable(config[CONF_LD6002B_ID])
|
||||
|
||||
for key, switch_type, setter in (
|
||||
(CONF_LOW_POWER, SwitchType.LOW_POWER, "set_low_power_switch"),
|
||||
(CONF_POINT_CLOUD, SwitchType.POINT_CLOUD, "set_point_cloud_switch"),
|
||||
(CONF_TARGET_DISPLAY, SwitchType.TARGET_DISPLAY, "set_target_display_switch"),
|
||||
):
|
||||
if conf := config.get(key):
|
||||
s = await switch.new_switch(conf, switch_type)
|
||||
await cg.register_parented(s, config[CONF_LD6002B_ID])
|
||||
cg.add(getattr(hub, setter)(s))
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "ld6002b_switch.h"
|
||||
|
||||
namespace esphome::ld6002b {
|
||||
|
||||
void LD6002BSwitch::write_state(bool state) {
|
||||
this->parent_->set_switch_state(this->type_, state);
|
||||
this->publish_state(state);
|
||||
}
|
||||
|
||||
} // namespace esphome::ld6002b
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "../ld6002b.h"
|
||||
|
||||
namespace esphome::ld6002b {
|
||||
|
||||
class LD6002BSwitch : public switch_::Switch, public Parented<LD6002BComponent> {
|
||||
public:
|
||||
explicit LD6002BSwitch(SwitchType type) : type_(type) {}
|
||||
|
||||
protected:
|
||||
void write_state(bool state) override;
|
||||
|
||||
SwitchType type_;
|
||||
};
|
||||
|
||||
} // namespace esphome::ld6002b
|
||||
@@ -0,0 +1,31 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import text_sensor
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import ENTITY_CATEGORY_DIAGNOSTIC
|
||||
|
||||
from . import LD6002BComponent
|
||||
from .const import CONF_LD6002B_ID, CONF_OTA_VERSION, CONF_WORK_MODE
|
||||
|
||||
DEPENDENCIES = ["ld6002b"]
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_LD6002B_ID): cv.use_id(LD6002BComponent),
|
||||
cv.Optional(CONF_WORK_MODE): text_sensor.text_sensor_schema(
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC
|
||||
),
|
||||
cv.Optional(CONF_OTA_VERSION): text_sensor.text_sensor_schema(
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
hub = await cg.get_variable(config[CONF_LD6002B_ID])
|
||||
if work_mode_config := config.get(CONF_WORK_MODE):
|
||||
sens = await text_sensor.new_text_sensor(work_mode_config)
|
||||
cg.add(hub.set_work_mode_text_sensor(sens))
|
||||
if ota_config := config.get(CONF_OTA_VERSION):
|
||||
sens = await text_sensor.new_text_sensor(ota_config)
|
||||
cg.add(hub.set_ota_version_text_sensor(sens))
|
||||
@@ -7,6 +7,8 @@ sensor:
|
||||
ld6002b_id: ld6002b_radar
|
||||
target_count:
|
||||
name: Target Count
|
||||
point_count:
|
||||
name: Point Count
|
||||
target_1:
|
||||
x:
|
||||
name: Target-1 X
|
||||
@@ -48,3 +50,33 @@ binary_sensor:
|
||||
name: Presence
|
||||
target_1:
|
||||
name: Target-1 Presence
|
||||
|
||||
text_sensor:
|
||||
- platform: ld6002b
|
||||
ld6002b_id: ld6002b_radar
|
||||
work_mode:
|
||||
name: Work Mode
|
||||
ota_version:
|
||||
name: OTA Version
|
||||
|
||||
number:
|
||||
- platform: ld6002b
|
||||
ld6002b_id: ld6002b_radar
|
||||
hold_delay:
|
||||
name: Hold Delay
|
||||
z_min:
|
||||
name: Z Min
|
||||
z_max:
|
||||
name: Z Max
|
||||
low_power_sleep_time:
|
||||
name: Low Power Sleep
|
||||
|
||||
switch:
|
||||
- platform: ld6002b
|
||||
ld6002b_id: ld6002b_radar
|
||||
low_power:
|
||||
name: Low Power
|
||||
point_cloud:
|
||||
name: Point Cloud
|
||||
target_display:
|
||||
name: Target Display
|
||||
|
||||
Reference in New Issue
Block a user