Neues TIN-Protokoll
Übersicht
Das Neues TIN-Protokoll wird von modernen Truma-Heizgeräten verwendet (TIN 4.0, ab Mitte 2018). Im Gegensatz zum Legacy TIN-Protokoll mit separaten Befehls-Frames verfügt Neues TIN über eine einheitliche Befehlsstruktur, bei der alle Heizungsparameter in einem einzigen Frame gesendet werden.
Dieses Protokoll wird verwendet von:
- Modernen Truma Combi-Heizgeräten (ab 2018)
- InetX-Bedienfeldern
- iNet X Connect-Fernsteuerungsmodulen
- Modernen Aventa-Klimaanlagen
Signal-Frame-Typen
| Signal-ID | Frame-Typ | Richtung | Zweck |
|---|---|---|---|
| 0x20 | Heater Command | Master → Slave | Einheitliche Heizungssteuerung |
| 0x21 | Heater Info 1 | Slave → Master | Temperatur-Telemetrie |
| 0x22 | Heater Info 2 | Slave → Master | Leistungs- und Systemstatus |
| 0x17 | Aircon Command | Master → Slave | Klimaanlagensteuerung |
Heater Command (0x20)
Der einheitliche Befehls-Frame zur Steuerung aller Heizungsfunktionen.
Frame-Struktur
| Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| Inhalt | Raumtemp-Code | Steuerflags | Wassertemp | Kraftstoff-Steuerung | Elektro-Leistung | Lüftung + Energie | 0xE0 | 0x0F |
| Funktion | Zieltemp | Boiler/Heizung | Wasserstufe | Gas-Freigabe | Elektroleistung | Lüfter + Bitmap | Fix | Fix |
Byte 0: Raumtemperatur-Code
Die Temperatur wird über folgende Formel codiert:
code = (220 + (temp - 5) * 10) % 256
temp = ((code - 220) % 256) / 10 + 5
Sonderfall: 0xAA = Aus
Temperaturbereich: 5-30°C (in 1°C-Schritten)
Byte 1: Steuerflags
| Bit | Funktion | Werte |
|---|---|---|
| 7 | Boiler-Freigabe | 0 = An, 1 = Aus (invertiert!) |
| 0 | Heizungs-Freigabe | 0 = Aus, 1 = An |
| 1-6 | Basis-Muster | Immer 0x2A (binär: 0010 1010) |
Gängige Werte:
0x2A(0010 1010): Boiler AN, Heizung AUS0x2B(0010 1011): Boiler AN, Heizung AN0xAA(1010 1010): Boiler AUS, Heizung AUS0xAB(1010 1011): Boiler AUS, Heizung AN
Byte 2: Wassertemperaturstufe
| Code | Stufe | Temperatur | Beschreibung |
|---|---|---|---|
0xAA | Aus | - | Wasserheizung deaktiviert |
0xC3 | Eco | ~40°C | Energiesparendes Warmwasser |
0xD0 | Hot | ~60°C | Maximales Warmwasser |
Byte 3: Kraftstoff-Steuerung
| Wert | Funktion |
|---|---|
0x00 | Kraftstoff deaktiviert |
0xFA | Kraftstoff aktiviert (Gas-/Dieselheizung aktiv) |
Byte 4: Elektro-Leistungsstufe
| Code | Leistungsstufe | Watt |
|---|---|---|
0x00 | Aus | 0W |
0x09 | Niedrig | 900W |
0x12 | Hoch | 1800W |
Byte 5: Lüftung + Energie-Bitmap
Oberes Nibble (Bits 4-7): Lüftungsstufe
| Nibble | Stufe | Beschreibung |
|---|---|---|
0x0 | Aus | Lüftung deaktiviert |
0x1 | Stufe 1 | Manuell minimal |
0x2 | Stufe 2 | Manuell niedrig |
0x3-0x9 | Stufen 3-9 | Manuelle Zwischenstufen |
0xA | Stufe 10 | Manuell maximal |
0xB | Comfort | Automatischer Komfortmodus |
0xD | Boost | Maximaler Boost-Modus |
Unteres Nibble (Bits 0-3): Energie-Bitmap
| Bit | Funktion |
|---|---|
| 0 | Kraftstoff aktiviert (spiegelt Byte 3) |
| 1 | Elektro aktiviert (abgeleitet von Byte 4) |
| 2-3 | Reserviert |
Gängige Muster:
0xB0= Comfort-Modus, keine Energie0xB1= Comfort-Modus, nur Kraftstoff0xB2= Comfort-Modus, nur Elektro0xB3= Comfort-Modus, Kraftstoff + Elektro (Mix)
Bytes 6-7: Feste Werte
- Byte 6: Immer
0xE0 - Byte 7: Immer
0x0F
Beispiel-Frames
Alles aus:
[0xAA] [0xAA] [0xAA] [0x00] [0x00] [0x00] [0xE0] [0x0F]
Raum auf 22°C heizen, Wasser Eco, nur Kraftstoff, Comfort-Lüfter:
[0x86] [0x2B] [0xC3] [0xFA] [0x00] [0xB1] [0xE0] [0x0F]
│ │ │ │ │ │
│ │ │ │ │ └─ Comfort-Modus (0xB), Kraftstoff-Bit gesetzt (0x1)
│ │ │ │ └─ Elektro aus
│ │ │ └─ Kraftstoff aktiviert
│ │ └─ Wasser Eco (40°C)
│ └─ Boiler an (Bit 7=0), Heizung an (Bit 0=1), Muster 0x2A
└─ Raum 22°C
Raum auf 28°C heizen, Wasser Hot, Mix-Modus (Kraftstoff + 900W), Boost-Lüfter:
[0xC2] [0x2B] [0xD0] [0xFA] [0x09] [0xD3] [0xE0] [0x0F]
│ │ │ │ │ │
│ │ │ │ │ └─ Boost-Modus (0xD), Kraftstoff + Elektro-Bits (0x3)
│ │ │ │ └─ Elektro 900W
│ │ │ └─ Kraftstoff aktiviert
│ │ └─ Wasser Hot (60°C)
│ └─ Boiler an, Heizung an
└─ Raum 28°C
Nur Wasserheizung (keine Raumheizung), Hot-Wasser, Kraftstoff:
[0xAA] [0x2A] [0xD0] [0xFA] [0x00] [0x01] [0xE0] [0x0F]
│ │ │ │ │ │
│ │ │ │ │ └─ Lüfter aus, Kraftstoff-Bit gesetzt
│ │ │ │ └─ Elektro aus
│ │ │ └─ Kraftstoff aktiviert
│ │ └─ Wasser Hot
│ └─ Boiler an, Heizung aus
└─ Raumheizung aus
Manuelle Lüftungsstufe 5, keine Heizung:
[0xAA] [0xAA] [0xAA] [0x00] [0x00] [0x50] [0xE0] [0x0F]
│
└─ Stufe 5 (0x5), keine Energie
Heater Info 1 (0x21)
Meldet aktuelle Raum- und Wassertemperaturen.
Frame-Struktur
| Byte | 0 | 1 | 2 | 3-7 |
|---|---|---|---|---|
| Inhalt | Raumtemp (untere 8 Bits) | Raum (obere 4 Bits) + Wasser (untere 4 Bits) | Wassertemp (obere 8 Bits) | Reserviert |
| Codierung | 12-Bit gepackt | Gemeinsames Byte | 12-Bit gepackt | Padding |
Temperatur-Codierung
Temperaturen werden als 12-Bit-Werte codiert, die Kelvin × 10 darstellen, gepackt in 3 Bytes.
Raumtemperatur:
raum_codiert = (byte1 & 0x0F) << 8 | byte0
raum_celsius = (raum_codiert / 10.0) - 273.0
Wassertemperatur:
wasser_codiert = byte2 << 4 | (byte1 & 0xF0) >> 4
wasser_celsius = (wasser_codiert / 10.0) - 273.0
Beispiel-Frame
Raum bei 22,5°C, Wasser bei 45,3°C:
Schritt 1: Temperaturen codieren
raum_kelvin_x10 = (22,5 + 273,0) × 10 = 2955
wasser_kelvin_x10 = (45,3 + 273,0) × 10 = 3183
Schritt 2: In Bytes packen
raum_codiert = 2955 = 0x0B8B (12-Bit)
byte0 = 0x8B (untere 8 Bits)
byte1_low = 0x0B (obere 4 Bits)
wasser_codiert = 3183 = 0xC6F (12-Bit)
byte2 = 0xC6 (obere 8 Bits)
byte1_high = 0x0F (untere 4 Bits)
byte1 = (0x0F << 4) | 0x0B = 0xFB
Frame:
[0x8B] [0xFB] [0xC6] [0x00] [0x00] [0x00] [0x00] [0x00]
│ │ │
│ │ └─ Wasser obere 8 Bits (0xC6)
│ └─ Raum obere 4 Bits (0x0B) + Wasser untere 4 Bits (0x0F)
└─ Raum untere 8 Bits (0x8B)
Decodierungs-Beispiel
Gegebener Frame: [0x9F] [0xBB] [0xB7] [0x28] [0x12] [0x02] [0xF0] [0x0F]
Raumtemperatur:
raum_codiert = ((0xBB & 0x0F) << 8) | 0x9F
= (0x0B << 8) | 0x9F
= 0x0B9F = 2975
raum_celsius = 2975 / 10.0 - 273.0 = 24,5°C
Wassertemperatur:
wasser_codiert = (0xB7 << 4) | ((0xBB & 0xF0) >> 4)
= (0xB7 << 4) | 0x0B
= 0xB7B = 2939
wasser_celsius = 2939 / 10.0 - 273.0 = 20,9°C
Heater Info 2 (0x22)
Meldet Stromversorgungsstatus und Boilerzustand.
Frame-Struktur
| Byte | 0 | 1 | 2 | 3-7 |
|---|---|---|---|---|
| Inhalt | Spannung | System-Flags | Boiler-Zustand | Reserviert |
Byte 0: Spannung
Codierung: Spannung × 100mV
Beispiel:
0x84= 132 → 13,2V0x85= 133 → 13,3V0x77= 119 → 11,9V
Byte 1: System-Flags
| Bit | Funktion | Werte |
|---|---|---|
| 5 | 230V AC-Versorgung | 0 = Nicht vorhanden, 1 = Vorhanden |
| 6 | AC-Auto-Modus | Statusindikator |
| 7 | Pumpe läuft | 0 = Aus, 1 = Läuft |
| 0-4 | Reserviert | Verschiedene Statusbits |
Gängige Werte:
0x20: 230V vorhanden, Pumpe aus0x60: 230V vorhanden, zusätzliches Flag gesetzt0x70: 230V vorhanden, Pumpe läuft0x30: 230V vorhanden, anderer Status
Byte 2: Boiler-Zustand
| Code | Zustand | Beschreibung |
|---|---|---|
0x10 | Eco erreicht | Wasser auf Eco-Temperatur (~40°C) |
0x11 | Eco heizend | Aktiv auf Eco heizend |
0x30 | Hot erreicht | Wasser auf Hot-Temperatur (~60°C) |
0x31 | Hot heizend | Aktiv auf Hot heizend |
0x04 | Fehler/Sonstiges | Alternativer Statuscode |
0x05 | Fehler/Sonstiges | Alternativer Statuscode |
Beispiel-Frames
13,2V, 230V vorhanden, Eco-Temperatur erreicht:
[0x84] [0x60] [0x10] [0x05] [0xFF] [0xFF] [0xFF] [0xFF]
11,9V, 230V vorhanden, Pumpe läuft, Hot-Wasser aktiv:
[0x77] [0x70] [0x31] [0x05] [0xFF] [0xFF] [0xFF] [0xFF]
13,3V, 230V vorhanden, Heizung inaktiv:
[0x85] [0x20] [0x10] [0x05] [0xFF] [0xFF] [0xFF] [0xFF]
Aircon Command (0x17)
Steuert Klimaanlagen am TIN-Bus.
Frame-Struktur
| Byte | 0-7 |
|---|---|
| Inhalt | AC-Steuerungsdaten |
Hinweis: Das genaue Format für die AC-Steuerung erfordert weitere Analyse. Das Signal wird für Truma Aventa- und Saphir-Klimaanlagen verwendet.
Vollständiges Steuersequenz-Beispiel
Szenario: Kalter Morgenstart
Schritt 1: Master sendet Heater Command (0x20)
Ziel: Raum 22°C, Wasser Eco, nur Kraftstoff, Comfort-Lüfter
[0x86] [0x2B] [0xC3] [0xFA] [0x00] [0xB1] [0xE0] [0x0F]
Schritt 2: Heizgerät antwortet mit Info 1 (0x21)
Aktuell: Raum 15,5°C, Wasser 12,0°C (Kaltstart)
[0x5A] [0xAB] [0xBC] [0x3C] [0x12] [0x01] [0xF0] [0x0F]
Schritt 3: Heizgerät antwortet mit Info 2 (0x22)
Spannung: 13,2V, 230V vorhanden, Eco-Heizung aktiv
[0x84] [0x60] [0x11] [0x05] [0xFF] [0xFF] [0xFF] [0xFF]
Schritt 4: Nach 30 Minuten, Info 1-Aktualisierung
Aktuell: Raum 21,5°C, Wasser 39,5°C (nähert sich Ziel)
[0x7A] [0xBB] [0xC3] [0x3C] [0x12] [0x01] [0xF0] [0x0F]
Schritt 5: Ziel erreicht, Info 2-Aktualisierung
Spannung: 13,2V, 230V vorhanden, Eco-Temperatur erreicht
[0x84] [0x60] [0x10] [0x05] [0xFF] [0xFF] [0xFF] [0xFF]
Implementierungshinweise
Temperaturcodierung
Raumtemperatur (Byte 0): Verwendet die Formel (220 + (temp - 5) * 10) % 256, wobei temp in Celsius (5-30°C) ist. Sonderfall: 0xAA = Aus.
Telemetrie-Temperaturen (Frame 0x21): Codiert als 12-Bit-Werte, die Kelvin × 10 darstellen, gepackt in Bytes.
Vorteile gegenüber Legacy TIN
- Einzelner Frame: Alle Parameter in einem Frame (0x20) vs. 5 separate Frames
- Effizient: Reduzierter Bus-Verkehr und einfachere Zustandsverwaltung
- Atomare Updates: Alle Parameter werden gleichzeitig aktualisiert
- Moderne Funktionen: Bessere Unterstützung für Mix-Modus, detaillierte Statusmeldungen
Migration von Legacy TIN
Bei Unterstützung beider Protokolle:
Erkennung: Produktidentifikation zur Bestimmung der Gerätegeneration verwenden
- Funktions-ID
0x0301oder0x0310→ Legacy TIN - Funktions-ID
0x0340oder0x0320→ Neues TIN
- Funktions-ID
Abstraktionsschicht: Einheitliche API erstellen, die auf entsprechendes Protokoll abbildet:
trait HeaterControl { fn set_room_temp(&mut self, celsius: u8); fn set_water_temp(&mut self, level: WaterLevel); fn set_fuel_enabled(&mut self, enabled: bool); fn set_electro_power(&mut self, watts: u16); fn set_fan_level(&mut self, level: FanLevel); }Frame-Generierung: High-Level-Befehle in protokollspezifische Frames konvertieren
Referenzen
- TIN-Protokollübersicht - Allgemeine TIN-Protokollinformationen
- Legacy TIN-Protokoll - Legacy Protokollspezifikation
- Implementierung:
womonet-drivers/src/tin/protocol/tinnew/ - Testdaten:
truma-driver/logs_new.md
