Stabiler Zwischenstand vor Release 1.0

This commit is contained in:
2026-07-23 23:15:56 +02:00
parent a5caf47b49
commit 5d3dfa6f52
4 changed files with 588 additions and 283 deletions
+85 -21
View File
@@ -1,10 +1,21 @@
substitutions:
geraet: auto-sender-01 # <- pro Fahrzeug ändern: 01, 02, 03 ...
fahrzeug_id: "0x01" # <- pro Fahrzeug ändern: 0x01, 0x02, 0x03 ...
device_name: auto-sender-01
friendly_name: Auto Sender 01
firmware_version: "1.0.0-rc1"
wifi_1_ssid: "Leonardo da WiFi"
wifi_1_password: "44290812080358610465"
# Weitere WLANs bei Bedarf aktivieren.
# wifi_2_ssid: "Werkstatt"
# wifi_2_password: "PASSWORT"
# wifi_3_ssid: "Hotspot"
# wifi_3_password: "PASSWORT"
esphome:
name: ${geraet}
friendly_name: Auto Sender 01
name: ${device_name}
friendly_name: ${friendly_name}
comment: "CC1101 433 MHz Fahrzeugsender ${firmware_version}"
esp32:
board: esp32-c3-devkitm-1
@@ -12,6 +23,7 @@ esp32:
type: esp-idf
logger:
level: INFO
api:
encryption:
@@ -22,44 +34,96 @@ ota:
password: "4bd4f24d4a26730d06e84d6e0816fb09"
wifi:
ssid: "Leonardo da WiFi"
password: "44290812080358610465"
# Wichtig: im Auto ist kein WLAN in Reichweite.
# Ohne diese Zeile würde der ESP alle 15 Min neu starten.
reboot_timeout: 0s
power_save_mode: none
networks:
- ssid: ${wifi_1_ssid}
password: ${wifi_1_password}
# - ssid: ${wifi_2_ssid}
# password: ${wifi_2_password}
# - ssid: ${wifi_3_ssid}
# password: ${wifi_3_password}
ap:
ssid: "${friendly_name} Fallback"
password: "Spring.3"
captive_portal:
# --- SPI zum CC1101 ---
spi:
clk_pin: GPIO6
mosi_pin: GPIO7
miso_pin: GPIO5
# --- CC1101 im Paketmodus ---
cc1101:
cs_pin: GPIO4
gdo0_pin: GPIO3
frequency: 433.92MHz
modulation_type: GFSK
symbol_rate: 4800
output_power: 10 # volle Leistung, Reichweite regelt der Empfänger per RSSI
output_power: 10
packet_mode: true
packet_length: 4
crc_enable: true
sync0: 0x91
sync1: 0xD3
# --- alle 2 Sekunden die Fahrzeug-Kennung senden ---
# Paketaufbau: [Magic, Magic, Fahrzeug-ID, Reserve]
output:
- platform: gpio
id: status_led
pin:
number: GPIO8
inverted: true
interval:
- interval: 2s
then:
- cc1101.send_packet:
data: [0xA7, 0x3C, ${fahrzeug_id}, 0x00]
data:
- 0xA7
- 0x3C
- 0x01
- 0x00
# Onboard-LED des Super Mini (invertiert)
light:
- platform: status_led
name: Status
pin:
number: GPIO8
inverted: true
- interval: 60s
then:
- output.turn_on: status_led
- delay: 100ms
- output.turn_off: status_led
sensor:
- platform: wifi_signal
name: "${friendly_name} WLAN Signal"
update_interval: 60s
- platform: uptime
name: "${friendly_name} Laufzeit"
update_interval: 60s
text_sensor:
- platform: version
name: "${friendly_name} ESPHome Version"
- platform: template
name: "${friendly_name} Firmware Version"
lambda: |-
return {"${firmware_version}"};
- platform: wifi_info
ip_address:
name: "${friendly_name} IP"
ssid:
name: "${friendly_name} WLAN SSID"
mac_address:
name: "${friendly_name} MAC"
button:
- platform: restart
name: "${friendly_name} Neustart"
+319 -66
View File
@@ -1,6 +1,21 @@
esphome:
name: tor-steuerung
substitutions:
device_name: tor-steuerung
friendly_name: Tor Steuerung
firmware_version: "1.0.0-rc1"
wifi_1_ssid: "Leonardo da WiFi"
wifi_1_password: "44290812080358610465"
# Weitere WLANs bei Bedarf aktivieren.
# wifi_2_ssid: "Werkstatt"
# wifi_2_password: "PASSWORT"
# wifi_3_ssid: "Hotspot"
# wifi_3_password: "PASSWORT"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
comment: "Autonome CC1101 433 MHz Torsteuerung ${firmware_version}"
esp32:
board: esp32dev
@@ -9,7 +24,7 @@ esp32:
version: recommended
logger:
level: DEBUG
level: INFO
api:
encryption:
@@ -20,41 +35,73 @@ ota:
password: "4bd4f24d4a26730d06e84d6e0816fb09"
wifi:
ssid: "Leonardo da WiFi"
password: "44290812080358610465"
reboot_timeout: 0s
power_save_mode: none
networks:
- ssid: ${wifi_1_ssid}
password: ${wifi_1_password}
# - ssid: ${wifi_2_ssid}
# password: ${wifi_2_password}
# - ssid: ${wifi_3_ssid}
# password: ${wifi_3_password}
ap:
ssid: "Torsteuerung"
password: "Spring.3"
captive_portal:
# --- Bestehende Hardware ---
debug:
update_interval: 60s
switch:
- platform: gpio
pin: GPIO16
id: tor_impuls_relay
name: "Tor Impuls"
restore_mode: ALWAYS_OFF
on_turn_on:
- delay: 500ms
- switch.turn_off: tor_impuls_relay
globals:
- id: total_packets
type: uint32_t
restore_value: true
initial_value: "0"
binary_sensor:
- platform: gpio
pin: GPIO34
name: "Tor AUF"
device_class: door
- platform: gpio
pin: GPIO35
name: "Tor ZU"
device_class: door
- id: valid_packets
type: uint32_t
restore_value: true
initial_value: "0"
# --- Neu: CC1101 433 MHz Empfänger für den Funksender im Auto ---
# Pinbelegung siehe README/doku/verdrahtung-cc1101.svg
# (GPIO16/34/35 sind durch die bestehende Hardware belegt, deshalb
# hier die freien VSPI-Standardpins verwendet)
- id: rejected_packets
type: uint32_t
restore_value: true
initial_value: "0"
- id: gate_open_count
type: uint32_t
restore_value: true
initial_value: "0"
- id: last_open_ms
type: uint32_t
restore_value: false
initial_value: "0"
- id: last_packet_ms
type: uint32_t
restore_value: false
initial_value: "0"
- id: last_vehicle_id
type: int
restore_value: true
initial_value: "0"
- id: last_rssi_value
type: float
restore_value: true
initial_value: "-127.0"
- id: last_lqi_value
type: int
restore_value: true
initial_value: "0"
spi:
clk_pin: GPIO18
@@ -63,64 +110,270 @@ spi:
cc1101:
cs_pin: GPIO5
gdo0_pin: GPIO4
gdo0_pin: GPIO17
frequency: 433.92MHz
modulation_type: GFSK
symbol_rate: 4800
packet_mode: true
packet_length: 4
crc_enable: true
sync0: 0x91
sync1: 0xD3
on_packet:
then:
- lambda: |-
// Magic-Bytes prüfen
if (x.size() < 3 || x[0] != 0xA7 || x[1] != 0x3C) return;
const char *tag = "tor_433";
const uint32_t now = millis();
id(total_packets) += 1;
id(last_packet_ms) = now;
uint8_t fz = x[2];
ESP_LOGI("tor", "Fahrzeug %u, RSSI %.1f dBm, LQI %u", fz, rssi, lqi);
// Reichweite: nur öffnen wenn Signal stark genug (= Auto nah)
if (rssi < id(rssi_schwelle).state) return;
// erlaubte Fahrzeuge
if (fz < 1 || fz > 10) {
ESP_LOGW("tor", "Unbekannte Fahrzeug-ID: %u", fz);
if (data.size() != 4) {
id(rejected_packets) += 1;
id(last_event_text).publish_state("Verworfen: falsche Paketlaenge");
ESP_LOGW(tag, "Paket verworfen: falsche Laenge (%u)", data.size());
return;
}
// Sperrzeit, damit das Tor nicht dauernd getriggert wird
uint32_t jetzt = millis();
if (id(letzte_oeffnung) != 0 && (jetzt - id(letzte_oeffnung)) < 60000) return;
id(letzte_oeffnung) = jetzt;
if (data[0] != 0xA7 || data[1] != 0x3C) {
id(rejected_packets) += 1;
id(last_event_text).publish_state("Verworfen: falsche Magic Bytes");
ESP_LOGW(tag, "Paket verworfen: Magic Bytes %02X %02X", data[0], data[1]);
return;
}
ESP_LOGI("tor", "Tor öffnen für Fahrzeug %u (RSSI %.1f)", fz, rssi);
id(letztes_fahrzeug).publish_state(std::to_string(fz));
id(tor_impuls_relay).turn_on();
const int vehicle_id = data[2];
const int reserve = data[3];
id(last_vehicle_id) = vehicle_id;
id(last_rssi_value) = rssi;
id(last_lqi_value) = lqi;
globals:
- id: letzte_oeffnung
type: uint32_t
restore_value: false
initial_value: '0'
id(last_vehicle_sensor).publish_state(vehicle_id);
id(last_rssi_sensor).publish_state(rssi);
id(last_lqi_sensor).publish_state(lqi);
ESP_LOGI(tag, "Paket: id=%d reserve=%d rssi=%.1f lqi=%d", vehicle_id, reserve, rssi, lqi);
if (vehicle_id < 1 || vehicle_id > 10) {
id(rejected_packets) += 1;
id(last_event_text).publish_state("Verworfen: Fahrzeug-ID nicht erlaubt");
ESP_LOGW(tag, "Paket verworfen: Fahrzeug-ID %d nicht erlaubt", vehicle_id);
return;
}
if (rssi < id(rssi_limit).state) {
id(rejected_packets) += 1;
id(last_event_text).publish_state("Verworfen: RSSI zu schwach");
ESP_LOGW(tag, "Paket verworfen: RSSI %.1f kleiner als Grenze %.1f", rssi, id(rssi_limit).state);
return;
}
const uint32_t lockout_ms = (uint32_t) (id(lockout_seconds).state * 1000.0f);
if (id(last_open_ms) != 0 && (now - id(last_open_ms)) < lockout_ms) {
id(rejected_packets) += 1;
id(last_event_text).publish_state("Verworfen: Sperrzeit aktiv");
ESP_LOGI(tag, "Paket ignoriert: Sperrzeit aktiv (%u ms verbleibend)", lockout_ms - (now - id(last_open_ms)));
return;
}
id(valid_packets) += 1;
if (id(test_mode).state) {
id(last_event_text).publish_state("Testmodus: Oeffnung waere erfolgt");
ESP_LOGI(tag, "Testmodus aktiv: Relais wird nicht geschaltet");
return;
}
id(last_open_ms) = now;
id(gate_open_count) += 1;
id(last_event_text).publish_state("Torimpuls ausgeloest");
ESP_LOGI(tag, "Torimpuls ausgeloest durch Fahrzeug-ID %d", vehicle_id);
id(trigger_gate).execute();
switch:
- platform: gpio
pin: GPIO16
id: tor_impuls_relay
name: "Tor Impuls"
restore_mode: ALWAYS_OFF
# In HA per Schieberegler einstellbar, kein Neuflashen nötig.
# Startwert -60 ≈ 5 m, im Betrieb anhand der geloggten RSSI-Werte feinjustieren.
number:
- platform: template
name: RSSI Schwelle
id: rssi_schwelle
min_value: -100
max_value: -20
step: 1
initial_value: -60
id: test_mode
name: "Testmodus"
optimistic: true
restore_value: true
unit_of_measurement: dBm
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
text_sensor:
binary_sensor:
- platform: gpio
pin: GPIO34
name: "Tor AUF"
device_class: door
- platform: gpio
pin: GPIO35
name: "Tor ZU"
device_class: door
- platform: status
name: "${friendly_name} Status"
number:
- platform: template
name: Letztes Fahrzeug
id: letztes_fahrzeug
id: rssi_limit
name: "RSSI Grenze"
min_value: -100
max_value: -30
step: 1
initial_value: -60
restore_value: true
optimistic: true
unit_of_measurement: "dBm"
entity_category: config
- platform: template
id: lockout_seconds
name: "Sperrzeit"
min_value: 5
max_value: 300
step: 1
initial_value: 60
restore_value: true
optimistic: true
unit_of_measurement: "s"
entity_category: config
script:
- id: trigger_gate
mode: single
then:
- switch.turn_on: tor_impuls_relay
- delay: 500ms
- switch.turn_off: tor_impuls_relay
sensor:
- platform: wifi_signal
name: "${friendly_name} WLAN Signal"
update_interval: 60s
- platform: uptime
name: "${friendly_name} Laufzeit"
update_interval: 60s
- platform: template
id: last_vehicle_sensor
name: "Letzte Fahrzeug-ID"
accuracy_decimals: 0
lambda: |-
return id(last_vehicle_id);
update_interval: 60s
- platform: template
id: last_rssi_sensor
name: "Letzter RSSI"
unit_of_measurement: "dBm"
accuracy_decimals: 1
lambda: |-
return id(last_rssi_value);
update_interval: 60s
- platform: template
id: last_lqi_sensor
name: "Letzter LQI"
accuracy_decimals: 0
lambda: |-
return id(last_lqi_value);
update_interval: 60s
- platform: template
name: "Pakete gesamt"
accuracy_decimals: 0
lambda: |-
return id(total_packets);
update_interval: 60s
- platform: template
name: "Pakete gueltig"
accuracy_decimals: 0
lambda: |-
return id(valid_packets);
update_interval: 60s
- platform: template
name: "Pakete verworfen"
accuracy_decimals: 0
lambda: |-
return id(rejected_packets);
update_interval: 60s
- platform: template
name: "Toroeffnungen"
accuracy_decimals: 0
lambda: |-
return id(gate_open_count);
update_interval: 60s
- platform: template
name: "Sekunden seit letztem Paket"
unit_of_measurement: "s"
accuracy_decimals: 0
lambda: |-
if (id(last_packet_ms) == 0) return {};
return (millis() - id(last_packet_ms)) / 1000.0f;
update_interval: 10s
- platform: template
name: "Sekunden seit letzter Toroeffnung"
unit_of_measurement: "s"
accuracy_decimals: 0
lambda: |-
if (id(last_open_ms) == 0) return {};
return (millis() - id(last_open_ms)) / 1000.0f;
update_interval: 10s
- platform: debug
free:
name: "${friendly_name} Freier Heap"
text_sensor:
- platform: version
name: "${friendly_name} ESPHome Version"
- platform: template
name: "${friendly_name} Firmware Version"
lambda: |-
return {"${firmware_version}"};
- platform: template
id: last_event_text
name: "Letztes 433 MHz Ereignis"
- platform: debug
reset_reason:
name: "${friendly_name} Neustartgrund"
- platform: wifi_info
ip_address:
name: "${friendly_name} IP"
ssid:
name: "${friendly_name} WLAN SSID"
mac_address:
name: "${friendly_name} MAC"
button:
- platform: restart
name: "${friendly_name} Neustart"
- platform: template
name: "Zaehler zuruecksetzen"
entity_category: config
on_press:
- lambda: |-
id(total_packets) = 0;
id(valid_packets) = 0;
id(rejected_packets) = 0;
id(gate_open_count) = 0;
id(last_event_text).publish_state("Zaehler zurueckgesetzt");