Zum Inhalt

Das HESP-Protokoll

HESP ist das binäre Anfrage/Antwort-Protokoll auf dem 19200-Baud-Bus (X7). Name und Grundstruktur des Telegramms sind in einem FHEM-Forum-Thread (Topic 96437) zur verwandten Hermes-/P-Serie vorbeschrieben; die hier dokumentierte Frame-Struktur und das Prüfsummenmodell wurden aus eigenen Busmitschnitten bestimmt.

Physische Ebene

  • 19200 Baud, 8N1, RS485 halbduplex, differentielles A/B-Paar auf X7-4/X7-3.
  • Master ist der STM32 des PTC-Moduls; er pollt den LPC1758 etwa alle 5 Sekunden und re-asserted dabei den aktuellen Panel-Zustand (Stufe/Modus/Sollwerte).

Frame-Format

Jeder Frame:

H0  80  00   <id_lo> <id_hi>   00 00   <len>   <data …>   <crc_lo> <crc_hi>
Feld Bytes Bedeutung
H0 1 Header. Low-Nibble = Typ (siehe unten), High-Nibble Länge/Node-abhängig
80 00 2 fester Kopf-Rest (Node/Subadresse; andere Nodes z. B. …07…)
id_lo id_hi 2 Datenpunkt-ID, 16-bit little-endian
00 00 2 Reserviert / Sub-Selektor
len 1 Nibble-Anzahl der Daten (0x08=4 B, 0x20=16 B, 0xe0=224 B)
data n Nutzdaten (float32 LE, int, Array …)
crc 2 Prüfsumme (little-endian)

Der Typ-Nibble

Das Low-Nibble des ersten Bytes kodiert die Telegramm-Art — exakt wie im Forum dokumentiert und am Draht bestätigt:

Nibble Typ Header-Beispiel
0 QUERY (Anfrage) 10 80 00 …
1 SET (Schreiben) 11 80 00 …
2 RESPONSE (Antwort) 22 40 00 …
3 CONFIRM (Schreibbestätigung) 23 40 00 …

Beispiele

QUERY    10 80 00 60 01 00 00 04 01 00 49 e1        # frage DP 0x0160
RESPONSE 22 40 00 d2 00 00 00 20 …16 B… 5a cb        # Antwort mit 16 B Daten
SET      11 80 00 27 02 00 00 08 00 00 98 41 8a cd  # setze DP 0x0227 = 19.0 (float32)
CONFIRM  23 40 00 27 02 00 00 00 39 a1              # Schreiben bestätigt

Nutzdaten sind IEEE-754 float32 little-endian für Temperaturen und Sollwerte, sonst Integer (RPM, Zähler, Flags) oder Arrays (Kennlinien).

Prüfsumme

Die letzten zwei Bytes jedes Frames bilden eine Prüfsumme.

  • Sie entspricht keiner Standard-CRC-16: alle 65536 Polynome in Kombination mit Reflect-Varianten und Byte-Reihenfolge wurden gegen echte Frame-Paare geprüft, ohne Übereinstimmung.
  • Die Prüfsumme ist jedoch eine affine Abbildung über GF(2) (linear plus Konstante). Ein end-ausgerichtetes affines Modell — variable End-Bits zuzüglich einer Konstante je Frame-Länge, bestimmt aus rund 1650 kurzen Frames — sagt 331 von 331 zurückgehaltenen Frames aller Typen korrekt voraus. Die gelösten Konstanten sind für alle beobachteten Frame-Längen (8–12 Bytes) null, das Modell ist also in diesem Bereich rein linear: Die Prüfsumme ist ein XOR fester 16-bit-Beitragsvektoren über alle gesetzten Nachrichtenbits.

Damit ist die Prüfsumme für selbst erzeugte Frames deterministisch berechenbar.

Modell in Tabellenform

