Upload files to "/"
This commit is contained in:
parent
bcbc379ece
commit
913a12c271
100
binary_sensors.yaml
Normal file
100
binary_sensors.yaml
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# =======================
|
||||
# BINARY SENSORS
|
||||
# =======================
|
||||
binary_sensor:
|
||||
|
||||
- platform: status
|
||||
name: Online
|
||||
id: ink_ha_connected
|
||||
|
||||
- platform: ld2410
|
||||
has_target:
|
||||
name: Presence
|
||||
id: ld2410_has_target
|
||||
has_moving_target:
|
||||
name: Moving Target
|
||||
id: has_moving_target
|
||||
has_still_target:
|
||||
name: Still Target
|
||||
id: has_still_target
|
||||
|
||||
- platform: gpio
|
||||
name: "OUT Pin"
|
||||
id: ld2410_out_pin
|
||||
pin:
|
||||
number: GPIO16
|
||||
mode:
|
||||
input: true
|
||||
inverted: false
|
||||
device_class: motion
|
||||
|
||||
# ===== STREFA 1 (GŁÓWNA – WC / ŁAZIENKA) =====
|
||||
- platform: template
|
||||
id: presence_zone_1
|
||||
name: "Presence Zone 1"
|
||||
device_class: occupancy
|
||||
filters:
|
||||
- delayed_off: 1s # BYŁO: 5s → TERAZ SZYBKO
|
||||
lambda: |-
|
||||
// brak targetu = brak obecności
|
||||
if (!id(ld2410_has_target).state) return false;
|
||||
|
||||
// ======================
|
||||
// FAST PATH – RUCH
|
||||
// ======================
|
||||
if (id(has_moving_target).state &&
|
||||
id(moving_distance).has_state() &&
|
||||
id(moving_distance).state > 0) {
|
||||
|
||||
float dm = id(moving_distance).state;
|
||||
|
||||
if (dm >= id(zone1_min_distance).state &&
|
||||
dm <= id(zone1_max_distance).state) {
|
||||
return true; // NATYCHMIASTOWA REAKCJA
|
||||
}
|
||||
}
|
||||
|
||||
// ======================
|
||||
// STABLE PATH – STILL
|
||||
// ======================
|
||||
if (id(has_still_target).state &&
|
||||
id(still_distance).has_state() &&
|
||||
id(still_distance).state > 0) {
|
||||
|
||||
float ds = id(still_distance).state;
|
||||
|
||||
// ignorowanie odbić (lustra / drzwi / kot)
|
||||
if (id(ignore_static_reflections).state &&
|
||||
id(still_energy).has_state() &&
|
||||
id(still_energy).state < 30) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ds >= id(zone1_min_distance).state &&
|
||||
ds <= id(zone1_max_distance).state;
|
||||
}
|
||||
|
||||
// fallback: target jest → obecność
|
||||
return true;
|
||||
|
||||
# ===== STREFA 2 (DALEJ / ZA DRZWIAMI) =====
|
||||
- platform: template
|
||||
id: presence_zone_2
|
||||
name: "Presence Zone 2"
|
||||
device_class: occupancy
|
||||
filters:
|
||||
- delayed_off: 1s # BYŁO: 5s → TERAZ SZYBKO
|
||||
lambda: |-
|
||||
if (!id(ld2410_has_target).state) return false;
|
||||
|
||||
if (id(has_moving_target).state &&
|
||||
id(moving_distance).has_state() &&
|
||||
id(moving_distance).state > 0) {
|
||||
|
||||
float dm = id(moving_distance).state;
|
||||
|
||||
return dm >= id(zone2_min_distance).state &&
|
||||
dm <= id(zone2_max_distance).state;
|
||||
}
|
||||
|
||||
return false;
|
||||
36
buttons.yaml
Normal file
36
buttons.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# =======================
|
||||
# BUTTONS
|
||||
# =======================
|
||||
button:
|
||||
- platform: template
|
||||
name: "Enable LD2410 BLE"
|
||||
icon: mdi:bluetooth
|
||||
entity_category: config
|
||||
on_press:
|
||||
lambda: |-
|
||||
id(ld2410_radar)->ble_control(true);
|
||||
|
||||
- platform: template
|
||||
name: "Disable LD2410 BLE"
|
||||
icon: mdi:bluetooth-off
|
||||
entity_category: config
|
||||
on_press:
|
||||
lambda: |-
|
||||
id(ld2410_radar)->ble_control(false);
|
||||
|
||||
- platform: template
|
||||
name: "LD2410 Reboot"
|
||||
icon: mdi:radar
|
||||
entity_category: config
|
||||
on_press:
|
||||
lambda: |-
|
||||
id(ld2410_radar)->reboot();
|
||||
|
||||
- platform: restart
|
||||
name: "ESP Reboot"
|
||||
icon: mdi:power-cycle
|
||||
|
||||
- platform: factory_reset
|
||||
name: Factory Reset
|
||||
id: factory_reset_all
|
||||
disabled_by_default: true
|
||||
185
ld2450_uart.h
Normal file
185
ld2450_uart.h
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#include "esphome.h"
|
||||
|
||||
#define CHECK_BIT(var, pos) (((var) >> (pos)) & 1)
|
||||
#define STATE_SIZE 8
|
||||
#define TARGETS 3
|
||||
|
||||
static const char *TAG = "ld2450";
|
||||
class LD2450 : public PollingComponent, public UARTDevice
|
||||
{
|
||||
public:
|
||||
LD2450(UARTComponent *parent) : UARTDevice(parent) {}
|
||||
|
||||
// BinarySensor *lastCommandSuccess = new BinarySensor();
|
||||
Sensor *lastCommandSuccess = new Sensor();
|
||||
Sensor *target1Resolution = new Sensor();
|
||||
Sensor *target1Speed = new Sensor();
|
||||
Sensor *target1X = new Sensor();
|
||||
Sensor *target1Y = new Sensor();
|
||||
Sensor *target2Resolution = new Sensor();
|
||||
Sensor *target2Speed = new Sensor();
|
||||
Sensor *target2X = new Sensor();
|
||||
Sensor *target2Y = new Sensor();
|
||||
Sensor *target3Resolution = new Sensor();
|
||||
Sensor *target3Speed = new Sensor();
|
||||
Sensor *target3X = new Sensor();
|
||||
Sensor *target3Y = new Sensor();
|
||||
Sensor *targets = new Sensor();
|
||||
|
||||
uint32_t lastPeriodicMillis = millis();
|
||||
|
||||
uint16_t twoByteToUint(char firstByte, char secondByte) {
|
||||
return (uint16_t)(secondByte << 8) + firstByte;
|
||||
}
|
||||
|
||||
void reportTargetInfo(int target, char *raw) {
|
||||
int16_t newX, newY, newSpeed, sum;
|
||||
uint16_t newResolution;
|
||||
|
||||
ESP_LOGV(TAG, "Will reporting taget %d", target);
|
||||
|
||||
switch (target) {
|
||||
case 0:
|
||||
newX = twoByteToUint(raw[0], raw[1] & 0x7F);
|
||||
if (raw[1] >> 7 != 0x1)
|
||||
newX = 0 - newX / 10;
|
||||
else
|
||||
newX = newX / 10;
|
||||
if (target1X->get_state() != newX)
|
||||
target1X->publish_state(newX);
|
||||
newY = twoByteToUint(raw[2], raw[3] & 0x7F);
|
||||
if (raw[3] >> 7 != 0x1)
|
||||
newY = 0 - newY / 10;
|
||||
else
|
||||
newY = newY / 10;
|
||||
if (target1Y->get_state() != newY)
|
||||
target1Y->publish_state(newY);
|
||||
newSpeed = twoByteToUint(raw[4], raw[5] & 0x7F);
|
||||
if (raw[5] >> 7 != 0x1)
|
||||
newSpeed = 0 - newSpeed;
|
||||
if (target1Speed->get_state() != newSpeed)
|
||||
target1Speed->publish_state(newSpeed);
|
||||
newResolution = twoByteToUint(raw[6], raw[7]);
|
||||
if (target1Resolution->get_state() != newResolution)
|
||||
target1Resolution->publish_state(newResolution);
|
||||
break;
|
||||
case 1:
|
||||
newX = twoByteToUint(raw[0], raw[1] & 0x7F);
|
||||
if (raw[1] >> 7 != 0x1)
|
||||
newX = 0 - newX / 10;
|
||||
else
|
||||
newX = newX / 10;
|
||||
if (target2X->get_state() != newX)
|
||||
target2X->publish_state(newX);
|
||||
newY = twoByteToUint(raw[2], raw[3] & 0x7F);
|
||||
if (raw[3] >> 7 != 0x1)
|
||||
newY = 0 - newY / 10;
|
||||
else
|
||||
newY = newY / 10;
|
||||
if (target2Y->get_state() != newY)
|
||||
target2Y->publish_state(newY);
|
||||
newSpeed = twoByteToUint(raw[4], raw[5] & 0x7F);
|
||||
if (raw[5] >> 7 != 0x1)
|
||||
newSpeed = 0 - newSpeed;
|
||||
if (target2Speed->get_state() != newSpeed)
|
||||
target2Speed->publish_state(newSpeed);
|
||||
newResolution = twoByteToUint(raw[6], raw[7]);
|
||||
if (target2Resolution->get_state() != newResolution)
|
||||
target2Resolution->publish_state(newResolution);
|
||||
break;
|
||||
case 2:
|
||||
newX = twoByteToUint(raw[0], raw[1] & 0x7F);
|
||||
if (raw[1] >> 7 != 0x1)
|
||||
newX = 0 - newX / 10;
|
||||
else
|
||||
newX = newX / 10;
|
||||
if (target3X->get_state() != newX)
|
||||
target3X->publish_state(newX);
|
||||
newY = twoByteToUint(raw[2], raw[3] & 0x7F);
|
||||
if (raw[3] >> 7 != 0x1)
|
||||
newY = 0 - newY / 10;
|
||||
else
|
||||
newY = newY / 10;
|
||||
if (target3Y->get_state() != newY)
|
||||
target3Y->publish_state(newY);
|
||||
newSpeed = twoByteToUint(raw[4], raw[5] & 0x7F);
|
||||
if (raw[5] >> 7 != 0x1)
|
||||
newSpeed = 0 - newSpeed;
|
||||
if (target3Speed->get_state() != newSpeed)
|
||||
target3Speed->publish_state(newSpeed);
|
||||
newResolution = twoByteToUint(raw[6], raw[7]);
|
||||
if (target3Resolution->get_state() != newResolution)
|
||||
target3Resolution->publish_state(newResolution);
|
||||
break;
|
||||
}
|
||||
sum = 0;
|
||||
if (target1Resolution->get_state() > 0){
|
||||
sum+=1;
|
||||
}
|
||||
if (target2Resolution->get_state() > 0){
|
||||
sum+=1;
|
||||
}
|
||||
if (target3Resolution->get_state() > 0){
|
||||
sum+=1;
|
||||
}
|
||||
if (targets->get_state() != sum){
|
||||
targets->publish_state(sum);
|
||||
}
|
||||
}
|
||||
|
||||
void handlePeriodicData(char *buffer, int len) {
|
||||
if (len < 29)
|
||||
return; // 4 frame start bytes + 2 length bytes + 1 data end byte + 1 crc byte + 4 frame end bytes
|
||||
if (buffer[0] != 0xAA || buffer[1] != 0xFF || buffer[2] != 0x03 || buffer[3] != 0x00)
|
||||
return; // check 4 frame start bytes
|
||||
if (buffer[len - 2] != 0x55 || buffer[len - 1] != 0xCC)
|
||||
return; // data end=0x55, 0xcc
|
||||
char stateBytes[STATE_SIZE];
|
||||
|
||||
/*
|
||||
Reduce data update rate to prevent home assistant database size glow fast
|
||||
*/
|
||||
uint32_t currentMillis = millis();
|
||||
if (currentMillis - lastPeriodicMillis < 1000)
|
||||
return;
|
||||
lastPeriodicMillis = currentMillis;
|
||||
for (int i = 0; i < TARGETS; i++) {
|
||||
memcpy(stateBytes, &buffer[4 + i * STATE_SIZE], STATE_SIZE);
|
||||
reportTargetInfo(i, stateBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void readline(int readch, char *buffer, int len) {
|
||||
static int pos = 0;
|
||||
if (readch >= 0) {
|
||||
if (pos < len - 1) {
|
||||
buffer[pos++] = readch;
|
||||
buffer[pos] = 0;
|
||||
} else {
|
||||
pos = 0;
|
||||
}
|
||||
if (pos >= 4) {
|
||||
if (buffer[pos - 2] == 0x55 && buffer[pos - 1] == 0xCC) {
|
||||
handlePeriodicData(buffer, pos);
|
||||
pos = 0; // Reset position index ready for next time
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void setup() override {
|
||||
set_update_interval(15000);
|
||||
}
|
||||
|
||||
void loop() override {
|
||||
const int max_line_length = 160;
|
||||
static char buffer[max_line_length];
|
||||
while (available()) {
|
||||
readline(read(), buffer, max_line_length);
|
||||
}
|
||||
}
|
||||
|
||||
void update(){
|
||||
}
|
||||
};
|
||||
25
led_time_uart.yaml
Normal file
25
led_time_uart.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# =======================
|
||||
# LED / TIME / UART
|
||||
# =======================
|
||||
light:
|
||||
- platform: status_led
|
||||
name: sys_status
|
||||
pin: GPIO15
|
||||
internal: true
|
||||
restore_mode: ALWAYS_OFF
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: time_sntp
|
||||
|
||||
uart:
|
||||
id: uart_ld2410
|
||||
tx_pin: GPIO18
|
||||
rx_pin: GPIO33
|
||||
baud_rate: 256000
|
||||
parity: NONE
|
||||
stop_bits: 1
|
||||
|
||||
ld2410:
|
||||
timeout: 150s
|
||||
id: ld2410_radar
|
||||
47
numbers.yaml
Normal file
47
numbers.yaml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# =======================
|
||||
# NUMBERS (SUWAKI)
|
||||
# =======================
|
||||
number:
|
||||
- platform: template
|
||||
name: "Zone 1 MIN distance (cm)"
|
||||
id: zone1_min_distance
|
||||
min_value: 0
|
||||
max_value: 200
|
||||
step: 10
|
||||
initial_value: 0
|
||||
restore_value: true
|
||||
optimistic: true
|
||||
entity_category: config
|
||||
|
||||
- platform: template
|
||||
name: "Zone 1 MAX distance (cm)"
|
||||
id: zone1_max_distance
|
||||
min_value: 50
|
||||
max_value: 400
|
||||
step: 10
|
||||
initial_value: 220
|
||||
restore_value: true
|
||||
optimistic: true
|
||||
entity_category: config
|
||||
|
||||
- platform: template
|
||||
name: "Zone 2 MIN distance (cm)"
|
||||
id: zone2_min_distance
|
||||
min_value: 200
|
||||
max_value: 600
|
||||
step: 10
|
||||
initial_value: 230
|
||||
restore_value: true
|
||||
optimistic: true
|
||||
entity_category: config
|
||||
|
||||
- platform: template
|
||||
name: "Zone 2 MAX distance (cm)"
|
||||
id: zone2_max_distance
|
||||
min_value: 300
|
||||
max_value: 800
|
||||
step: 10
|
||||
initial_value: 450
|
||||
restore_value: true
|
||||
optimistic: true
|
||||
entity_category: config
|
||||
65
sample.yaml
Normal file
65
sample.yaml
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
esphome:
|
||||
name: radar-lazienka
|
||||
comment: Radar Lazienka
|
||||
friendly_name: Radar Lazienka
|
||||
name_add_mac_suffix: True
|
||||
platformio_options:
|
||||
board_build.flash_mode: dio
|
||||
board_build.f_cpu: 80000000L
|
||||
project:
|
||||
name: radar.lazienka
|
||||
version: 1U
|
||||
min_version: 2025.5.1
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: git
|
||||
url: https://github.com/screek-workshop/custom_components_support_for_screek_1u
|
||||
ref: master
|
||||
components: [ ld2410 ]
|
||||
|
||||
esp32:
|
||||
board: lolin_s2_mini
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
improv_serial:
|
||||
|
||||
logger:
|
||||
hardware_uart: uart0
|
||||
|
||||
api:
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: ""
|
||||
|
||||
wifi:
|
||||
ssid: "xxx"
|
||||
password: "zzz"
|
||||
output_power: 19dB
|
||||
power_save_mode: LIGHT
|
||||
reboot_timeout: 10min
|
||||
fast_connect: true
|
||||
#manual_ip:
|
||||
#static_ip: 20.0.10.2
|
||||
#gateway: 20.0.0.1
|
||||
#subnet: 255.255.0.0
|
||||
#dns1: 20.0.0.1
|
||||
#dns2: 8.8.8.8
|
||||
ap:
|
||||
ssid: "mmwave"
|
||||
password: "Pass.Word"
|
||||
|
||||
captive_portal:
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
packages:
|
||||
mmwave_binary_sensors: github://rafalrk/mmWaveLD2410c/binary_sensors.yaml@main
|
||||
mmwave_sensors: github://rafalrk/mmWaveLD2410c/sensors.yaml@main
|
||||
mmwave_numbers: github://rafalrk/mmWaveLD2410c/numbers.yaml@main
|
||||
mmwave_switches: github://rafalrk/mmWaveLD2410c/switches.yaml@main
|
||||
mmwave_buttons: github://rafalrk/mmWaveLD2410c/buttons.yaml@main
|
||||
mmwave_led_uart_time: github://rafalrk/mmWaveLD2410c/led_time_uart.yaml@main
|
||||
51
sensors.yaml
Normal file
51
sensors.yaml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# =======================
|
||||
# SENSORS
|
||||
# =======================
|
||||
sensor:
|
||||
- platform: internal_temperature
|
||||
id: sys_esp_temperature
|
||||
name: ESP Temperature
|
||||
unit_of_measurement: °C
|
||||
device_class: temperature
|
||||
update_interval: 45s
|
||||
entity_category: diagnostic
|
||||
|
||||
- platform: uptime
|
||||
name: Uptime
|
||||
id: sys_uptime
|
||||
update_interval: 10s
|
||||
|
||||
- platform: wifi_signal
|
||||
name: RSSI
|
||||
id: wifi_signal_db
|
||||
update_interval: 5s
|
||||
entity_category: diagnostic
|
||||
|
||||
- platform: template
|
||||
id: esp_memory
|
||||
name: ESP Free Memory
|
||||
lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024;
|
||||
unit_of_measurement: kB
|
||||
entity_category: diagnostic
|
||||
|
||||
- platform: ld2410
|
||||
moving_distance:
|
||||
name: Moving Distance
|
||||
id: moving_distance
|
||||
still_distance:
|
||||
name: Still Distance
|
||||
id: still_distance
|
||||
moving_energy:
|
||||
name: Move Energy
|
||||
id: moving_energy
|
||||
still_energy:
|
||||
name: Still Energy
|
||||
id: still_energy
|
||||
detection_distance:
|
||||
name: Detection Distance
|
||||
id: detection_distance
|
||||
force_update: true
|
||||
filters:
|
||||
- median:
|
||||
window_size: 3
|
||||
send_every: 1
|
||||
17
switches.yaml
Normal file
17
switches.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# =======================
|
||||
# SWITCHES (TRYBY)
|
||||
# =======================
|
||||
switch:
|
||||
- platform: template
|
||||
name: "Ignore doors / mirrors / pet"
|
||||
id: ignore_static_reflections
|
||||
optimistic: true
|
||||
restore_mode: RESTORE_DEFAULT_OFF
|
||||
entity_category: config
|
||||
|
||||
- platform: template
|
||||
name: "Shower / WC mode"
|
||||
id: shower_mode
|
||||
optimistic: true
|
||||
restore_mode: RESTORE_DEFAULT_OFF
|
||||
entity_category: config
|
||||
Loading…
Reference in New Issue
Block a user