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
+37
View File
@@ -0,0 +1,37 @@
# Changelog
## 1.0.0-rc1 - 2026-07-23
### Hinzugefuegt
- Vollstaendige ESPHome-Konfiguration fuer den Fahrzeugsender.
- Vollstaendige ESPHome-Konfiguration fuer die Torsteuerung.
- Autonome lokale Torlogik ohne Home-Assistant-Abhaengigkeit.
- CC1101 433 MHz Paketprotokoll mit Magic Bytes `0xA7 0x3C`.
- Sender-Heartbeat per LED nur noch einmal pro Minute.
- Mehrere WLANs vorbereitet.
- OTA fuer Sender und Empfaenger.
- Fallback-AP fuer Sender und Empfaenger.
- Diagnosewerte fuer RSSI, LQI, Pakete, Toroeffnungen, WLAN, Laufzeit, Heap und Neustartgrund.
- Einstellbare RSSI-Grenze.
- Einstellbare Sperrzeit.
- Testmodus ohne Relaisschaltung.
- Zaehler-Reset per Home Assistant Button.
- README mit Flash-, Test- und Git-Ablauf.
### Beibehalten
- Getestetes 4-Byte-Funkpaket: `0xA7 0x3C 0x01 0x00`.
- Frequenz `433.92 MHz`.
- Modulation `GFSK`.
- Symbolrate `4800`.
- Paketlaenge `4`.
- CRC aktiviert.
- Sync-Bytes `0x91 0xD3`.
- Torrelais auf `GPIO16`.
- Torkontakte auf `GPIO34` und `GPIO35`.
### Hinweise
- Die genaue `cc1101.on_packet` Syntax haengt von der verwendeten externen CC1101-Komponente ab. Der Sender nutzt die bereits getestete `cc1101.send_packet` Syntax.
- Vor dem Einbau am endgueltigen Ort sollten Sender und Empfaenger gemeinsam kompiliert, geflasht und mit Testmodus geprueft werden.
+147 -196
View File
@@ -1,233 +1,184 @@
# Funksender Tor
Automatische Toröffnung per 433 MHz. Jedes Fahrzeug bekommt einen kleinen Sender
am Zündungsplus, der Empfänger am Tor öffnet, sobald ein bekanntes Fahrzeug nah
genug ist. Kein Knopfdruck, keine App, kein Account.
ESPHome-Projekt fuer eine autonome Torsteuerung mit 433 MHz CC1101 Funk.
**Hardware:** ESP32-C3 Super Mini + CC1101 (433 MHz) je Sender,
ein bestehender ESP32 DevKit (`tor-steuerung`) + CC1101 als Empfänger am Tor —
derselbe ESP, der schon Relais und Türsensoren steuert.
Das System besteht aus zwei Teilen:
---
- `auto_sender_01.yaml`: ESP32-C3 Sender im Fahrzeug
- `tor_steuerung.yaml`: ESP32 Empfaenger an der Torsteuerung
## Inhalt
Home Assistant ist nur fuer OTA, Diagnose und Einstellungen vorgesehen. Die eigentliche Entscheidung und das Schalten des Relais laufen lokal auf der Torsteuerung. Das Tor kann also auch dann oeffnen, wenn Home Assistant, WLAN oder Internet ausfallen.
- [Verdrahtung CC1101](#verdrahtung-cc1101)
- [Flashen](#flashen) — **hier steht der USB-TTL-Kram**
- [ESPHome einrichten](#esphome-einrichten)
- [Reichweite einstellen](#reichweite-einstellen)
- [Weiteres Fahrzeug hinzufügen](#weiteres-fahrzeug-hinzufügen)
- [Paketformat](#paketformat)
## Status
---
Release-Kandidat: `1.0.0-rc1`
## Verdrahtung CC1101
Getestetes Funkpaket:
Die Pins des CC1101 sitzen als **4 Zeilen à 2 Pins**, Antenne rechts:
```
① GND │ VDD ②
③ GDO0 │ CSN ④
⑤ SCK │ MOSI ⑥
⑦ MISO │ GDO2 ⑧
```text
0xA7 0x3C 0x01 0x00
```
> **Achtung:** Pin 1 ist **GND**, Pin 2 ist **VDD**. Nicht die verbreitete
> Belegung mancher anderer CC1101-Boards annehmen, wo es umgekehrt ist —
> Vertauschen macht das Modul und ggf. den ESP heiß.
## Dateien
| CC1101 | Signal | ESP32-C3 Super Mini |
|--------|--------|---------------------|
| 1 | GND | `G` (links) |
| 2 | VDD | `3.3` (links) — **niemals 5V** |
| 3 | GDO0 | `GPIO3` (links) |
| 4 | CSN | `GPIO4` (links) |
| 5 | SCK | `GPIO6` (rechts) |
| 6 | MOSI | `GPIO7` (rechts) |
| 7 | MISO | `GPIO5` (rechts) |
| 8 | GDO2 | *frei lassen* |
Schema: [`doku/verdrahtung-cc1101.svg`](doku/verdrahtung-cc1101.svg)
(zeigt die Pin-Reihenfolge am CC1101 selbst — die Zuordnung zu GPIOs
unterscheidet sich je nach ESP-Board, siehe Tabellen oben/unten.)
### Empfänger (`tor-steuerung`, ESP32 DevKit)
GPIO16 (Relais) und GPIO34/35 (Türsensoren) sind schon belegt. Der CC1101
hängt deshalb an den freien VSPI-Standardpins:
| CC1101 | Signal | ESP32 DevKit |
|--------|--------|--------------|
| 1 | GND | GND |
| 2 | VDD | 3V3 |
| 3 | GDO0 | `GPIO4` |
| 4 | CSN | `GPIO5` |
| 5 | SCK | `GPIO18` |
| 6 | MOSI | `GPIO23` |
| 7 | MISO | `GPIO19` |
| 8 | GDO2 | *frei lassen* |
---
## Flashen
### Warum nicht über den USB-C-Anschluss?
Der ESP32-C3 hat einen eingebauten USB-Serial/JTAG-Controller. Unter Windows 11
sollte er automatisch als COM-Port erscheinen — **tut er aber nicht mehr, sobald
Zadig einmal auf ihm gelaufen ist.**
Was passiert war: Zadig ersetzt den nativen `usbser.sys` durch WinUSB bzw.
selbstgenerierte libwdi/libusbK-Treiber. Danach zeigt der Geräte-Manager zwar
einen COM-Port, aber esptool bekommt nur
```
A fatal error occurred: Failed to connect to ESP32-C3: No serial data received.
```text
esphome/
auto_sender_01.yaml
tor_steuerung.yaml
README.md
CHANGELOG.md
```
Das lässt sich reparieren (siehe unten), ist aber fummelig. **Der USB-TTL-Adapter
umgeht das Thema komplett.**
## Hardware
### USB-TTL-Adapter anschließen ← *das ist der Weg, der funktioniert hat*
### Sender
> **Adapter zwingend auf 3.3 V jumpern.** Der ESP32-C3 ist nicht 5V-tolerant.
- ESP32-C3 DevKit / ESP32-C3 Super Mini
- CC1101 433 MHz Modul
- Versorgung passend zur Einbausituation
| USB-TTL-Adapter | ESP32-C3 Super Mini |
|-----------------|---------------------|
| TX | `GPIO20` (rechts, vorletzter Pin) |
| RX | `GPIO21` (rechts, letzter Pin) |
| GND | `G` (links, 2. Pin) |
| 3.3V | `3.3` (links, 3. Pin) |
### Empfaenger
TX und RX sind **gekreuzt** — das ist so richtig.
Das CC1101 kann angeschlossen bleiben, GPIO20/21 kollidieren mit nichts.
- ESP32 DevKit / ESP32 Relaisboard
- CC1101 433 MHz Modul
- Relaiskontakt fuer Torimpuls
- Endschalter oder Rueckmeldekontakte fuer Tor AUF und Tor ZU
Liefert der Adapter auf 3.3 V zu wenig Strom, den ESP stattdessen über ein
USB-Netzteil an der USB-C-Buchse versorgen und vom Adapter nur TX, RX und GND
anschließen. **Nicht beide Quellen gleichzeitig.**
## Funkprotokoll
### Boot-Modus
Der Sender uebertraegt alle 2 Sekunden ein festes 4-Byte-Paket:
**`GPIO9``G` brücken, danach erst Strom drauf.** Reihenfolge ist wichtig.
Nach dem Flashen die Brücke wieder entfernen.
### Ablauf
```bash
# 1. Verbindung prüfen — COM-Port des TTL-Adapters aus dem Geräte-Manager
python -m esptool --chip esp32c3 --port COM16 chip-id
```text
Byte 1: 0xA7 Magic
Byte 2: 0x3C Magic
Byte 3: 0x01 Fahrzeug-ID
Byte 4: 0x00 Reserve
```
Erwartete Ausgabe:
CC1101 Einstellungen:
```
Chip type: ESP32-C3 AZ (QFN32) (revision v1.1)
Features: Wi-Fi, BT 5 (LE), Single Core, 160MHz, Embedded Flash 4MB (XMC)
MAC: 44:b1:76:18:cb:ec
- Frequenz: `433.92 MHz`
- Modulation: `GFSK`
- Symbolrate: `4800`
- Paketlaenge: `4`
- CRC: aktiv
- Sync: `0x91 0xD3`
## Sender flashen
Datei:
```text
esphome/auto_sender_01.yaml
```
```bash
# 2. Factory-Image flashen (nicht die normale .bin!)
python -m esptool --chip esp32c3 --port COM16 --baud 460800 \
write-flash 0x0 auto-sender-01.factory.bin
```
Das erste Flashen erfolgt bei deiner Hardware per TTL/USB-Adapter. Danach kann OTA verwendet werden, sobald der Sender im WLAN erreichbar ist.
Bricht es bei 460800 ab, mit `--baud 115200` wiederholen.
Danach GPIO9-Brücke raus, Strom aus/an. Ab hier läuft alles über OTA —
der Adapter wird nicht mehr gebraucht.
`esptool` installieren falls nötig: `pip install esptool`
### Falls der interne USB doch mal repariert werden soll
Als Administrator:
```cmd
pnputil /enum-drivers | findstr /i "libwdi libusb"
pnputil /delete-driver oemXX.inf /uninstall /force
```
Alle gefundenen libwdi/libusbK-Pakete löschen, besonders das mit
`MS_COMP_USBSER` — das kapert systemweit jedes CDC-Gerät. Danach neu starten.
Windows zieht dann wieder `usbser.sys`.
**Zadig nicht mehr auf den ESP32-C3 loslassen.** Für den eingebauten
USB-Serial/JTAG ist es das falsche Werkzeug (außer man will JTAG-Debugging
über OpenOCD).
---
## ESPHome einrichten
Beide Geräte tragen WLAN-Zugangsdaten, `api`-Verschlüsselungskey und
OTA-Passwort **direkt in der YAML** statt über `secrets.yaml` — so war
`tor_steuerung.yaml` schon angelegt, und `auto_sender_01.yaml` verwendet
bewusst dieselben Werte, damit beide Geräte zusammenpassen.
> **Achtung:** Damit stehen WLAN-Passwort und Schlüssel im Klartext in diesem
> Repo. Nur vertretbar, wenn `git.dominicspringer.de` privat/intern bleibt.
> Soll das Repo öffentlich werden, vorher alles auf `!secret`-Verweise
> umstellen und eine lokale `secrets.yaml` (nicht committen) anlegen.
1. In ESPHome (HA-Add-on) das jeweilige Gerät anlegen bzw. die bestehende
`tor-steuerung` mit dem neuen Inhalt überschreiben
2. Inhalt der passenden Datei aus `esphome/` einfügen
3. Drei Punkte → **Install****Manual download****Factory format**
4. Mit esptool flashen (siehe oben)
`reboot_timeout: 0s` beim Sender ist kein Versehen: im Auto ist kein WLAN in
Reichweite, ohne diese Zeile startet der ESP alle 15 Minuten neu.
---
## Reichweite einstellen
Die Reichweite wird **nicht** am Sender begrenzt — alle Sender laufen mit voller
Leistung. Der Empfänger entscheidet anhand der Signalstärke (RSSI), ob das
Fahrzeug nah genug ist.
Der Schwellwert liegt als Schieberegler **„RSSI Schwelle"** in Home Assistant,
Änderungen brauchen kein Neuflashen.
Einmessen:
1. Empfänger-Log in ESPHome öffnen
2. Mit dem Fahrzeug in verschiedenen Abständen anhalten
3. RSSI-Werte notieren — z. B. `Fahrzeug 1, RSSI -73.5 dBm, LQI 12`
4. Den Wert bei der gewünschten Distanz (~5 m) als Schwelle setzen
Je näher der Wert an 0, desto kürzer die Reichweite. Startwert ist `-60`.
Nach jeder Öffnung greift eine **Sperrzeit von 60 Sekunden**.
---
## Weiteres Fahrzeug hinzufügen
In `auto_sender_01.yaml` nur die beiden Substitutions oben ändern:
Wichtige Anpassung fuer weitere Fahrzeuge:
```yaml
substitutions:
geraet: auto-sender-02
fahrzeug_id: "0x02"
device_name: auto-sender-02
friendly_name: Auto Sender 02
```
Der Empfänger akzeptiert IDs `0x01` bis `0x0A` (110) und muss dafür **nicht**
angefasst werden. Sollen weniger Fahrzeuge erlaubt sein, im `on_packet`-Lambda
die Zeile `if (fz < 1 || fz > 10)` anpassen.
Und im Paket:
---
```yaml
- 0x02
```
## Paketformat
Die LED blinkt nur einmal pro Minute kurz auf. Das reduziert unnoetige LED-Laufzeit, ist aber noch kein echter Akkubetrieb. Fuer Akkubetrieb sollte spaeter Deep Sleep oder ein Wakeup-Konzept ergaenzt werden.
4 Bytes, GFSK, 4800 Baud, CRC-16 aktiv, Sync `0xD391`:
## Empfaenger flashen
| Byte | Inhalt |
|------|--------|
| 0 | `0xA7` Magic |
| 1 | `0x3C` Magic |
| 2 | Fahrzeug-ID (`0x01``0x0A`) |
| 3 | reserviert (`0x00`) |
Datei:
Der Sender schickt das Paket alle 2 Sekunden, solange die Zündung an ist.
```text
esphome/tor_steuerung.yaml
```
Die Torsteuerung arbeitet autonom:
1. CC1101 Paket empfangen
2. Magic Bytes pruefen
3. Fahrzeug-ID pruefen
4. RSSI-Grenze pruefen
5. Sperrzeit pruefen
6. Relais lokal fuer 500 ms schalten
Home Assistant wird nicht zum Oeffnen benoetigt.
## Home Assistant Diagnose
Die Torsteuerung stellt unter anderem bereit:
- Letzte Fahrzeug-ID
- Letzter RSSI
- Letzter LQI
- Pakete gesamt
- Gueltige Pakete
- Verworfene Pakete
- Toroeffnungen
- Sekunden seit letztem Paket
- Sekunden seit letzter Toroeffnung
- WLAN Signal
- Freier Heap
- Neustartgrund
- Firmware-Version
Einstellbar:
- `RSSI Grenze`
- `Sperrzeit`
- `Testmodus`
Der Testmodus prueft die komplette Logik, schaltet aber das Relais nicht.
## WLAN
Beide YAML-Dateien enthalten einen aktiven WLAN-Eintrag und vorbereitete weitere Eintraege:
```yaml
wifi:
networks:
- ssid: ${wifi_1_ssid}
password: ${wifi_1_password}
```
Weitere WLANs koennen in den `substitutions` und im `wifi.networks` Block aktiviert werden.
## Testablauf vor Einbau
1. Sender flashen.
2. Empfaenger flashen.
3. Pruefen, ob beide in Home Assistant online sind.
4. Empfaenger auf `Testmodus` stellen.
5. Sender in Reichweite bringen.
6. RSSI, LQI und Paketzaehler pruefen.
7. Testmodus deaktivieren.
8. Torimpuls pruefen.
9. Home Assistant oder WLAN testweise deaktivieren.
10. Pruefen, dass der Empfaenger weiterhin lokal schaltet.
## Git
Zwischenstand speichern:
```bash
git add .
git commit -m "Stabiler Zwischenstand vor Release 1.0"
git push origin main
```
Nach erfolgreichem Test als Release markieren:
```bash
git add .
git commit -m "Release 1.0.0 - autonome CC1101 Torsteuerung"
git tag -a v1.0.0 -m "Erste stabile Version"
git push origin main
git push origin v1.0.0
```
Falls dein Standard-Branch `master` heisst, ersetze `main` durch `master`.
+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");