Bits werden vom Frame-Ende her indiziert (GF(2)-Konvention „end-aligned"): Für Byte i (0-basiert ab Frame-Anfang), Bit b (0 = LSB) eines Frames mit N Bytes (ohne die 2 CRC-Bytes) ist die End-Bitposition

e = (N − 1 − i) · 8 + b

Die 16-bit-Prüfsumme (dargestellt als crc_hi·256 + crc_lo; im Frame steht crc_lo zuerst) ist das XOR der Beitragsvektoren V[e] aller gesetzten Nachrichtenbits:

CRC = ⊕ V[e]   über alle Bits e mit Wert 1
e V[e] e V[e] e V[e] e V[e]
0 8bb4 1 a379 2 b9e0 3 0222
4 0000 5 0000 6 6474 7 92a8
8 80fc 9 0169 10 02d2 11 05a4
12 0b48 13 1690 14 2d20 15 0000
16 cd56 17 9a3d 18 34eb 19 69d6
20 d3ac 21 a7c9 22 4f03 23 9e06
24 0534 25 0a68 26 14d0 27 29a0
28 5340 29 a680 30 4d91 31 9b22
32 b823 33 70d7 34 e1ae 35 c3cd
36 870b 37 0e87 38 1d0e 39 3a1c
40 78a8 41 f150 42 e231 43 c4f3
45 c2be 46 0000 48 8e67 49 1c5f
50 38be 51 717c 52 e2f8 53 c561
54 8a53 55 1437 56 0c91 57 1922
58 3244 59 ecb4 61 136c 62 6e15
63 0000 64 cc6b 65 9847 66 301f
67 603e 68 c07c 69 8069 70 0043
71 0086 72 a403 73 e47b 76 6242
77 0000 78 3b0b 79 0000 81 0000
85 0000 86 0daf 87 1213 88 0000
89 0000 92 0000 93 0000

Geltungsbereich des Modells

Die Positionen e ∈ {44, 47, 60, 74, 75, 80, 82, 83, 84, 90, 91, 94, 95} fehlen in der Tabelle: Diese Bits waren im gesamten Trainingsmaterial konstant, ihre Beitragsvektoren sind daher unbekannt (nicht null!). Das Modell gilt nur für Frames, deren gesetzte Bits von der Tabelle abgedeckt sind (typische Anfrage-/ Setz-Frames auf Sub-Adresse 0, Längen 8–12 Bytes). Für davon abweichende Datenbytes ist der Trainingsdatensatz zu erweitern oder ein entsprechender Master-Frame aus einem Mitschnitt unverändert zu übernehmen. Die 0000-Einträge dagegen sind echte, gelöste Nullbeiträge.

Rechenbeispiel

Anfrage-Frame für Datenpunkt 0x0160 (siehe Beispiele oben), N = 10 Nutzbytes:

10 80 00 60 01 00 00 04 01 00

Gesetzte Bits und ihre Beitragsvektoren:

Byte i Wert Bit b e = (9−i)·8+b V[e]
0 10 4 76 6242
1 80 7 71 0086
3 60 5 53 c561
3 60 6 54 8a53
4 01 0 40 78a8
7 04 2 18 34eb
8 01 0 8 80fc

XOR aller sieben Vektoren:

6242 ⊕ 0086 ⊕ c561 ⊕ 8a53 ⊕ 78a8 ⊕ 34eb ⊕ 80fc = e149

crc_lo = 49, crc_hi = e1; der vollständige Frame auf dem Bus lautet also

10 80 00 60 01 00 00 04 01 00 49 e1

und entspricht exakt dem Mitschnitt.

Meta-Datenpunkte (Selbstauskunft)

Der Bus beschreibt sich teilweise selbst:

DP Inhalt
0x0001 Klartextname des Nodes (z. B. Node 0x41 = „PTC-Modul")
0x0033 Liste aller Parameter-DP-Nummern (Verzeichnis)
0x0034 parallele Typcode-Liste dazu
0x0038 Zugriffslevel-Maske je DP (siehe unten)
0x0039 Einheiten-Code je DP (8=°C, 5=Sekunden, 11=String …)
0x0130 Fehlerstatus als Klartext („Kein Fehler")

Zugriffsmaske 0x0038

Ein Byte pro DP kodiert die Schreibrechte über vier Zugriffsebenen (je 2 Bit R/W):

Maske Bedeutung trifft
0x55 read-only alle Messwerte, Zähler
0xFF überall schreibbar die vom Panel gesetzten User-Werte (Raumsoll etc.)
0xD5 nur oberste Ebene schreibbar der Fachmann-Parameterblock
0xC0 nur oberste Ebene sichtbar Werks-Kennlinien, Lüfter-Arrays

Die Maske bestätigt unabhängig, welche DPs das (PIN-geschützte) Fachmann-Menü ausmachen — nützlich, um beim Parametrieren nicht blind in geschützte Register zu schreiben.