diff --git a/.gitignore b/.gitignore index 9cd85a451..a99e551a2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,7 @@ .pio .clang_complete .gcc-flags.json -platformio.ini lib/readme.txt -.travis.yml # web stuff compiled src/websrc/css/required.css diff --git a/CHANGELOG.md b/CHANGELOG.md index 29a747b4d..399e29686 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.9.1] 2019-10-05 + +### Added + +- Support for multiple Heating Circuits - https://github.com/proddy/EMS-ESP/issues/162 +- new `mqttlog` command also shows which MQTT topics it is subscribed too +- Optimized event log loading in web and added integrity checks on all config and log files during boot +- `autodetect quick` +- `log_events` option, now optional to save the log events to SPIFFS + +### Fixed + +- fixed zero values (0.0) for setpoint temperature with the RC35 thermostat when in Auto mode - https://github.com/proddy/EMS-ESP/issues/180 +- added check for corrupted event log, which could happen due to SPIFFS writing while UART is active +- made Junkers work again (broke in 1.9.0) + +### Changed + +- Web login password is now mandatory +- Faster detection of EMS devices on bus by using the 0x07 telegram instead of the brute-force scan +- Fixes to the default HA climate component .yaml file to support latest Home Assistance ('heat' added) +- Update documentation in Wiki on MQTT and troubleshooting +- Slowed down firmware upload via the Web to prevent users rebooting too early +- Change way WiFi is intialized to prevent dual AP and Client + +### Removed + +- Removed `heating_circuit` config setting +- Removed showing the JSON config files when Saving from the Web + ## [1.9.0] 2019-09-01 ### Changed @@ -57,7 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - HeatPump support (e.g. the Nefit Enviline) - new device: Buderus MM50 Mixer - new devices: Junkers FW100 and ISM1 (thanks Vuego123) -- Improved Tx logic to support EMS, EMS+ and Heatronics (thanks kwertie01, susisstrolch, philrich) +- Improved Tx logic to support EMS, EMS+ and Heatronic 3 (thanks kwertie01, susisstrolch, philrich) - MQTT heartbeat ### Fixed diff --git a/doc/ems references/HT3-Bus_Telegramme.html b/doc/ems references/HT3-Bus_Telegramme.html new file mode 100644 index 000000000..1a019762c --- /dev/null +++ b/doc/ems references/HT3-Bus_Telegramme.html @@ -0,0 +1,7862 @@ + + + + + + + + + + + + + + + + + +
+

+

Übersicht

+ Telegramm Übersicht
+ ID 2
+ ID 7
+ ID 6
+ ID 190
+ ID 24
+ ID 25
+ ID 188
+ ID 27
+ ID 51
+ ID 52
+ ID 467...468
+ ID 26
+ ID 268
+ ID 296
+ ID 357...366
+ ID 367...376
+ ID 377...386
+ ID 677...684
+ ID 259
+ ID 260
+ ID 866
+ ID 868
+ ID 873
+ ID 874
+ ID 910
+ ID 913
+ ID 357_366_14_Modem
+ ID 377_387_4_Modem
+ ID 357...366_1x_Modem
+ ID 377...386_x_Modem
+ +

+
+

Tabelle 1: Telegramm Übersicht

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme







Datum:14.10.2016


Version:0.2.0







Message-IDTelegramm(hex)BeschreibungSource-Werte (hex)Bemerkung



(SO)
2SO TT 02 xySoftware-Version / Busteilnehmer88TT = <Target-/Token-Nr>
7SO 00 07 xySteuerung: EMS Token Status88
6SO 00 06 xyDatum / Zeit90 | 98Mit 14 und 17 Bytes Länge
190TT 00 BE xyErrorCode / DisplayCode von Target
TT = <Target-/Token-Nr>
24SO 00 18 xyHeizgerät: Kesseldaten88Mit 31 und 33 Bytes Länge
25SO 00 19 xyHeizgerät: Heizungsdaten88
188SO 00 BC xyHeizgerät: Hybrid (Wärmepumpe)

27SO 00 1B xySollwert Warmwasser90
51SO 00 33 xyWarmwasser: Daten von Steuerung88
52SO 00 34 xyWarmwasser: Daten von Steuerung | IPM88 | Ax (x:=0...7)Mit 22,23 und 25 Bytes Länge
467...468SO 00 FF xy 00 D3...D4Betriebsart WW-System90
26SO 08 1A xyHeizkreis: Systemwerte90
268SO 00 FF xy 00 0CHeizkreis: von IPM1/IPM2 für MischerAx (x:=0...7)
296SO 00 FF xy 00 28Heizkreis: Fehlermeldungen90
357...366SO 00 FF xy 00 65...6EHeizkreis: Bauart190
367...376SO 00 FF xy 00 6F...78Heizkreis: Temperaturniveau90 | 9x (x:=8...F)
377...386SO 00 FF xy 00 79...82Heizkreis: Bauart290
677...684SO 00 FF xy 01 A5...ACHeizkreis: Systemwerte90 | 98Cxyz-Controller (z.B. CW100)
259SO 00 FF xy 00 03Solar: Solardaten von ISM1B0
260SO 00 FF xy 00 04Solar: Solardaten von ISM2B0Mit 24 und 35 Bytes Länge
866SO 00 FF xy 02 62Solar: Solardaten von MS100B0EMS2-Bus
868SO 00 FF xy 02 64Solar: Solardaten von MS100B0EMS2-Bus
873SO 00 FF xy 02 69Solar: Solardaten von MS100B0EMS2-Bus
874SO 00 FF xy 02 6ASolar: Solardaten von MS100B0EMS2-Bus
910SO 00 FF xy 02 8ESolar: Solardaten von MS100B0EMS2-Bus
913SO 00 FF xy 02 91Solar: Solardaten von MS100B0EMS2-Bus
357_14...366_14SO TA FF 0E 00 65...6EModem-CMD: Betriebsart setzen8D | C8TA = <Target-Nr>
377_4 ...386_4SO TA FF 04 00 79...82Modem-CMD: Betriebsart setzen8D | C8TA = <Target-Nr>
357_17...366_17SO TA FF 11 00 65...6EModem-CMD: Temp-Niveau setzen8D | C8TA = <Target-Nr>
377_7 ...386_7SO TA FF 07 00 79...82Modem-CMD: Temp-Niveau setzen8D | C8TA = <Target-Nr>





1: ( Hi-Byte * 256 + Lo-Byte ) / 10
Calculation-Type: 1
2: ( Byte3 * 65536 + Byte2 * 256 + Byte1 )
Calculation-Type: 2
3: ( Byte4 * 1048576 + Byte3 * 65536 + Byte2 * 256 + Byte1 )
Calculation-Type: 3
4: ( Type 3 ) / 10
Calculation-Type: 4
5: ( Type 3 ) / 1000
Calculation-Type: 5
+ +
+

Tabelle 2: ID 2

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme



Message-ID: 2_x_0

ByteWerte (Hex)BemerkungBedeutung / IDBeispiel (Hex)

16Byte




Telegramm: Software-Version / Busteilnehmer

0SO
Source88
1TT<Token-/Target-Nr> (Geräteadr. Ungleich 0)Target18
202
2_x_002
3xy Telegramm-Offset (hier 0...9).
00
4xyErste Erkennung Busteilnehmer2_0_05F


- 00 = Variantenerkennung in Betrieb oder fehlerhaft



…..



- 5F = Heatronic III



- 64 = Schaltmodul IPM1



- 65 = Solarmodul ISM1



- 66 = Schaltmodul IPM2



- 67 = Solarmodul ISM2



- 67 = Solarmodul ISM2



- 69 = Witterungsgeführter Regler FW100



- 6A = Witterungsgeführter Regler FW200



- 6B = Raumtemperaturregler FR100



- 6C = Raumtemperaturregler FR110



- 6D = Fernbedienung FB 10



- 6E = Fernbedienung FB100



- 6F = Raumtemperaturregler FR10



…..



- BD = KM200



- BF = Raumtemperaturregler FR120



- C0 = Witterungsgefuehrter Regler FW120



…..

5xySoftware-Familie2_1_022
6xyVersion der Softwarefamilie2_2_004
7xyZweite Erkennung Busteilnehmern2_3_000
8xyKennzahl f. Grosse Änderung in HW- und SW2_4_000
9xyKennzahl f. Kleine Änderung in HW- und SW2_5_000
10xyDritte Erkennung Busteilnehmern2_6_000
11xyKennzahl f. Kleine Änderung in HW- und SW2_7_000
12xyKennzahl f. Grosse Änderung in HW- und SW2_8_000
13xyMarkenidentifizierung2_9_000


- 00 = keine Markenerkennung



- 01 = Bosch



- 02 = Junkers



- 03 = Buderus



…..

14<CRC>CRC
63
15<Ende>Ende
00
+ +
+

Tabelle 3: ID 7

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID: 7_x_y
ByteWerte (Hex)BemerkungBedeutung / ID

21Byte



EMS Token Status
0SO
Source
100
Target
207
7_x_y
3xy Telegramm-Offset (hier 0...14).
4Bit0...Bit7EMS Token Status 8: EMS Master 7_0_0 bis


- EMS Token Status 9 … 157_0_7
5Bit0...Bit7EMS Token Status 16 … 23 7_1_0 bis



7_1_7
6Bit0...Bit7Busadresse 24 vorhanden7_2_0 bis


- EMS Token Status 25 … 31 7_2_7
7Bit0...Bit7Busadresse 32:Mischerstellmotor im HK1 vorhanden7_3_0 bis


- EMS Token Status 33 … 397_3_7
8Bit0...Bit7Busadresse 40:Warmwassersystem im HK1 vorhanden7_4_0 bis


- EMS Token Status 41 … 477_4_7
9Bit0...Bit7Busadresse 48:Solarmodul vorhanden7_5_0 bis


- EMS Token Status 49 … 557_5_7
10Bit0...Bit7Busadresse 56:Fernbedienung f. HK1 vorhanden7_6_0 bis


- EMS Token Status 57 … 637_6_7
11Bit0...Bit7Busadresse 64:Temperaturfühler im HK1 vorhanden7_7_0 bis


- EMS Token Status 65 … 717_7_7
12Bit0...Bit7Status für Busadresse 72...797_8_0 bis



7_8_7
13Bit0...Bit7EMS Token Status 80 … 877_9_0 bis



7_9_7
14Bit0...Bit7EMS Token Status 88 … 957_10_0 bis



7_10_7
15Bit0...Bit7EMS Token Status 96 … 1037_11_0 bis



7_11_7
16Bit0...Bit7EMS Token Status 104 … 1117_12_0 bis



7_12_7
17Bit0...Bit7EMS Token Status 112 … 119 (Cascaded EMS)7_13_0 bis



7_13_7
18Bit0...Bit7EMS Token Status 120 … 127 (Cascaded EMS)7_14_0 bis



7_14_7
19<CRC>CRC
20<Ende>Ende Marker
+ +
+

Tabelle 4: ID 6

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme



Message-ID:6_x_y
ByteWerte (Hex)BemerkungBedeutung / ID

14Byte 17Byte




Datum/Zeit – Telegramm
090 | 9890 | 98Source :=90h oder :=98hSource
10000
Target
20606
6_x_y
3xyxy Telegramm-Offset (hier 0...6|10).
4xyxyJahr (Wert + 2000)dez.6_0_0
5xyxyMonat (01 … 12)dez.6_1_0
6xyxyStunden (00 … 23)dez.6_2_0
7xyxyTag (01 … 31)dez.6_3_0
8xyxyMinute (00 … 59)dez.6_4_0
9xyxySekunde (00 … 59)dez.6_5_0
10xyxyWochentag6_6_0



01=Montag; 02=Dienstag;... für Fxyz – Regler



00=Montag; 01=Dienstag;... für Cxyz – Regler
11Bit0...Bit7Bit0...Bit7Uhrstatus

Bit0Bit0- Sommerzeit6_7_0

Bit1Bit1- Funkempfang vorhanden6_7_1

Bit2Bit2- Funksignal vorhanden6_7_2

Bit3...Bit7Bit3...Bit7- Immer 0
12<CRC>xyToken-Adresse des aktuellen RTC-Owner6_8_0
13<Ende>xyAutomatische Sommer/Winter Umschaltung6_9_0
14
xyRTC Benutzer Kalibierungswert6_10_0
15
<CRC>

16
<Ende>

+ +
+

Tabelle 5: ID 190

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID: 190_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

11Byte



ErrorCode von Target-/Token
0TTTarget-/Token NummerSource
100- 00 = An AlleTarget
2BE
190_x_0
300Immer 0
4xyBus-Adresse des Fehlercodes190_0_0
5Hi-ByteDisplaycode190_1_0
6Lo-Byte
7Hi-ByteCause Code190_3_0
8Lo-Byte
9<CRC>CRC
10<Ende>Ende Marker
+ +
+

Tabelle 6: ID 24

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme



Message-ID:24_x_y
ByteWerte (Hex)BemerkungBedeutung / ID

31Byte 33Byte




Kessel-Telegramm: Heizgerät
08888
Source
10000
Target
21818
24_x_y
3xyxy Telegramm-Offset (hier 0...25).
4xyxyVorlauf Soll-Temperatur24_0_0
5Hi-ByteHi-ByteVorlauf Ist-Temperatur24_1_0
6Lo-ByteLo-Byte
7xyxyKessel maximale Leistung (76/84/100; 100)%24_3_0
80-1000-100Aktuelle Brennerleistung in %24_4_0
9Bit0...Bit7BitfeldBetriebsmode

Bit0Bit1- Heizungs-Mode24_5_0

Bit1Bit2- Warmwasser-Mode24_5_1

Bit2Bit3:=0- Status Servicebetrieb24_5_2

Bit3Bit4- Brennerflamme an24_5_3

Bit4Bit5:=0- Aufheizphase des Wärmeerzeugers24_5_4

Bit5Bit6:=0- Verriegelnder Fehler24_5_5

Bit6Bit7:=0- Blockierender Fehler24_5_6

Bit7Bit8:=0- Status Wartungsanforderung24_5_7
10Bit0...Bit7Bit0...Bit7Status Heizbetrieb

Bit0Bit0- Heizbetrieb im Bussystem24_6_0

Bit1Bit1- Wärmeanforderung (durch Schalter)24_6_1

Bit2Bit2- Wärmeanforderung bei Betriebsart: Frost24_6_2

Bit3Bit3- Wärmeanforderung im WW-Betrieb bei Betriebsart: Frost24_6_3

Bit4Bit4- Interne Wärmeanforderung bei WW24_6_4

Bit5Bit5- Wärmeanforderung f. WW-Erkennung im Bussystem24_6_5

Bit6Bit6- Wärmeanforderung24_6_6

Bit7Bit7- Wärmeanforderung im Testmodus24_6_7
11Bit0...Bit7Bit0...Bit7Betriebs-Status

Bit0Bit0- Brenner an (Relais-Signal erste Brennstufe)24_7_0

Bit1Bit1- Brenner an (Relais-Signal zweite Brennstufe)24_7_1

Bit2Bit2- Lüfter an (Relais-Signal f. Lüfter)24_7_2

Bit3Bit3- Zündung an (Relais-Signal f. Zündung)24_7_3

Bit4Bit4- Ölvorwärmer an (Relais-Signal f. Ölvorwärmer)24_7_4

Bit5Bit5- Heizungspumpe an (Relais-Signal f. HP)24_7_5

Bit6Bit6- 3-Wege-Ventil auf Speicherladung24_7_6

Bit7Bit7- Zirkulationspumpe an (Relais-Signal f. ZP)24_7_7
12Bit0...Bit7Bit0...Bit7Status 1

Bit0Bit0- Meldesignal Abgasklappe f. Freigabe Ölbrenner24_8_0

Bit1Bit1- Signal vom Luftdruckschalter24_8_1

Bit2Bit2- Signal vom Flüssiggasbrenner24_8_2

Bit3Bit3- Signal vom Gasdruckwächter24_8_3

Bit4Bit4- Signal vom externen Ein-/Aus-Schalter24_8_4

Bit5Bit5- Digitales Eingangssignal24_8_5

Bit6Bit6- Signal vom Sicherheitstemperaturbegrenzer (TB)24_8_6

Bit7Bit7- Signal vom Raumthermostat24_8_7
13Hi-ByteHi-ByteWW-Temperatur Speicherfühler124_9_0
14Lo-ByteLo-Byte- (0x8300 := Nicht vorhanden)
15Hi-ByteHi-ByteWW-Temperatur Speicherfühler224_11_0
16Lo-ByteLo-Byte- (0x8000 | 0x7D00 := Nicht vorhanden)
17Hi-ByteHi-ByteTemperatur Kessel-Rücklauf24_13_0
18Lo-ByteLo-Byte- (0x8000 | 0x7D00 := Nicht vorhanden)
19Hi-ByteHi-ByteIonisationsstrom24_15_0
20Lo-ByteLo-Byte
21FFFFAnlagendruck am Wärmeerzeuger24_17_0



- (FF := ungültig)
22Hi-ByteHi-ByteDisplaycode24_18_0
23Lo-ByteLo-Byte
24Hi-ByteHi-ByteCause Code24_20_0
25Lo-ByteLo-Byte
2600FFWarmwasserdurchfluss-Menge24_22_0



- (FF := ungültig)
27Bit0...Bit7Bit0...Bit7Status 2

Bit0Bit0- Status Speicherlade-Pumpe (SP)24_23_0

Bit1Bit1- Flüssiggasventil an24_23_1

Bit2Bit2- Status Gaswärmepumpe24_23_2

Bit3Bit3- Status d. Relais im Schaltmodul UM1024_23_3

Bit4Bit4- Zirkulationspumpe an (Relais-Signal f. ZP)24_23_4

Bit5Bit5- Status Brenner Relais24_23_5

Bit6Bit6- FB reservierte Bit24_23_6

Bit7Bit7- FB reservierte Bit24_23_7
28Bit0...Bit7Bit0...Bit7Status 3

Bit0Bit0- Status der Füllfunktion 24_24_0

Bit1Bit1- Status Schaltmodul UM1024_24_1

Bit2Bit2- UM10 Signal für Brenner-Blockierung24_24_2

Bit3Bit3- Brennerfreigabe durch Schaltmodul24_24_3

Bit4Bit4- Status Brenneranlauf im Schaltmodul24_24_4

Bit5Bit5- Heizbetrieb blockiert bei Heatronic III24_24_5

Bit6Bit6- STB – Test aktiv24_24_6

Bit7Bit7- Tastensperre ein24_24_7
29<CRC>Hi-ByteCRC | Hi-Byte - Ansauglufttemperaturxy | 24_25_0
30<Ende>Lo-ByteEnde | Lo-Byte - Ansauglufttemperatur
31<CRC> -– | CRC
32<Ende> –- | Ende
+ +
+

Tabelle 7: ID 25

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:25_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

33Byte



Kessel-Telegramm: Heizgerät
088
Source
100
Target
219
25_x_0
3xy Telegramm-Offset (hier 0...25).
4Hi-ByteAußentemperatur25_0_0
5Lo-Byte
6Hi-ByteMaximale Temperatur25_2_0
7Lo-Byte- 0x8000 = Sensorunterbrechung / Fühler nicht vorhanden


- 0x7FFF = Sensorkurzschluss
8Hi-ByteAbgastemperatur25_4_0
9Lo-Byte- 0x8000 = Sensorunterbrechung / Fühler nicht vorhanden


- 0x7FFF = Sensorkurzschluss
10Hi-ByteGasdruck / Luftdruck25_6_0
11Lo-Byte- 0xFFFF = Sensorunterbrechung / Fühler nicht vorhanden
12xyTaktsperre im Zweipunkt Betrieb25_8_0
13xyModulationsbereich Heizungspumpe (HP)25_9_0
14Byte 3Brennerstarts Total (für Warmwasser und Heizung)25_10_0
15Byte 2 „ ( Calculation-Type: 2 )
16Byte 1
17Byte 3Betriebsminuten Brenner Total (für Warmwasser und Heizung)25_13_0
18Byte 2 „ ( Calculation-Type: 2 )
19Byte 1
20Byte 3Betriebszeit f. Zweite Brennerstufe25_16_0
21Byte 2 „ ( Calculation-Type: 2 )
22Byte 1
23Byte 3Betriebsminuten Brenner (nur Heizung)25_19_0
24Byte 2 „ ( Calculation-Type: 2 )
25Byte 1
26Byte 3Brennerstarts (nur Heizung)25_22_0
27Byte 2 „ ( Calculation-Type: 2 )
28Byte 1
29Hi-ByteTemperatur an hydraulischer Weiche25_25_0
30Lo-Byte- 0x8000 = Sensorunterbrechung / Fühler nicht vorhanden


- 0x7FFF = Sensorkurzschluss
31<CRC>CRC
32<Ende>Ende Marker
+ +
+

Tabelle 8: ID 188

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:188_x_y
ByteWerte (Hex)BemerkungBedeutung / ID






Kessel-Telegramm: Heizgerät
088
Source
100
Target
2BC
188_x_y
3xy Telegramm-Offset (hier 0...13).
4Hi-ByteTemperatur Puffer-Speicher oben188_0_0
5Lo-Byte
6Hi-ByteTemperatur Puffer-Speicher unten188_2_0
7Lo-Byte
8Hi-ByteTemperatur Vorlauf Verflüssiger188_4_0
9Lo-Byte
10Hi-ByteTemperatur Rücklauf Verflüssiger188_6_0
11Lo-Byte
12Bit0...Bit7Betriebs-Status1

Bit0- Wärmepumpe188_8_0

Bit1
188_8_1

Bit2
188_8_2

Bit3
188_8_3

Bit4- Status Abtaumöglichkeit an W-Pumpe188_8_4

Bit5
188_8_5

Bit6
188_8_6

Bit7
188_8_7
13Bit0...Bit7Betriebs-Status2

Bit0- Abtaufunktion an W-Pumpe188_9_0

Bit1- Status Verdichter188_9_1

Bit2- Fehlerstatus Wärmepumpe188_9_2

Bit3
188_9_3

Bit4
188_9_4

Bit5
188_9_5

Bit6
188_9_6

Bit7
188_9_7
14<CRC>CRC
15<Ende>Ende
+ +
+

Tabelle 9: ID 27

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:27_0_0
ByteWerte (Hex)BemerkungBedeutung / ID

7Byte



Telegramm: Solltemperatur WW-System
090 Source
100
Target
21B
27_x_0
300Immer 00
432Sollwert Warmwasser-Temperatur27_0_0
5<CRC>CRC
6<Ende>Ende Marker
+ +
+

Tabelle 10: ID 51

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID: 51_x_y
ByteWerte (Hex)BemerkungBedeutung / ID






Kessel-Telegramm: Warmwasser
088
Source
100
Target
233
51_x_y
3xy Telegramm-Offset (hier 0...12).
4xySoll-Temperatur Warmwasser51_0_0
5xy
51_1_0
6xySoll-Temperatur Warmwasser51_2_0
7xyTemperaturhysterese bei T-Soll51_3_0
8xy
51_4_0
9xy
51_5_0
10xy
51_6_0
11xy
51_7_0
12xy
51_8_0
13xy
51_9_0
14xy
51_10_0
15xy
51_11_0
16xy
51_12_0
17<CRC>

18<Ende>

+ +
+

Tabelle 11: ID 52

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme






Message-ID: 52_x_y
ByteWerte (Hex)
BemerkungBedeutung / ID

23Byte 22Byte 25Byte





Kessel-Telegramm: Warmwasser
0888888
Source
1000000
Target
2343434
52_x_y
3xyxyxy Telegramm-Offset (hier 0...17).
4xyxyxySoll-Temperatur Warmwasser52_0_0
5Hi-ByteHi-ByteHi-ByteIst-Temperatur Warmwasser52_1_0
6Lo-ByteLo-ByteLo-Byte- 0x8000 = Sensorunterbrechung / Fühler nicht vorhanden




- 0x7FFF = Sensorkurzschluss
7Hi-ByteHi-ByteHi-ByteIst-Temperatur im Warmwasser - Speicher52_3_0
8Lo-ByteLo-ByteLo-Byte- 0x8000 = Sensorunterbrechung / Fühler nicht vorhanden




- 0x7FFF = Sensorkurzschluss
9Bit0...Bit7Bit0...Bit7Bit0...Bit7Warmwasser-Status

Bit0Bit0Bit0- WW-Bereitung im Normalbetrieb52_5_0

Bit1Bit1Bit1- Einmalige Speicher-Ladung52_5_1

Bit2Bit2Bit2- Thermische Desinfektion52_5_2

Bit3Bit3Bit3- Speicherladung im WW-System52_5_3

Bit4Bit4Bit4- Speicherladung im Nachwärmsystem52_5_4

Bit5Bit5Bit5- Erreichter Sollwert Warmwasser-Temperatur52_5_5

Bit6Bit6Bit6- Warmwasserbetrieb52_5_6

Bit7Bit7Bit7- Status f. Art der Warmwasserbereitung52_5_7




-- 0 = Warmwasserteilvorrang




-- 1 = Warmwasservorrang
10Bit0...Bit7Bit0...Bit7Bit0...Bit7WW-Fehlersignale

Bit0Bit0Bit0- WW-Temperaturfühler 1 defekt52_6_0

Bit1Bit1Bit1- WW-Temperaturfühler 2 defekt52_6_1

Bit2Bit2Bit2- WW-System wird nicht aufgeheizt52_6_2

Bit3Bit3Bit3- Thermische Desinfektion ist nicht in Betrieb52_6_3

Bit4Bit4Bit4- WW ist nicht blockiert52_6_4

Bit5...Bit7Bit5...Bit7Bit5...Bit7- Immer 052_6_5 bis





52_6_7
11Bit0...Bit7Bit0...Bit7Bit0...Bit7Zirkulationspumpen-Status

Bit0Bit0Bit0- Zirkulationspumpe (ZP) im Normalbetrieb52_7_0

Bit1Bit1Bit1- Zirkulationspumpe (ZP) an bei einmaliger Speicherladung52_7_1

Bit2Bit2Bit2- Zirkulationspumpe (ZP) an52_7_2

Bit3Bit3Bit3- Ansteuersignal f. Zirkulationspumpe (ZP)52_7_3

Bit4...Bit7Bit4...Bit7Bit4...Bit7- Immer 0
120...40...40...4Bauart des Warmwassersystems52_8_0




- 0 = ohne Warmwasserbereitung




- 1 = nach Durchlaufprinzip




- 2 = Druckloser Speicher




- 3 = Warmwasser-Speicherprinzip




- 4 = Schichtlade-Speicher
13xyxyxyAktuelle Wasserduchflussmenge52_9_0
14Byte 3Byte 3Byte 3Betriebszeit Warmwasser-Erzeugung (Minuten)52_10_0
15Byte 2Byte 2Byte 2
16Byte 1Byte 1Byte 1
17Byte 3Byte 3Byte 3Anzahl Brennerstarts für Warmwassererzeugung52_13_0
18Byte 2Byte 2Byte 2
19Byte 1Byte 1Byte 1
20xy<CRC>xyModulationsbereich ZP im WW-System 152_16_0
21<CRC><Ende>Hi-ByteHi-Byte Warmwasser Eingangstemperatur52_17_0
22<Ende>--Lo-ByteLo-Byte Warmwasser Eingangstemperatur




- 0x8000 = Sensorunterbrechung / Fühler nicht vorhanden




- 0x7FFF = Sensorkurzschluss
23

<CRC>

24

<Ende>

+ +
+

Tabelle 12: ID 467...468

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:467_x_0 bis 468_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

11Byte



Telegramm: Betriebsart WW-System
090 Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
400Immer 00EMS Type(H)
5D3 / D4WW-System


- D3=WW-System1467_0_0


- D4=WW-System2468_0_0
6xyBetriebsart Warmwasser-System


- 0=Automatikbetrieb f. WW-Speicher


- 1=Automatikbetrieb b. Kombigerät aktiv


- 2=Automatikbetrieb b. Kombigerät ausgeschaltet


- 3=Automatikbetrieb i. Urlaubsmodus f. WW-Speicher


- 4=Urlaubsfunktion eingeschaltet a. Kombigerät


- 5=Urlaubsfunktion ausgeschaltet a. Kombigerät


- 6=Fest eingestellte Speichertemperatur im Urlaubsprogramm


- 7=Thermische Desinfektion f. WW-Speicher


- 8=Warmwasser sofort


- 9=Estrichtrocknung in Betrieb oder angehalten
7xyWert f. Temperaturreduzierung bei solarer Unterstuetzung467_1_0 bis 468_1_0
8xyStatus der letzten thermischen Desinfektion467_2_0 bis 468_2_0


- 0=Abgeschlossen


- 1=In Betrieb


- 2=Abgebrochen
9<CRC>CRC
10<Ende>Ende Marker
+ +
+

Tabelle 13: ID 26

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme



Message-ID:26_x_0

ByteWerte (Hex)BemerkungBedeutung / IDBeispiel (Hex)

11Byte




Telegramm: Heizkreis Systemwerte

090
Source
108Target = SteuerungTarget
21AImmer 1A26_x_0
3xy Telegramm-Offset (hier 0...4).

426Sollwert f. Vorlauftemperatur im Heizkreis26_0_0
564Maximale Leistung des Wärmeerzeugers26_1_0
664Sollwert f. Drehzahl der Umwälzpumpe26_2_0
70 / FFStatus f. Aufheizen mit hohem Wirkungsgrad26_3_0
83Betriebsart f. Umwälzpumpe im Energiesparmodus26_4_0
9<CRC>CRC

10<Ende>Ende Marker

+ +
+

Tabelle 14: ID 268

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:268_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

14Byte



IPM – Telegramm (Schaltmodul)
0A0...A7
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
400Immer 00EMS Type(H)
50CImmer 0CEMS Type(L)
60...2Bauart des Heizkreises (Mischer ja/nein)


- 0=Nicht vorhanden


- 1=Ungemischter Heizkreis268_0_0


- 2=Gemischter Heizkreis268_0_1
70...1Status Heizungspumpe im Heizkreis268_1_0


- 0=Pumpe aus


- 1=Pumpe Ein
8xyMischer Position (Prozentwert)268_2_0
9Hi-ByteVorlauftemperatur 'Ist' für gemischten Heizkreis268_3_0
10Lo-Byte
11xySollwert Vorlauftemperatur (Grad)268_5_0
12<CRC>CRC
13<Ende>Ende Marker
+ +
+

Tabelle 15: ID 296

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:296_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

32Byte



Telegramm: Heizkreis Fehlermeldungen
090
Source
100
Target
2FF
EMS Marker
3xyOffset auf nächste FehlermeldungEMS Offset
400Immer 00EMS Type(H)
528FehlerEMS Type(L)
6xy1Fehler1: Display-Code1296_0_0
7xy2Fehler1: Display-Code2296_1_0
8Hi-ByteFehler1: Fehlercode296_2_0
9Lo-Byte

10xyFehler1: Jahr (+2000)296_4_0
11xyFehler1: Monat296_5_0
12xyFehler1: Stunde296_6_0
13xyFehler1: Tag296_7_0
14xyFehler1: Minute296_8_0
15Hi-ByteFehler1: Minute (Reserviert)296_9_0
16Lo-Byte

17xyFehler1: Busadresse296_11_0
18xy1Fehler2: Display-Code1296_12_0
19xy2Fehler2: Display-Code2296_13_0
20Hi-ByteFehler2: Fehlercode296_14_0
21Lo-Byte

22xyFehler2: Jahr (+2000)296_16_0
23xyFehler2: Monat296_17_0
24xyFehler2: Stunde296_18_0
25xyFehler2: Tag296_19_0
26xyFehler2: Minute296_20_0
27Hi-ByteFehler2: Minute (Reserviert)296_21_0
28Lo-Byte

29xyFehler2: Busadresse296_23_0
30<CRC>CRC
31<Ende>Ende Marker
+ +
+

Tabelle 16: ID 357...366

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:357_x_0 bis 366_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

29Byte



Telegramm: Heizkreis Steuerung


(Bauart des Heizkreises)
090
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
400Immer 00EMS Type(H)
565...6EHeizkreis xEMS Type(L)

65 65=Heizkreis1357_0_0

66 66=Heizkreis2358_0_0

67 67=Heizkreis3359_0_0

68 68=Heizkreis4360_0_0

69 69=Heizkreis5361_0_0

6A 6A=Heizkreis6362_0_0

6B 6B=Heizkreis7363_0_0

6C 6C=Heizkreis8364_0_0

6D 6D=Heizkreis9365_0_0

6E 6E=Heizkreis10366_0_0
60...3Bauart-Werte357_1_0 bis


- 0=Nicht vorhanden366_1_0


- 1=Ungemischter Heizkreis ohne Schaltmodul IPM


- 2=Ungemischter Heizkreis mit Schaltmodul IPM


- 3=Gemischter Heizkreis
70...2Fernbedienung für Heizkreis x


- 0=Nicht vorhanden


- 1=Fernbedienung FB 10


- 2=Fernbedienung FB100
80...4Bauart des Heizkreis x


- 0=nicht definiert357_2_0 bis


- 1=Fußpunkt/Endpunkt366_2_0


- 2=Radiatoren


- 3=Konvektoren


- 4=Fußbodenheizung
9z.B. 19Fußpunkt für Heizkurve (in Grad)357_3_0 bis



366_3_0
10z.B. 30Endpunkt für Heizkurve (in Grad)357_4_0 bis



366_4_0
11z.B. 50Maximale Vorlauftemperatur (in Grad) für Heizkreis x357_5_0 bis



366_5_0
12
Raumeinfluss-Faktor (%) im Heizkreis x357_6_0 bis



366_6_0
130...2Raumeinfluss im Heizkreis x bei Betriebsart357_7_0 bis


- 0=nicht definiert366_7_0


- 1=Normalbetrieb / Sparbetrieb / Frostschutzbetrieb


- 2=Sparbetrieb / Frostschutzbetrieb
14
Einstellung dauerhafte Raumtemperatur-Korrektur im Heizkreis x357_8_0 bis



366_8_0
150...3Betriebsart Raumtemperaturfühler für Heizkreis x357_9_0 bis


- 0=nicht definiert366_9_0


- 1=Externer Temperaturfühler


- 2=Interner Temperaturfühler


- 3=Temperatur im Sparmodus




160/FFStatus für Temperaturniveau Frost357_10_0 bis


- 0 = Aus366_10_0


- FF = Ein
17z.B. 2BAbschaltung (Außentemperaturgesteuert) von Heizkreis x357_11_0 bis


- (in 0.5 Grad Schritten)366_11_0
18
Frostgrenztemperatur für Heizkreis x357_12_0 bis


- (in 0.5 Grad Schritten)366_12_0
190...6Aktives Heizprogramm im Heizkreis x357_13_0 bis


- 0=nicht definiert366_13_0


- 1-6=Nummer des aktiven Heizprogramms


- (1:A; 2:=B;3:=C; …)
200....4Betriebsart für den Heizkreis x357_14_0 bis


- 0=nicht definiert366_14_0


- 1=Betrieb im Frostschutzmodus


- 2=Betrieb im Sparmodus


- 3=Betrieb im Normalmodus


- 4=Automatikbetrieb
21z.B. 14Temperaturniveau für Betriebsart Frost im Heizkreis x357_15_0 bis


- (in 0.5 Grad Schritten)366_15_0
22z.B. 28Temperaturniveau für Betriebsart Sparen im Heizkreis x357_16_0 bis


- (in 0.5 Grad Schritten)366_16_0
23z.B. 2BTemperaturniveau für Betriebsart Normal im Heizkreis x357_17_0 bis


- (in 0.5 Grad Schritten)366_17_0
240...3Aufheizgeschwindigkeit für Heizkreis x357_18_0 bis


- 0=nicht definiert366_18_0


- 1=Langsam


- 2=Normal


- 3=Schnell
250...4Urlaubsprogramm Betriebsart für Heizkreis x357_19_0 bis


- 0=nicht definiert366_19_0


- 1=Betrieb im Frostschutzmodus


- 2=Betrieb im Sparmodus


- 3=Betrieb im Normalmodus


- 4=Automatikbetrieb
26
Optimierungseinfluss für solare Unterstützung im Heizkreis x357_20_0 bis


- (in 1 Grad Schritten)366_20_0
27<CRC>CRC
28<Ende>Ende Marker
+ +
+

Tabelle 17: ID 367...376

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme






Message-ID:367_x_0 bis 376_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

17Byte 14Byte 9Byte





Telegramm: Heizkreis Steuerung




(Temperaturniveau für den Heizkreis)
090 | 9x90 | 9x90 | 9x (wobei: x:= 8...F)Source
1000000
Target
2FFFFFF
EMS Marker
3xyxyxy
EMS Offset
4000000Immer 00EMS Type(H)
56F...786F...786F...78Heizkreis-ZuordnungEMS Type(L)




6F=Heizkreis1367_0_0




70=Heizkreis2368_0_0




71=Heizkreis3369_0_0




72=Heizkreis4370_0_0




73=Heizkreis5371_0_0




74=Heizkreis6372_0_0




75=Heizkreis7373_0_0




76=Heizkreis8374_0_0




77=Heizkreis9375_0_0




78=Heizkreis10376_0_0
60...30...30...3Betriebsart Heizung:367_0_0 bis




- 0=nicht definiert376_0_0




- 1=Frost




- 2=Sparen




- 3=Heizen
70...50...5<CRC>Betriebsart Heizkreis | | CRC367_1_0 bis




- 0=nicht definiert376_1_0



- 1=dauernd



- 2=Automatikbetrieb



- 3=Urlaub



- 4=Estrichtrocknung im StandbyModus



- 5=Estrichtrocknung in Betrieb
8Hi-ByteHi-Byte<Ende>Soll-Temperatur (HK1 bis HK10) | | Ende Marker367_2_0 bis
9Lo-ByteLo-Byte376_2_0
10Hi-ByteHi-ByteIst-Temperatur (HK1 bis HK10 vom Regler)367_4_0 bis
11Lo-ByteLo-Byte376_4_0
12Hi-Byte<CRC>T-Raum FB10x | CRC367_6_0
13Lo-Byte<Ende>T-Raum FB10x | Ende Marker
1400 … 07Temperaturwert für solare Unterstützung der Vorlauftemperatur367_8_0
15<CRC>CRC
16<Ende>Ende Marker
+ +
+

Tabelle 18: ID 377...386

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:377_x_0 bis 386_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

19Byte



Telegramm: Heizkreis Steuerung
090 (Bauart des Heizkreises)Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
400Immer 00EMS Type(H)
579...82Heizkreis x KennungEMS Type(L)


79=Heizkreis1377_0_0


7A=Heizkreis2378_0_0


7B=Heizkreis3379_0_0


7C=Heizkreis4380_0_0


7D=Heizkreis5381_0_0


7E=Heizkreis6382_0_0


7F=Heizkreis7383_0_0


80=Heizkreis8384_0_0


81=Heizkreis9385_0_0


82=Heizkreis10386_0_0
60...3Bauart-Werte377_0_0 bis


- 0=Nicht vorhanden386_0_0


- 1=Ungemischter Heizkreis ohne Schaltmodul IPM


- 2=Ungemischter Heizkreis mit Schaltmodul IPM


- 3=Gemischter Heizkreis
7
Anpassungsfaktor im Heizkreis x377_1_0 bis



386_1_0
8
Verstärkungsfaktor im Heizkreis x377_2_0 bis



386_2_0
9
Maximale Vorlauftemperatur im Heizkreis x377_3_0 bis



386_3_0
100...4Betriebsart für Heizkreis x377_4_0 bis


- 0=nicht definiert386_4_0


- 1=Betrieb im Frostschutzmodus


- 2=Betrieb im Sparmodus


- 3=Betrieb im Normalmodus


- 4=Automatikbetrieb
11
Temperaturniveau bei Betriebsart Frost377_5_0 bis


- (in 0.5 Grad Schritten)386_5_0
12
Temperaturniveau bei Betriebsart Sparen377_6_0 bis


- (in 0.5 Grad Schritten)386_6_0
13
Temperaturniveau bei Betriebsart Normal377_7_0 bis


- (in 0.5 Grad Schritten)386_7_0
14
Urlaubsprogramm Betriebsart für Heizkreis x377_8_0 bis


- ( Werte wie bei Byte:10 Betriebsart Heizkreis)386_8_0
150/FFStatus Optimierungsfunktion im Heizkreis x377_9_0 bis


- 0 = Aus386_9_0


- FF = Ein
160...6Aktiviertes Heizprogramm377_10_0 bis


- 0=Nicht definiert386_10_0


- 1-6=Nummer des aktiven Heizprogramms


- (1=A; 2=B; 3=C; …)
17<CRC>CRC
18<Ende>Ende Marker
+ +
+

Tabelle 19: ID 677...684

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:677_x_0 bis 684_x_0
Byte
BemerkungBedeutung / ID






Telegramm: Heizkreis Steuerung


(Temperaturniveau für den Heizkreis)
090
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
401Immer 01EMS Type(H)
5A5...ACHeizkreis-ZuordnungEMS Type(L)


A5=Heizkreis1677_0_0


A6=Heizkreis2678_0_0


A7=Heizkreis3679_0_0


A8=Heizkreis4680_0_0


A9=Heizkreis5681_0_0


AA=Heizkreis6682_0_0


AB=Heizkreis7683_0_0


AC=Heizkreis8684_0_0
6Hi-ByteIst-Raumtemperatur (HK1 bis HK8)677_0_0 bis
7Lo-Byte684_0_0
8xyStatus Heizkreis6xy_2_0
9xy
6xy_3_0
10xy
6xy_4_0
11xy
6xy_5_0
12xySoll-Raumtemperatur (HK1 bis HK8)6xy_6_0
13xy
6xy_7_0
14Hi-Byte
6xy_8_0
15Lo-Byte
16xy
6xy_10_0
17xyTemperatur-Niveau6xy_11_0
18xy
6xy_12_0
19Hi-Byte
6xy_13_0
20Lo-Byte
21Hi-Byte
6xy_15_0
22Lo-Byte
23xy
6xy_17_0
24xy
6xy_18_0
25xy
6xy_19_0
26xy
6xy_20_0
27xyBetriebsstatus (HK1 bis HK8) {Auto / Manuell}6xy_21_0
28Hi-Byte
6xy_22_0
29Lo-Byte
30xy
6xy_24_0
31xy
6xy_25_0
32xy
6xy_26_0
33Hi-Byte
6xy_27_0
34Lo-Byte
35xy
6xy_29_0
36xy
6xy_30_0
37<CRC>CRC
38<Ende>Ende Marker
+ +
+

Tabelle 20: ID 259

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:259_x_0
ByteWerte (Hex)BemerkungBedeutung / ID

21Byte



ISM Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
400Immer 00EMS Type(H)
503Immer 03EMS Type(L)
6xyOptimierungsfaktor WW mit solarer Unterstützung259_0_0
7xyOptimierungsfaktor Heiz. mit solarer Unterstützung259_1_0
8Hi-ByteSolarertrag in der letzten Stunde (Wh)259_2_0
9Lo-Byte
10Hi-ByteSolarkollektor1 Temperatur T1259_4_0
11Lo-Byte
12Hi-ByteSolarspeicher Temperatur T2259_6_0
13Lo-Byte
14Bit0...Bit7Betriebsart Solarpumpe (1. Kollektorfeld)

Bit0- Solarpumpe (SP); 0=aus; 1=ein259_8_0

Bit1- Relaysignal Umwälzpumpe(PE) bei thermischer Desinfektion259_8_1

Bit2..Bit7- Immer 0
15Bit0...Bit7Solar Systemstatus

Bit0- Abschaltung 1.Kollektorfeld bei Stagnation259_9_0


-- 0 =Nein


-- 1 =Ja (5 Grad Hysterese)

Bit1- Status Temperatur bei thermischer Desinfektion259_9_1

Bit2- Status Solarspeicher259_9_2


-- 0 =Nicht voll geladen


-- 1 =Voll geladen (2 Grad Hysterese)

Bit3-8 Immer 0
16Byte 3Laufzeit Solarpumpe (Minuten)
17Byte 2 „ ( Calculation-Type: 2 )259_10_0
18Byte 1
19<CRC>CRC
20<Ende>Ende Marker
+ +
+

Tabelle 21: ID 260

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme



Message-ID:260_x_y
ByteWerte (Hex)
BemerkungBedeutung / ID

24Byte 35Byte




ISM Solar-Telegramm
0B0B0
Source
10000
Target
2FFFF
EMS Marker
3xyxy
EMS Offset
40000Immer 00EMS Type(H)
50404Immer 04EMS Type(L)
6Hi-Byte T3Hi-Byte T3Temperatur T3 im Pufferspeicher f. Rücklaufanhebung260_0_0
7Lo-Byte T3Lo-Byte T3
8Hi-ByteHi-ByteHeizungsrücklauftemperatur260_2_0
9Lo-ByteLo-Byte
10Hi-Byte T5Hi-Byte T5Temperatur T5 im Pufferspeicher (oben)260_4_0
11Lo-Byte T5Lo-Byte T5
12Hi-Byte T6Hi-Byte T6Temperatur T6 im Bereitschaftsspeicher (unten)260_6_0
13Lo-Byte T6Lo-Byte T6
14Hi-ByteHi-ByteTemperatur 2. Kollektorfeld260_8_0
15Lo-ByteLo-Byte
16Hi-ByteHi-ByteTemperatur TB im Pufferspeicher (oben)260_10_0
17Lo-ByteLo-Byte
18Hi-ByteHi-ByteTemperatur TC im Vorrang-/Nachrangspeicher260_12_0
19Lo-ByteLo-Byte
20Hi-ByteHi-ByteTemperatur am externen Wärmetauscher f. Solarsystem260_14_0
21Lo-ByteLo-Byte
22<CRC>Bit0...Bit7Status 1


Bit0- Betriebsart Ventil (DWU) f. Rücklaufanhebung260_16_0


Bit1- Relaisansteuerung f. Umwälzpumpe Umladesystem260_16_1


Bit2- Umwälzpumpe (PA) im 2. Kollektorfeld260_16_2


Bit3- Relaisansteuerung f. Umwälzpumpe (PB) Umladesystem260_16_3


Bit4- Betriebsart Umwälzpumpe (PC)/Umschaltventil260_16_4


Bit5- Betriebsart Umwälzpumpe (PD) im Sekundärkreis260_16_5


Bit6- Relaissignal bei Option F260_16_6


Bit7- unbenutzt260_16_7
23<Ende>Bit0...Bit7Status 2


Bit0- Ansteuerung Ventil DWU1 f. Rücklaufanhebung260_17_0


Bit1- Status maximale Temperatur im Umladespeicher260_17_1


Bit2- Status Umwälzpumpe (PA) im 2.Kollektorfeld (Stagnation)260_17_2


Bit3- Maximaltemperatur erreicht im WW-Speicher B260_17_3


Bit4- WW-Speicher geladen260_17_4


Bit5- Testmodus (Speicherladung Vorrangspeicher)260_17_5


Bit6- Maximaltemperatur erreicht im WW-Speicher C260_17_6


Bit7- Testmodus260_17_7
24
Byte 3Betriebszeit f. Solarmumpe (PA) im zweiten Kollektorfeld260_18_0
25
Byte 2
26
Byte 1
27
Hi-ByteZeitintervall f. Überprüfung ob Speicher C geladen wird260_21_0
28
Lo-Byte

29
Hi-ByteTemperatur TF 1 in Wärmequelle260_23_0
30
Lo-Byte

31
Hi-ByteTemperatur TF 2 in Wärmesenke260_25_0
32
Lo-Byte

33
<CRC>

34
<Ende>

+ +
+

Tabelle 22: ID 866

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:866
Byte
BemerkungBedeutung / ID






MS100 Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
402Immer 02EMS Type(H)
562Immer 62EMS Type(L)
6Hi-ByteSolarkollektor1 Temperatur866_0_0
7Lo-Byte
8Hi-ByteSolarspeicher Temperatur unten866_2_0
9Lo-Byte
10Hi-ByteSolarspeicher Temperatur mittlerer Sensor866_4_0
11Lo-Byte
12Hi-ByteSolarkollektor2 Temperatur866_6_0
13Lo-Byte
14Hi-ByteSolarspeicher Beipass Temperatur866_8_0
15Lo-Byte
16Hi-ByteSolarspeicher Beipass Return-Temperatur866_10_0
17Lo-Byte
18Hi-Byte
866_12_0
19Lo-Byte
20Hi-Byte
866_14_0
21Lo-Byte
22Hi-Byte
866_16_0
23Lo-Byte
24Hi-Byte
866_18_0
25Lo-Byte
26Hi-Byte
866_20_0
27Lo-Byte
28Hi-Byte
866_22_0
29Lo-Byte
30Hi-Byte
866_24_0
31Lo-Byte
32<CRC>

33<Ende>

+ +
+

Tabelle 23: ID 868

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:868_x_y
Byte
BemerkungBedeutung / ID






MS100 Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
402Immer 02EMS Type(H)
564Immer 64EMS Type(L)
6xy
868_0_0
7xy
868_1_0
8Bit0...Bit7
868_2_x

Bit0
868_2_0

Bit1
868_2_1

Bit2
868_2_2

Bit3
868_2_3

Bit4
868_2_4

Bit5
868_2_5

Bit6
868_2_6

Bit7
868_2_7
9Bit0...Bit7Solar Systemstatus868_3_x

Bit0- Abschaltung 1.Kollektorfeld bei Stagnation868_3_0


-- 0 =Nein


-- 1 =Ja

Bit1-- 1 =Solarspeicher maximale Temperatur erreicht868_3_1

Bit2-- 1 =Solarspeicher minimale Temperatur erreicht868_3_2

Bit3
868_3_3

Bit4
868_3_4

Bit5
868_3_5

Bit6
868_3_6

Bit7
868_3_7
10xy
868_4_0
11xy
868_5_0
12xy
868_6_0
13xy
868_7_0
14xy
868_8_0
15xyAktuelle Solarpumpen – Leistung868_9_0
16xy
868_10_0
17xy868_11_0
18xy
868_12_0
19xy868_13_0
20xy
868_14_0
21xy868_15_0
22<CRC>

23<Ende>

+ +
+

Tabelle 24: ID 873

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:873_x_0
Byte
BemerkungBedeutung / ID






MS100 Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
402Immer 02EMS Type(H)
569Immer 69EMS Type(L)
6Byte 4Solarertrag letzte Stunde873_0_0
7Byte 3
8Byte 2 „ ( Calculation-Type: 4 )
9Byte 1
10Byte 4Solarertrag aktueller Tag873_4_0
11Byte 3
12Byte 2
13Byte 1
14Byte 4Solarertrag Summe873_8_0
15Byte 3
16Byte 2
17Byte 1
18<CRC>

19<Ende>

+ +
+

Tabelle 25: ID 874

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:874_x_0
Byte
BemerkungBedeutung / ID






MS100 Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
402Immer 02EMS Type(H)
56AImmer 6AEMS Type(L)
6xy
874_0_0
7xy
874_1_0
8xy
874_2_0
9xy
874_3_0
10xy
874_4_0
11xy
874_5_0
12xy
874_6_0
13xy
874_7_0
14xy
874_8_0
15xy
874_9_0
16Bit0...Bit7
874_10_x

Bit0
874_10_0

Bit1
874_10_1

Bit2- Solarpumpe (SP); 0=aus; 1=ein874_10_2

Bit3
874_10_3

Bit4
874_10_4

Bit5
874_10_5

Bit6
874_10_6

Bit7
874_10_7
17xy
874_11_0
18xy
874_12_0
19xy874_13_0
20xy
874_14_0
21xy874_15_0
22<CRC>

23<Ende>

+ +
+

Tabelle 26: ID 910

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:910_x_0
Byte
BemerkungBedeutung / ID






MS100 Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
402Immer 02EMS Type(H)
58EImmer 8EEMS Type(L)
6Byte 4Solarertrag letzte Stunde910_0_0
7Byte 3
8Byte 2 „ ( Calculation-Type: 4 )
9Byte 1
10Byte 4Solarertrag aktueller Tag910_4_0
11Byte 3
12Byte 2 „ ( Calculation-Type: 5 )
13Byte 1
14Byte 4Solarertrag Summe910_8_0
15Byte 3
16Byte 2 „ ( Calculation-Type: 4 )
17Byte 1
18<CRC>

19<Ende>

+ +
+

Tabelle 27: ID 913

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:913_x_0
Byte
BemerkungBedeutung / ID






MS100 Solar-Telegramm
0B0
Source
100
Target
2FF
EMS Marker
3xy
EMS Offset
402Immer 02EMS Type(H)
591Immer 91EMS Type(L)
6Byte 4Laufzeit Solarpumpe (Minuten)913_0_0
7Byte 3
8Byte 2 „ ( Calculation-Type: 2 )
9Byte 1
10xy
913_4_0
11xy
913_5_0
12xy
913_6_0
13xy
913_7_0
14xy
913_8_0
15xy
913_9_0
16xy
913_10_0
17xy
913_11_0
18<CRC>

19<Ende>

+ +
+

Tabelle 28: ID 357_366_14_Modem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:357_14_0 bis 366_14_0
ByteWerte (Hex)BemerkungBedeutung / ID

9Byte



Modem-CMD:: Betriebsart setzen
08DSource: ModemSource
110TargetTarget
2FFEMS-TypeEMS Marker
30E
EMS Offset
400
EMS Type(H)
565...6EHeizkreis xEMS Type(L)


65=Heizkreis1


66=Heizkreis2


67=Heizkreis3


68=Heizkreis4


69=Heizkreis5


6A=Heizkreis6


6B=Heizkreis7


6C=Heizkreis8


6D=Heizkreis9


6E=Heizkreis10
60...4Heizkreisbetriebsart-Werte357_14_0 bis


- 0=Nicht definiert366_14_0


- 1=Betrieb im Frostschutzmodus


- 2=Betrieb im Sparmodus


- 3=Betrieb im Normalmodus


- 4=Automatikbetrieb
7<CRC>CRC
8<Ende>Ende Marker
+ +
+

Tabelle 29: ID 377_387_4_Modem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme


Message-ID:377_4_0 bis 386_4_0
ByteWerte (Hex)BemerkungBedeutung / ID

9Byte



Modem-CMD: Betriebsart setzen
08DSource: ModemSource
110TargetTarget
2FFEMS-TypeEMS Marker
304
EMS Offset
400
EMS Type(H)
579...82Heizkreis x KennungEMS Type(L)


79=Heizkreis1


7A=Heizkreis2


7B=Heizkreis3


7C=Heizkreis4


7D=Heizkreis5


7E=Heizkreis6


7F=Heizkreis7


80=Heizkreis8


81=Heizkreis9


82=Heizkreis10
60...4Heizkreisbetriebsart-Werte357_4_0 bis


- 0=Nicht definiert366_4_0


- 1=Betrieb im Frostschutzmodus


- 2=Betrieb im Sparmodus


- 3=Betrieb im Normalmodus


- 4=Automatikbetrieb
7<CRC>CRC
8<Ende>Ende Marker
+ +
+

Tabelle 30: ID 357...366_1x_Modem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme




Message-ID:357_1x_0 bis 366_1x_0


ByteWerte (Hex)BemerkungBedeutung / ID


9Byte
Betriebsart



Modem-CMD: Temperatur-Niveau setzen (Betriebsart Normal/Sparen/Frost) NormalSparenFrost
08DSource: ModemSourceSourceSource
110TargetTargetTargetTarget
2FFEMS-TypeEMS MarkerEMS MarkerEMS Marker
311/10/0FEMS-Offset 11 (hex)10 (hex) F (hex)
400
EMS Type(H)EMS Type(H)EMS Type(H)
565...6EHeizkreis xEMS Type(L)EMS Type(L)EMS Type(L)


65=Heizkreis1




66=Heizkreis2




67=Heizkreis3




68=Heizkreis4




69=Heizkreis5




6A=Heizkreis6




6B=Heizkreis7




6C=Heizkreis8




6D=Heizkreis9




6E=Heizkreis10


6
Temperaturniveau für Betriebsart: y im Heizkreis x357_17_0 bis357_16_0 bis357_15_0 bis


- (in 0.5 Grad Schritten)366_17_0366_16_0366_15_0
7<CRC>CRC


8<Ende>Ende Marker


+ +
+

Tabelle 31: ID 377...386_x_Modem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HT Bus-Telegramme




Message-ID:377_x_0 bis 386_x_0


ByteWerte (Hex)BemerkungBedeutung / ID


9Byte





Modem-CMD: Temperatur-Niveau setzen (Betriebsart Normal/Sparen/Frost) NormalSparenFrost
08DSource: ModemSourceSourceSource
110TargetTargetTargetTarget
2FFEMS-TypeEMS MarkerEMS MarkerEMS Marker
307/06/05EMS-Offset 7 (hex) 6 (hex) 5 (hex)
400
EMS Type(H)EMS Type(H)EMS Type(H)
579...82Heizkreis x KennungEMS Type(L)EMS Type(L)EMS Type(L)


79=Heizkreis1




7A=Heizkreis2




7B=Heizkreis3




7C=Heizkreis4




7D=Heizkreis5




7E=Heizkreis6




7F=Heizkreis7




80=Heizkreis8




81=Heizkreis9




82=Heizkreis10


60...4Temperaturniveau für Betriebsart: y im Heizkreis x377_7_0 bis377_6_0 bis377_5_0 bis


- (in 0.5 Grad Schritten)386_7_0386_6_0386_5_0
7<CRC>CRC


8<Ende>Ende Marker


+ + + + diff --git a/doc/ems references/wiki_ ems_ telegrams.pdf b/doc/ems references/wiki_ ems_ telegrams.pdf new file mode 100644 index 000000000..882a997ab Binary files /dev/null and b/doc/ems references/wiki_ ems_ telegrams.pdf differ diff --git a/doc/home_assistant/automations.yaml b/doc/home assistant/automation.yaml similarity index 100% rename from doc/home_assistant/automations.yaml rename to doc/home assistant/automation.yaml diff --git a/doc/home_assistant/binary_sensor.yaml b/doc/home assistant/binary_sensor.yaml similarity index 100% rename from doc/home_assistant/binary_sensor.yaml rename to doc/home assistant/binary_sensor.yaml diff --git a/doc/home_assistant/climate.yaml b/doc/home assistant/climate.yaml similarity index 98% rename from doc/home_assistant/climate.yaml rename to doc/home assistant/climate.yaml index f23edba77..083b4246b 100644 --- a/doc/home_assistant/climate.yaml +++ b/doc/home assistant/climate.yaml @@ -2,7 +2,7 @@ name: Thermostat modes: - "auto" - - "manual" + - "heat" - "off" mode_state_topic: "home/ems-esp/thermostat_data" diff --git a/doc/home_assistant/customize.yaml b/doc/home assistant/customize.yaml similarity index 100% rename from doc/home_assistant/customize.yaml rename to doc/home assistant/customize.yaml diff --git a/doc/home_assistant/ha.png b/doc/home assistant/ha.png similarity index 100% rename from doc/home_assistant/ha.png rename to doc/home assistant/ha.png diff --git a/doc/home_assistant/ha_notify.jpg b/doc/home assistant/ha_notify.jpg similarity index 100% rename from doc/home_assistant/ha_notify.jpg rename to doc/home assistant/ha_notify.jpg diff --git a/doc/home_assistant/notify.yaml b/doc/home assistant/notify.yaml similarity index 100% rename from doc/home_assistant/notify.yaml rename to doc/home assistant/notify.yaml diff --git a/doc/home_assistant/scripts.yaml b/doc/home assistant/script.yaml similarity index 100% rename from doc/home_assistant/scripts.yaml rename to doc/home assistant/script.yaml diff --git a/doc/home_assistant/sensors.yaml b/doc/home assistant/sensor.yaml similarity index 100% rename from doc/home_assistant/sensors.yaml rename to doc/home assistant/sensor.yaml diff --git a/doc/home_assistant/switches.yaml b/doc/home assistant/switch.yaml similarity index 100% rename from doc/home_assistant/switches.yaml rename to doc/home assistant/switch.yaml diff --git a/doc/home_assistant/ui-lovelace.yaml b/doc/home assistant/ui-lovelace.yaml similarity index 100% rename from doc/home_assistant/ui-lovelace.yaml rename to doc/home assistant/ui-lovelace.yaml diff --git a/platformio.ini-example b/platformio.ini similarity index 76% rename from platformio.ini-example rename to platformio.ini index 231231332..118742f17 100644 --- a/platformio.ini-example +++ b/platformio.ini @@ -4,26 +4,35 @@ [platformio] default_envs = release -;default_envs = debug +; default_envs = debug +;default_envs = crash +;default_envs = tests [common] -; -DMYESP_TIMESTAMP -DTESTS -DCRASH -DFORCE_SERIAL -DNO_GLOBAL_EEPROM -DLOGICANALYZER -general_flags = +; build options are: +; -DMYESP_TIMESTAMP +; -DTESTS +; -DCRASH +; -DFORCE_SERIAL +; -DLOGICANALYZER + +general_flags = -g -w -DNO_GLOBAL_EEPROM -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -DBEARSSL_SSL_BASIC +;general_flags = [env] board = d1_mini framework = arduino platform = espressif8266 lib_deps = + ESPAsyncTCP CRC32 CircularBuffer OneWire JustWifi AsyncMqttClient ArduinoJson - EEPROM_rotate + EEPROM_Rotate ESP Async WebServer - ESPAsyncTCP ESPAsyncUDP upload_speed = 921600 monitor_speed = 115200 @@ -39,7 +48,7 @@ monitor_speed = 115200 [env:buildweb] extra_scripts = pre:scripts/buildweb.py -[env:test] +[env:tests] build_type = debug build_flags = ${common.general_flags} -DTESTS extra_scripts = @@ -48,7 +57,7 @@ extra_scripts = [env:crash] build_type = debug -build_flags = ${common.general_flags} -DNO_GLOBAL_EEPROM -DCRASH +build_flags = ${common.general_flags} -DCRASH extra_scripts = pre:scripts/rename_fw.py pre:scripts/buildweb.py @@ -65,7 +74,7 @@ extra_scripts = pre:scripts/clean_fw.py [env:release] build_flags = ${common.general_flags} -extra_scripts = +extra_scripts = pre:scripts/rename_fw.py pre:scripts/buildweb.py diff --git a/scripts/analyze_stackdmp.py b/scripts/analyze_stackdmp.py index 1e29b2449..76c138616 100755 --- a/scripts/analyze_stackdmp.py +++ b/scripts/analyze_stackdmp.py @@ -17,7 +17,7 @@ import os # 3fffffb0: feefeffe feefeffe 3ffe8558 40100b01 # << 0: bag[var] = m.group(1) +with open('./src/ems-esp.cpp', 'r') as f: + for l in f.readlines(): + for expr, var in exprs: + m = expr.match(l) + if m and len(m.groups()) > 0: + bag[var] = m.group(1) + app_version = bag.get('app_version') app_name = bag.get('app_name') app_hostname = bag.get('app_hostname') @@ -32,5 +39,8 @@ branch = env['PIOENV'] env.AddPreAction("buildprog", build_web) # build filename, replacing . with _ for the version -env.Replace(PROGNAME="firmware_%s" % branch + "_" + app_version.replace(".", "_")) +#env.Replace(PROGNAME="firmware_%s" % branch + "_" + app_version.replace(".", "_")) +env.Replace(PROGNAME=app_name + "-" + app_version.replace(".", "_") + "-" + board + "-" + branch) +#env.Replace(PROGNAME=app_name + "-" + app_version) + diff --git a/src/MyESP.cpp b/src/MyESP.cpp index 55f47144f..34144126c 100644 --- a/src/MyESP.cpp +++ b/src/MyESP.cpp @@ -46,6 +46,7 @@ MyESP::MyESP() { _ota_post_callback_f = nullptr; _load_average = 100; // calculated load average _general_serial = true; // serial is set to on as default + _general_log_events = true; // all logs are written to an event log in SPIFFS _have_ntp_time = false; // telnet @@ -95,8 +96,7 @@ MyESP::MyESP() { _systemStable = true; // ntp - _ntp_server = strdup(MYESP_NTP_SERVER); - ; + _ntp_server = strdup(MYESP_NTP_SERVER); _ntp_interval = 60; _ntp_enabled = false; @@ -105,6 +105,7 @@ MyESP::MyESP() { // MQTT log for (uint8_t i = 0; i < MYESP_MQTTLOG_MAX; i++) { + MQTT_log[i].type = 0; MQTT_log[i].timestamp = 0; MQTT_log[i].topic = nullptr; MQTT_log[i].payload = nullptr; @@ -213,8 +214,18 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) { ArduinoOTA.begin(); // moved to support esp32 myDebug_P(PSTR("[OTA] listening to %s.local:%u"), ArduinoOTA.getHostname().c_str(), OTA_PORT); - - myDebug_P(PSTR("[SYSTEM] Last reset info: %s"), (char *)ESP.getResetInfo().c_str()); // unconditionally show the last reset reason + /* + // show reason for the restart if any + unsigned char reason = _getCustomResetReason(); + if (reason > 0) { + char buffer[32]; + strcpy_P(buffer, custom_reset_string[reason - 1]); + myDebug_P(PSTR("[SYSTEM] Last reset reason: %s (count %d)"), buffer, _getSystemStabilityCounter()); + } else { + myDebug_P(PSTR("[SYSTEM] Last reset reason: %s (count %d)"), (char *)ESP.getResetReason().c_str(), _getSystemStabilityCounter()); + myDebug_P(PSTR("[SYSTEM] Last reset info: %s"), (char *)ESP.getResetInfo().c_str()); + } + */ // MQTT Setup _mqtt_setup(); @@ -241,7 +252,7 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) { _wifi_callback_f(); } - jw.enableAPFallback(false); // Disable AP mode after initial connect was successful + // jw.enableAPFallback(false); // Disable AP mode after initial connect was successful - test for https://github.com/proddy/EMS-ESP/issues/187 } if (code == MESSAGE_ACCESSPOINT_CREATED) { @@ -308,6 +319,9 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) { if (code == MESSAGE_ACCESSPOINT_CREATING) { myDebug_P(PSTR("[WIFI] Creating access point")); + // for setting of wifi mode to AP, but don't save + _network_wmode = 1; + // (void)_fs_writeConfig(); } if (code == MESSAGE_ACCESSPOINT_FAILED) { @@ -353,16 +367,23 @@ void MyESP::_mqttOnMessage(char * topic, char * payload, size_t len) { // MQTT subscribe void MyESP::mqttSubscribe(const char * topic) { if (mqttClient.connected() && (strlen(topic) > 0)) { - unsigned int packetId = mqttClient.subscribe(_mqttTopic(topic), _mqtt_qos); - myDebug_P(PSTR("[MQTT] Subscribing to %s (PID %d)"), _mqttTopic(topic), packetId); + char * topic_s = _mqttTopic(topic); + + //char topic_s[MQTT_MAX_TOPIC_SIZE]; + //strlcpy(topic_s, _mqttTopic(topic), sizeof(topic_s)); + (void)mqttClient.subscribe(topic_s, _mqtt_qos); + // myDebug_P(PSTR("[MQTT] Subscribing to %s"), topic_s); + + // add to mqtt log + _addMQTTLog(topic_s, "", 2); // type of 2 means Subscribe. Has an empty payload for now } } // MQTT unsubscribe void MyESP::mqttUnsubscribe(const char * topic) { if (mqttClient.connected() && (strlen(topic) > 0)) { - unsigned int packetId = mqttClient.unsubscribe(_mqttTopic(topic)); - myDebug_P(PSTR("[MQTT] Unsubscribing to %s (PID %d)"), _mqttTopic(topic), packetId); + (void)mqttClient.unsubscribe(_mqttTopic(topic)); + myDebug_P(PSTR("[MQTT] Unsubscribing to %s"), _mqttTopic(topic)); } } @@ -371,7 +392,7 @@ void MyESP::mqttPublish(const char * topic, const char * payload) { // myDebug_P(PSTR("[MQTT] Sending pubish to %s with payload %s"), _mqttTopic(topic), payload); // for debugging mqttClient.publish(_mqttTopic(topic), _mqtt_qos, _mqtt_retain, payload); - _addMQTTLog(topic, payload); // add to the log + _addMQTTLog(topic, payload, 1); // add to the log, using type of 1 for Publish } // MQTT onConnect - when a connect is established @@ -443,19 +464,20 @@ void MyESP::_wifi_setup() { jw.subscribe([this](justwifi_messages_t code, char * parameter) { _wifiCallback(code, parameter); }); jw.setConnectTimeout(MYESP_WIFI_CONNECT_TIMEOUT); jw.setReconnectTimeout(MYESP_WIFI_RECONNECT_INTERVAL); - jw.enableAPFallback(true); // AP mode only as fallback - jw.enableSTA(true); // Enable STA mode (connecting to a router) - jw.enableScan(false); // Configure it to scan available networks and connect in order of dBm - jw.cleanNetworks(); // Clean existing network configuration /// wmode 1 is AP, 0 is client if (_network_wmode == 1) { jw.enableAP(true); } else { jw.enableAP(false); - jw.addNetwork(_network_ssid, _network_password); // Add a network } + jw.enableAPFallback(true); // AP mode only as fallback + jw.enableSTA(true); // Enable STA mode (connecting to a router) + jw.enableScan(false); // Configure it to not scan available networks and connect in order of dBm + jw.cleanNetworks(); // Clean existing network configuration + jw.addNetwork(_network_ssid, _network_password); // Add a network + #if defined(ESP8266) WiFi.setSleepMode(WIFI_NONE_SLEEP); // added to possibly fix wifi dropouts in arduino core 2.5.0 #endif @@ -609,7 +631,7 @@ void MyESP::_consoleShowHelp() { myDebug_P(PSTR("*")); myDebug_P(PSTR("* Commands:")); - myDebug_P(PSTR("* ?=help, CTRL-D/quit=exit telnet session")); + myDebug_P(PSTR("* ?/help=show commands, CTRL-D/quit=close telnet session")); myDebug_P(PSTR("* set, system, restart, mqttlog")); #ifdef CRASH myDebug_P(PSTR("* crash ")); @@ -626,7 +648,7 @@ void MyESP::_consoleShowHelp() { // see if a char * string is empty. It could not be initialized yet. // return true if there is a value bool MyESP::_hasValue(char * s) { - if (s == nullptr) { + if ((s == nullptr) || (strlen(s) == 0)) { return false; } return (s[0] != '\0'); @@ -634,7 +656,7 @@ bool MyESP::_hasValue(char * s) { // print all set commands and current values void MyESP::_printSetCommands() { - myDebug_P(PSTR("\nThe following set commands are available:\n")); + myDebug_P(PSTR("\nset commands:\n")); myDebug_P(PSTR(" set erase")); myDebug_P(PSTR(" set ")); myDebug_P(PSTR(" set [value]")); @@ -645,13 +667,14 @@ void MyESP::_printSetCommands() { myDebug_P(PSTR(" set mqtt_port [value]")); myDebug_P(PSTR(" set ntp_enabled ")); myDebug_P(PSTR(" set serial ")); + myDebug_P(PSTR(" set log_events ")); // call callback function if (_telnet_callback_f) { (_telnet_callback_f)(TELNET_EVENT_SHOWSET); } - myDebug_P(PSTR("\nStored settings:\n")); + myDebug_P(PSTR("\nCurrent settings:\n")); if (_network_wmode == 0) { myDebug_P(PSTR(" wifi_mode=client")); @@ -697,8 +720,14 @@ void MyESP::_printSetCommands() { myDebug_P(PSTR(" mqtt_port=%d"), _mqtt_port); myDebug_P(PSTR(" mqtt_heartbeat=%s"), (_mqtt_heartbeat) ? "on" : "off"); +#ifdef FORCE_SERIAL + myDebug_P(PSTR(" serial=%s (this is always when compiled with -DFORCE_SERIAL)"), (_general_serial) ? "on" : "off"); +#else myDebug_P(PSTR(" serial=%s"), (_general_serial) ? "on" : "off"); +#endif + myDebug_P(PSTR(" ntp_enabled=%s"), (_ntp_enabled) ? "on" : "off"); + myDebug_P(PSTR(" log_events=%s"), (_general_log_events) ? "on" : "off"); // print any custom settings if (_fs_setlist_callback_f) { @@ -823,11 +852,11 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) if (strcmp(value, "on") == 0) { _general_serial = true; save_config = true; - myDebug_P(PSTR("Do a 'restart' to activate Serial mode.")); + myDebug_P(PSTR("Type 'restart' to activate Serial mode.")); } else if (strcmp(value, "off") == 0) { _general_serial = false; save_config = true; - myDebug_P(PSTR("Do a 'restart' to deactivate Serial mode.")); + myDebug_P(PSTR("Type 'restart' to deactivate Serial mode.")); } else { save_config = false; } @@ -863,6 +892,21 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) save_config = false; } } + } else if (strcmp(setting, "log_events") == 0) { + save_config = true; + if (value) { + if (strcmp(value, "on") == 0) { + _general_log_events = true; + save_config = true; + myDebug_P(PSTR("Event logging on")); + } else if (strcmp(value, "off") == 0) { + _general_log_events = false; + save_config = true; + myDebug_P(PSTR("Event logging off")); + } else { + save_config = false; + } + } } else { // finally check for any custom commands if (_fs_setlist_callback_f) { @@ -941,12 +985,19 @@ void MyESP::_telnetCommand(char * commandLine) { } if (!ok) { - myDebug_P(PSTR("\nInvalid parameter for set command.")); + myDebug_P(PSTR("")); // newline + myDebug_P(PSTR("Unknown set command or wrong number of arguments.")); } return; } + // help command + if ((strcmp(ptrToCommandName, "help") == 0) && (wc == 1)) { + _consoleShowHelp(); + return; + } + // restart command if ((strcmp(ptrToCommandName, "restart") == 0) && (wc == 1)) { resetESP(); @@ -980,9 +1031,6 @@ void MyESP::_telnetCommand(char * commandLine) { crashDump(); } else if (strcmp(cmd, "clear") == 0) { crashClear(); - } else if ((strcmp(cmd, "test") == 0) && (wc == 3)) { - char * value = _telnet_readWord(false); - crashTest(atoi(value)); } else { myDebug_P(PSTR("Error. Usage: crash ")); } @@ -1404,9 +1452,13 @@ void MyESP::_telnetHandle() { if (charsRead > 0) { charsRead = 0; // is static, so have to reset _suspendOutput = false; + /* if (_general_serial) { SerialAndTelnet.serialPrint('\n'); // force newline if in Serial } + */ + SerialAndTelnet.write('\n'); // force NL + _telnetCommand(_command); } break; @@ -1517,29 +1569,149 @@ char * MyESP::_mqttTopic(const char * topic) { return buffer; } -// print contents of file -// assumes Serial is open -void MyESP::_fs_printFile(const char * file) { - File configFile = SPIFFS.open(file, "r"); - if (!configFile) { - myDebug_P(PSTR("[FS] Failed to read file %s for printing"), file); - return; +// validates a file in SPIFFS, loads it into the json buffer and returns true if ok +bool MyESP::_fs_validateConfigFile(const char * filename, size_t maxsize, JsonDocument & doc) { + // see if we can open it + File file = SPIFFS.open(filename, "r"); + if (!file) { + myDebug_P(PSTR("[FS] File %s not found"), filename); + return false; } - myDebug_P(PSTR("[FS] File: %s, Size: %d"), file, configFile.size()); + // check size + size_t size = file.size(); + myDebug_P(PSTR("[FS] Checking file %s (size %d bytes)"), filename, size); // remove for debugging + + if (size > maxsize) { + file.close(); + myDebug_P(PSTR("[FS] File %s size %d is too large (max %d)"), filename, size, maxsize); + return false; + } else if (size == 0) { + file.close(); + myDebug_P(PSTR("[FS] Corrupted file %s"), filename); + return false; + } + + // check integrity by reading file from SPIFFS into the char array + char * buffer = new char[size + 2]; // reserve some memory to read in the file + + size_t real_size = file.readBytes(buffer, size); + if (real_size != size) { + file.close(); + myDebug_P(PSTR("[FS] Error, file %s sizes don't match (%d/%d), looks corrupted"), filename, real_size, size); + delete[] buffer; + return false; + } + + // now read into the given json + DeserializationError error = deserializeJson(doc, buffer); + if (error) { + myDebug_P(PSTR("[FS] Failed to deserialize json, error %s"), error.c_str()); + delete[] buffer; + return false; + } + + // serializeJsonPretty(doc, Serial); // enable for debugging + + file.close(); + delete[] buffer; + return true; +} + +// validates the event log file in SPIFFS +// returns true if all OK +bool MyESP::_fs_validateLogFile(const char * filename) { + // exit if we have disabled logging + if (!_general_log_events) { + return true; + } + + // see if we can open it + File eventlog = SPIFFS.open(filename, "r"); + if (!eventlog) { + myDebug_P(PSTR("[FS] File %s not found"), filename); + return false; + } + + // check sizes + size_t size = eventlog.size(); + size_t maxsize = ESP.getFreeHeap() - 2000; // reserve some buffer + myDebug_P(PSTR("[FS] Checking file %s (size %d bytes, max is %d)"), filename, size, maxsize); // remove for debugging + if (size > maxsize) { + eventlog.close(); + myDebug_P(PSTR("[FS] File %s size %d is too large (max %d)"), filename, size, maxsize); + return false; + } else if (size == 0) { + eventlog.close(); + myDebug_P(PSTR("[FS] Corrupted file %s"), filename); + return false; + } + + /* + // check integrity by reading file from SPIFFS into the char array + char * buffer = new char[size + 2]; // reserve some memory to read in the file + size_t real_size = file.readBytes(buffer, size); + if (real_size != size) { + file.close(); + myDebug_P(PSTR("[FS] Error, file %s sizes don't match (%d/%d), looks corrupted"), filename, real_size, size); + delete[] buffer; + return false; + } + file.close(); + delete[] buffer; + */ + + /* + File configFile = SPIFFS.open(filename, "r"); + myDebug_P(PSTR("[FS] File: ")); while (configFile.available()) { SerialAndTelnet.print((char)configFile.read()); } - myDebug_P(PSTR("[FS] end")); // newline - configFile.close(); + */ + + // parse it to check JSON validity + // its slow but the only reliable way to check integrity of the file + uint16_t char_count = 0; + bool abort = false; + char char_buffer[MYESP_JSON_LOG_MAXSIZE]; + char c; + StaticJsonDocument doc; + + // eventlog.seek(0); + while (eventlog.available() && !abort) { + c = eventlog.read(); // read a char + + // see if we have reached the end of the string + if (c == '\0' || c == '\n') { + char_buffer[char_count] = '\0'; // terminate and add it to the list + // Serial.printf("Got line: %s\n", char_buffer); // for debugging + // validate it by looking at JSON structure + DeserializationError error = deserializeJson(doc, char_buffer); + if (error) { + myDebug_P(PSTR("[FS] Event log has a corrupted entry (error %s)"), error.c_str()); + abort = true; + } + char_count = 0; // start new record + } else { + // add the char to the buffer if recording, checking for overrun + if (char_count < MYESP_JSON_LOG_MAXSIZE) { + char_buffer[char_count++] = c; + } else { + abort = true; // reached limit of our line buffer + } + } + } + + eventlog.close(); + return !abort; } // format File System void MyESP::_fs_eraseConfig() { - myDebug_P(PSTR("[FS] Doing a factory reset.")); + myDebug_P(PSTR("[FS] Performing a factory reset...")); _formatreq = true; } @@ -1563,40 +1735,11 @@ bool MyESP::_fs_loadConfig() { myDebug_P(PSTR("[FS] Removed old config version")); } - File configFile = SPIFFS.open(MYESP_CONFIG_FILE, "r"); - if (!configFile) { - configFile.close(); - myDebug_P(PSTR("[FS] No system config found")); - return false; - } + StaticJsonDocument doc; - // check size - size_t size = configFile.size(); - if (size > MYESP_SPIFFS_MAXSIZE) { - configFile.close(); - myDebug_P(PSTR("[FS] System config size is too large")); - return false; - } else if (size == 0) { - configFile.close(); - myDebug_P(PSTR("[FS] Corrupted system config")); - return false; - } - - // read file from SPIFFS into a char array - char json[MYESP_SPIFFS_MAXSIZE] = {0}; - if (configFile.readBytes(json, size) != size) { - configFile.close(); - myDebug_P(PSTR("[FS] Error, file sizes don't match with system config")); - return false; - } - configFile.close(); - - StaticJsonDocument doc; - - DeserializationError error = deserializeJson(doc, json); // Deserialize the JSON document - if (error) { - myDebug_P(PSTR("[FS] Failed to deserialize json, error %s"), error.c_str()); - configFile.close(); + // set to true to print out contents of file + if (!_fs_validateConfigFile(MYESP_CONFIG_FILE, MYESP_SPIFFS_MAXSIZE_CONFIG, doc)) { + myDebug_P(PSTR("[FS] Failed to open system config")); return false; } @@ -1606,10 +1749,10 @@ bool MyESP::_fs_loadConfig() { _network_wmode = network["wmode"]; // 0 is client, 1 is AP JsonObject general = doc["general"]; - - _general_password = strdup(general["password"] | MYESP_HTTP_PASSWORD); + _general_password = strdup(general["password"] | MYESP_HTTP_PASSWORD); _ws->setAuthentication("admin", _general_password); - _general_hostname = strdup(general["hostname"]); + _general_hostname = strdup(general["hostname"]); + _general_log_events = general["log_events"] | false; // default is off // serial is only on when booting #ifdef FORCE_SERIAL @@ -1631,64 +1774,31 @@ bool MyESP::_fs_loadConfig() { JsonObject ntp = doc["ntp"]; _ntp_server = strdup(ntp["server"] | ""); _ntp_interval = ntp["interval"] | 60; - if (_ntp_interval == 0) + if (_ntp_interval < 2) _ntp_interval = 60; _ntp_enabled = ntp["enabled"]; - myDebug_P(PSTR("[FS] System settings loaded")); - // serializeJsonPretty(doc, Serial); // turn on for debugging + myDebug_P(PSTR("[FS] System config loaded")); return true; } // load custom settings bool MyESP::_fs_loadCustomConfig() { - File configFile = SPIFFS.open(MYESP_CUSTOMCONFIG_FILE, "r"); - if (!configFile) { - myDebug_P(PSTR("[FS] No custom config found")); - return false; - } + StaticJsonDocument doc; - // check size - size_t size = configFile.size(); - if (size > MYESP_SPIFFS_MAXSIZE) { - configFile.close(); - myDebug_P(PSTR("[FS] Custom config size is too large")); - return false; - } else if (size == 0) { - configFile.close(); - myDebug_P(PSTR("[FS] Corrupted custom config")); - return false; - } - - // read file from SPIFFS into a char array - char data[MYESP_SPIFFS_MAXSIZE] = {0}; - if (configFile.readBytes(data, size) != size) { - myDebug_P(PSTR("[FS] File sizes don't match with custom config")); - configFile.close(); - return false; - } - configFile.close(); - - // create the JSON doc and pass it back to the callback function - StaticJsonDocument doc; - JsonObject json = doc.to(); // create empty object - - DeserializationError error = deserializeJson(doc, data); // Deserialize the JSON document - - if (error) { - myDebug_P(PSTR("[FS] Failed to deserialize json for custom config, error %s"), error.c_str()); - configFile.close(); + if (!_fs_validateConfigFile(MYESP_CUSTOMCONFIG_FILE, MYESP_SPIFFS_MAXSIZE_CONFIG, doc)) { + myDebug_P(PSTR("[FS] Failed to open custom config")); return false; } if (_fs_loadsave_callback_f) { + const JsonObject & json = doc["settings"]; if (!(_fs_loadsave_callback_f)(MYESP_FSACTION_LOAD, json)) { myDebug_P(PSTR("[FS] Error reading custom config")); return false; } else { myDebug_P(PSTR("[FS] Custom config loaded")); - //serializeJsonPretty(doc, Serial); // added for debugging } } @@ -1699,37 +1809,42 @@ bool MyESP::_fs_loadCustomConfig() { bool MyESP::fs_saveCustomConfig(JsonObject root) { bool ok = false; - // open for writing - File configFile = SPIFFS.open(MYESP_CUSTOMCONFIG_FILE, "w"); - if (!configFile) { - myDebug_P(PSTR("[FS] Failed to open custom config for writing")); - return false; - } - // call any custom functions before handling SPIFFS if (_ota_pre_callback_f) { (_ota_pre_callback_f)(); } - // Serialize JSON to file - size_t n = serializeJson(root, configFile); - configFile.close(); + // open for writing + File configFile = SPIFFS.open(MYESP_CUSTOMCONFIG_FILE, "w"); + if (!configFile) { + myDebug_P(PSTR("[FS] Failed to open custom config for writing")); + ok = false; + } else { + // Serialize JSON to file + size_t n = serializeJson(root, configFile); + configFile.close(); - if (n) { - // reload the settings + if (n) { + /* + // reload the settings, not sure why? if (_fs_loadsave_callback_f) { if (!(_fs_loadsave_callback_f)(MYESP_FSACTION_LOAD, root)) { myDebug_P(PSTR("[FS] Error parsing custom config json")); } } + */ - _writeEvent("INFO", "system", "Custom config stored in the SPIFFS", ""); - myDebug_P(PSTR("[FS] custom config saved")); - ok = true; + if (_general_log_events) { + _writeEvent("INFO", "system", "Custom config stored in the SPIFFS", ""); + } + + myDebug_P(PSTR("[FS] custom config saved")); + ok = true; + } } - if (_ota_pre_callback_f) { - (_ota_pre_callback_f)(); + if (_ota_post_callback_f) { + (_ota_post_callback_f)(); } return ok; @@ -1739,32 +1854,34 @@ bool MyESP::fs_saveCustomConfig(JsonObject root) { bool MyESP::fs_saveConfig(JsonObject root) { bool ok = false; - // open for writing - File configFile = SPIFFS.open(MYESP_CONFIG_FILE, "w"); - if (!configFile) { - myDebug_P(PSTR("[FS] Failed to open system config for writing")); - return false; - } - // call any custom functions before handling SPIFFS if (_ota_pre_callback_f) { (_ota_pre_callback_f)(); } - // Serialize JSON to file - size_t n = serializeJson(root, configFile); - configFile.close(); + // open for writing + File configFile = SPIFFS.open(MYESP_CONFIG_FILE, "w"); + if (!configFile) { + myDebug_P(PSTR("[FS] Failed to open system config for writing")); + ok = false; + } else { + // Serialize JSON to file + size_t n = serializeJson(root, configFile); + configFile.close(); - if (n) { - _writeEvent("INFO", "system", "System config stored in the SPIFFS", ""); - myDebug_P(PSTR("[FS] system config saved")); - ok = true; + if (n) { + if (_general_log_events) { + _writeEvent("INFO", "system", "System config stored in the SPIFFS", ""); + } + myDebug_P(PSTR("[FS] system config saved")); + ok = true; + } + + // serializeJsonPretty(root, Serial); // for debugging } - // serializeJsonPretty(root, Serial); // for debugging - - if (_ota_pre_callback_f) { - (_ota_pre_callback_f)(); + if (_ota_post_callback_f) { + (_ota_post_callback_f)(); } return ok; @@ -1772,8 +1889,8 @@ bool MyESP::fs_saveConfig(JsonObject root) { // create an initial system config file using default settings bool MyESP::_fs_writeConfig() { - StaticJsonDocument doc; - JsonObject root = doc.to(); + StaticJsonDocument doc; + JsonObject root = doc.to(); root["command"] = "configfile"; // header, important! @@ -1808,20 +1925,21 @@ bool MyESP::_fs_writeConfig() { // create an empty json doc for the custom config and call callback to populate it bool MyESP::_fs_createCustomConfig() { - StaticJsonDocument doc; - JsonObject json = doc.to(); + StaticJsonDocument doc; + JsonObject root = doc.to(); - json["command"] = "custom_configfile"; // header, important! + root["command"] = "custom_configfile"; // header, important! if (_fs_loadsave_callback_f) { - if (!(_fs_loadsave_callback_f)(MYESP_FSACTION_SAVE, json)) { + JsonObject settings = root.createNestedObject("settings"); + if (!(_fs_loadsave_callback_f)(MYESP_FSACTION_SAVE, settings)) { myDebug_P(PSTR("[FS] Error building custom config json")); } } else { myDebug_P(PSTR("[FS] Created custom config")); } - bool ok = fs_saveCustomConfig(json); + bool ok = fs_saveCustomConfig(root); return ok; } @@ -1830,10 +1948,16 @@ bool MyESP::_fs_createCustomConfig() { // init the SPIFF file system and load the config // if it doesn't exist try and create it void MyESP::_fs_setup() { + if (_ota_pre_callback_f) { + (_ota_pre_callback_f)(); // call custom function + } + if (!SPIFFS.begin()) { myDebug_P(PSTR("[FS] Formatting filesystem...")); if (SPIFFS.format()) { - _writeEvent("WARN", "system", "File system formatted", ""); + if (_general_log_events) { + _writeEvent("WARN", "system", "File system formatted", ""); + } } else { myDebug_P(PSTR("[FS] Failed to format file system")); } @@ -1849,8 +1973,36 @@ void MyESP::_fs_setup() { if (!_fs_loadCustomConfig()) { _fs_createCustomConfig(); // create the initial config file } + + /* + // fill event log with tests + SPIFFS.remove(MYESP_EVENTLOG_FILE); + File fs = SPIFFS.open(MYESP_EVENTLOG_FILE, "w"); + fs.close(); + char logs[100]; + for (uint8_t i = 1; i < 143; i++) { + sprintf(logs, "Record #%d", i); + _writeEvent("WARN", "system", "test data", logs); + } + */ + + // validate the event log. Sometimes it can can corrupted. + if (_fs_validateLogFile(MYESP_EVENTLOG_FILE)) { + myDebug_P(PSTR("[FS] Event log is healthy")); + } else { + myDebug_P(PSTR("[FS] Resetting event log")); + SPIFFS.remove(MYESP_EVENTLOG_FILE); + if (_general_log_events) { + _writeEvent("WARN", "system", "Event Log", "Log was erased due to probable file corruption"); + } + } + + if (_ota_post_callback_f) { + (_ota_post_callback_f)(); // call custom function + } } +// returns load average as a % uint32_t MyESP::getSystemLoadAverage() { return _load_average; } @@ -2057,52 +2209,7 @@ void MyESP::crashDump() { myDebug_P(PSTR("\nTo clean this dump use the command: %scrash clear%s\n"), COLOR_BOLD_ON, COLOR_BOLD_OFF); } -/* - * Force some crashes to test if stack collection works - */ -void MyESP::crashTest(uint8_t t) { - if (t == 1) { - myDebug_P(PSTR("[CRASH] Attempting to divide by zero ...")); - int result, zero; - zero = 0; - result = 1 / zero; - Serial.printf("Result = %d", result); - } - - if (t == 2) { - myDebug_P(PSTR("[CRASH] Attempting to read through a pointer to no object ...")); - int * nullPointer; - nullPointer = nullptr; - // null pointer dereference - read - // attempt to read a value through a null pointer - Serial.println(*nullPointer); - } - - if (t == 3) { - myDebug_P(PSTR("[CRASH] Crashing with hardware WDT (%ld ms) ...\n"), millis()); - ESP.wdtDisable(); - while (true) { - // stay in an infinite loop doing nothing - // this way other process can not be executed - // - // Note: - // Hardware wdt kicks in if software wdt is unable to perfrom - // Nothing will be saved in EEPROM for the hardware wdt - } - } - - if (t == 4) { - myDebug_P(PSTR("[CRASH] Crashing with software WDT (%ld ms) ...\n"), millis()); - while (true) { - // stay in an infinite loop doing nothing - // this way other process can not be executed - } - } -} - #else -void MyESP::crashTest(uint8_t t) { -} void MyESP::crashClear() { } void MyESP::crashDump() { @@ -2112,7 +2219,9 @@ void MyESP::crashInfo() { #endif // write a log entry to SPIFFS +// assumes we have "log_events" on void MyESP::_writeEvent(const char * type, const char * src, const char * desc, const char * data) { + // this will also create the file if its doesn't exist File eventlog = SPIFFS.open(MYESP_EVENTLOG_FILE, "a"); if (!eventlog) { //Serial.println("[SYSTEM] Error opening event log for writing"); // for debugging @@ -2140,21 +2249,22 @@ void MyESP::_writeEvent(const char * type, const char * src, const char * desc, // send a paged list (10 items) to the ws void MyESP::_sendEventLog(uint8_t page) { - File eventlog = SPIFFS.open(MYESP_EVENTLOG_FILE, "r"); - if (!eventlog) { - eventlog.close(); - myDebug_P(PSTR("[WEB] Event log is missing")); - if (_ota_post_callback_f) { - (_ota_post_callback_f)(); // call custom function - } - return; // file can't be opened - } - if (_ota_pre_callback_f) { (_ota_pre_callback_f)(); // call custom function } + File eventlog; + // if its missing create it, it'll be empty though + if (!SPIFFS.exists(MYESP_EVENTLOG_FILE)) { + myDebug_P(PSTR("[FS] Event log is missing. Creating it.")); + eventlog = SPIFFS.open(MYESP_EVENTLOG_FILE, "w"); + eventlog.close(); + } + + eventlog = SPIFFS.open(MYESP_EVENTLOG_FILE, "r"); + // the size of the json will be quite big so best not to use stack (StaticJsonDocument) + // it only covers 10 log entries DynamicJsonDocument doc(MYESP_JSON_MAXSIZE); JsonObject root = doc.to(); root["command"] = "eventlist"; @@ -2162,60 +2272,64 @@ void MyESP::_sendEventLog(uint8_t page) { JsonArray list = doc.createNestedArray("list"); - uint8_t first = ((page - 1) * 10) + 1; - uint8_t last = page * 10; - uint8_t char_count = 0; - uint8_t line_count = 0; - uint16_t read_count = 0; - bool abort = false; - char char_buffer[MYESP_JSON_LOG_MAXSIZE]; + size_t static lastPos; + // if first page, reset the file pointer + if (page == 1) { + lastPos = 0; + } - // if at start, start immediately recording - bool record = (first == 1) ? true : false; + eventlog.seek(lastPos); // move to position in file + + uint8_t char_count = 0; + uint8_t line_count = 0; + bool abort = false; + char char_buffer[MYESP_JSON_LOG_MAXSIZE]; + char c; + float pages; // start at top and read until we find the page we want (sets of 10) while (eventlog.available() && !abort) { - char c = eventlog.read(); - - // see if we've overrun, which means corrupt so ignore rest - if (read_count++ > MYESP_JSON_LOG_MAXSIZE - 1) { - abort = true; - } + c = eventlog.read(); // see if we have reached the end of the string if (c == '\0' || c == '\n') { - line_count++; - - // save line - if (record) { - char_buffer[char_count] = '\0'; - list.add(char_buffer); - } - - char_count = 0; - read_count = 0; - if (line_count == first - 1) { // have we come to the start position, start recording - record = true; - } else if (line_count == last) { // finish recording and exit loop - record = false; + char_buffer[char_count] = '\0'; // terminate and add it to the list + // Serial.printf("Got line %d: %s\n", line_count+1, char_buffer); // for debugging + list.add(char_buffer); + // increment line counter and check if we've reached 10 records, if so abort + if (++line_count == 10) { + abort = true; } + char_count = 0; // start new record } else { - // add the char to the buffer if recording - if (record && (char_count < MYESP_JSON_LOG_MAXSIZE)) { + // add the char to the buffer if recording, checking for overrun + if (char_count < MYESP_JSON_LOG_MAXSIZE) { char_buffer[char_count++] = c; + } else { + abort = true; // reached limit of our line buffer } } } + + lastPos = eventlog.position(); // remember last position for next cycle + + // calculate remaining pages, as needed for footable + if (eventlog.available()) { + float totalPagesRoughly = eventlog.size() / (float)(lastPos / page); + pages = totalPagesRoughly < page ? page + 1 : totalPagesRoughly; + } else { + pages = page; // this was the last page + } + eventlog.close(); // close SPIFFS - float pages = line_count / 10.0; root["haspages"] = ceil(pages); char buffer[MYESP_JSON_MAXSIZE]; size_t len = serializeJson(root, buffer); - //Serial.printf("\nEVENTLOG: page %d\n", page); // turn on for debugging - //serializeJson(root, Serial); // turn on for debugging + //Serial.printf("\nEVENTLOG: page %d, length=%d\n", page, len); // turn on for debugging + //serializeJson(root, Serial); // turn on for debugging _ws->textAll(buffer, len); _ws->textAll("{\"command\":\"result\",\"resultof\":\"eventlist\",\"result\": true}"); @@ -2281,21 +2395,9 @@ void MyESP::_procMsg(AsyncWebSocketClient * client, size_t sz) { // Check whatever the command is and act accordingly if (strcmp(command, "configfile") == 0) { - if (_ota_pre_callback_f) { - (_ota_pre_callback_f)(); - } - _shouldRestart = fs_saveConfig(root); - if (_ota_post_callback_f) { - (_ota_post_callback_f)(); - } + (void)fs_saveConfig(root); } else if (strcmp(command, "custom_configfile") == 0) { - if (_ota_pre_callback_f) { - (_ota_pre_callback_f)(); - } (void)fs_saveCustomConfig(root); - if (_ota_post_callback_f) { - (_ota_post_callback_f)(); - } } else if (strcmp(command, "status") == 0) { _sendStatus(); } else if (strcmp(command, "custom_status") == 0) { @@ -2310,10 +2412,16 @@ void MyESP::_procMsg(AsyncWebSocketClient * client, size_t sz) { uint8_t page = doc["page"]; _sendEventLog(page); } else if (strcmp(command, "clearevent") == 0) { + if (_ota_pre_callback_f) { + (_ota_pre_callback_f)(); // call custom function + } if (SPIFFS.remove(MYESP_EVENTLOG_FILE)) { _writeEvent("WARN", "system", "Event log cleared", ""); } else { - myDebug_P(PSTR("[WEB] Couldn't clear log file")); + myDebug_P(PSTR("[WEB] Could not clear event log")); + } + if (_ota_post_callback_f) { + (_ota_post_callback_f)(); // call custom function } } else if (strcmp(command, "scan") == 0) { WiFi.scanNetworksAsync(std::bind(&MyESP::_printScanResult, this, std::placeholders::_1), true); @@ -2335,7 +2443,7 @@ void MyESP::_procMsg(AsyncWebSocketClient * client, size_t sz) { bool MyESP::_fs_sendConfig() { File configFile; size_t size; - char json[MYESP_SPIFFS_MAXSIZE] = {0}; + char json[MYESP_SPIFFS_MAXSIZE_CONFIG] = {0}; configFile = SPIFFS.open(MYESP_CONFIG_FILE, "r"); if (!configFile) { @@ -2362,7 +2470,7 @@ bool MyESP::_fs_sendConfig() { size = configFile.size(); // read file from SPIFFS into the same char array - memset(json, 0, MYESP_SPIFFS_MAXSIZE); + memset(json, 0, MYESP_SPIFFS_MAXSIZE_CONFIG); if (configFile.readBytes(json, size) != size) { configFile.close(); return false; @@ -2464,8 +2572,9 @@ void MyESP::_sendStatus() { // create MQTT log JsonArray list = root.createNestedArray("mqttlog"); + // only send Publish for (uint8_t i = 0; i < MYESP_MQTTLOG_MAX; i++) { - if (MQTT_log[i].topic != nullptr) { + if ((MQTT_log[i].type == 1) && (MQTT_log[i].topic != nullptr)) { JsonObject item = list.createNestedObject(); item["topic"] = MQTT_log[i].topic; item["payload"] = MQTT_log[i].payload; @@ -2544,6 +2653,7 @@ void MyESP::_webserver_setup() { return; } if (!index) { + ETS_UART_INTR_DISABLE(); // disable all UART interrupts to be safe _writeEvent("INFO", "system", "Firmware update started", ""); //Serial.printf("[SYSTEM] Firmware update started: %s\n", filename.c_str()); // enable for debugging Update.runAsync(true); @@ -2561,7 +2671,6 @@ void MyESP::_webserver_setup() { if (final) { if (Update.end(true)) { _writeEvent("INFO", "system", "Firmware update finished", ""); - //Serial.printf("[SYSTEM] Firmware update finished: %uB\n", index + len); // enable for debugging _shouldRestart = !Update.hasError(); } else { _writeEvent("ERRO", "system", "Firmware update failed", ""); @@ -2609,11 +2718,9 @@ void MyESP::_webserver_setup() { //static String remoteIP = (String)address[0] + "." + (String)address[1] + "." + (String)address[2] + "." + (String)address[3]; if (!request->authenticate(MYESP_HTTP_USERNAME, _general_password)) { - //_writeEvent("WARN", "system", "New login attempt", remoteIP); return request->requestAuthentication(); } request->send(200, "text/plain", "Success"); - // _writeEvent("INFO", "system", "Login successful", remoteIP); }); _webServer->rewrite("/", "/index.html"); @@ -2639,10 +2746,24 @@ void MyESP::_printHeap(const char * s) { // print MQTT log - everything that was published last per topic void MyESP::_printMQTTLog() { myDebug_P(PSTR("MQTT publish log:")); + uint8_t i; - for (uint8_t i = 0; i < MYESP_MQTTLOG_MAX; i++) { - if (MQTT_log[i].topic != nullptr) { - myDebug_P(PSTR("(%d) [%lu] Topic:%s Payload:%s"), i, MQTT_log[i].timestamp, MQTT_log[i].topic, MQTT_log[i].payload); + for (i = 0; i < MYESP_MQTTLOG_MAX; i++) { + if ((MQTT_log[i].topic != nullptr) && (MQTT_log[i].type == 1)) { + myDebug_P(PSTR(" Topic:%s Payload:%s"), MQTT_log[i].topic, MQTT_log[i].payload); + } + } + + myDebug_P(PSTR("")); // newline + myDebug_P(PSTR("MQTT subscriptions:")); + + for (i = 0; i < MYESP_MQTTLOG_MAX; i++) { + if ((MQTT_log[i].topic != nullptr) && (MQTT_log[i].type == 2)) { + if (_hasValue(MQTT_log[i].payload)) { + myDebug_P(PSTR(" Topic:%s Last Payload:%s"), MQTT_log[i].topic, MQTT_log[i].payload); + } else { + myDebug_P(PSTR(" Topic:%s"), MQTT_log[i].topic); + } } } @@ -2650,16 +2771,18 @@ void MyESP::_printMQTTLog() { } // add an MQTT log entry to our buffer -void MyESP::_addMQTTLog(const char * topic, const char * payload) { +// type 0=none, 1=publish, 2=subscribe +void MyESP::_addMQTTLog(const char * topic, const char * payload, const uint8_t type) { static uint8_t logCount = 0; uint8_t logPointer = 0; bool found = false; - // myDebug("Publish [#%d] %s (%d) %s (%d)", logCount, topic, strlen(topic), payload, strlen(payload)); // for debugging + // myDebug("_addMQTTLog [#%d] %s (%d) [%s] (%d)", logCount, topic, strlen(topic), payload, strlen(payload)); // for debugging // find the topic + // topics must be unique for either publish or subscribe while ((logPointer < MYESP_MQTTLOG_MAX) && (_hasValue(MQTT_log[logPointer].topic))) { - if (strcmp(MQTT_log[logPointer].topic, topic) == 0) { + if ((strcmp(MQTT_log[logPointer].topic, topic) == 0) && (MQTT_log[logPointer].type == type)) { found = true; break; } @@ -2678,12 +2801,12 @@ void MyESP::_addMQTTLog(const char * topic, const char * payload) { if (MQTT_log[logPointer].topic) { free(MQTT_log[logPointer].topic); } - if (MQTT_log[logPointer].payload) { free(MQTT_log[logPointer].payload); } - // add new record + // and add new record + MQTT_log[logPointer].type = type; // 0=none, 1=publish, 2=subscribe MQTT_log[logPointer].topic = strdup(topic); MQTT_log[logPointer].payload = strdup(payload); MQTT_log[logPointer].timestamp = now(); @@ -2703,7 +2826,6 @@ void MyESP::_sendTime() { // bootup sequence // quickly flash LED until we get a Wifi connection, or AP established -// fast way is to use WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + (state ? 4 : 8), (1 << EMSESP_Status.led_gpio)); // 4 is on, 8 is off void MyESP::_bootupSequence() { uint8_t boot_status = getSystemBootStatus(); @@ -2711,7 +2833,9 @@ void MyESP::_bootupSequence() { if (boot_status == MYESP_BOOTSTATUS_BOOTED) { if ((_ntp_enabled) && (now() > 10000) && !_have_ntp_time) { _have_ntp_time = true; - _writeEvent("INFO", "system", "System booted", ""); + if (_general_log_events) { + _writeEvent("INFO", "system", "System booted", ""); + } } return; } @@ -2741,7 +2865,9 @@ void MyESP::_bootupSequence() { // write a log message if we're not using NTP, otherwise wait for the internet time to arrive if (!_ntp_enabled) { - _writeEvent("INFO", "system", "System booted", ""); + if (_general_log_events) { + _writeEvent("INFO", "system", "System booted", ""); + } } } } @@ -2756,10 +2882,6 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char * _telnet_setup(); // Telnet setup, called first to set Serial - // _fs_printFile(MYESP_CONFIG_FILE); // for debugging - // _fs_printFile(MYESP_CUSTOMCONFIG_FILE); // for debugging - // _fs_printFile(MYESP_EVENTLOG_FILE); // for debugging - // print a welcome message myDebug_P(PSTR("\n\n* %s version %s"), _app_name, _app_version); @@ -2814,7 +2936,9 @@ void MyESP::loop() { } if (_shouldRestart) { - _writeEvent("INFO", "system", "System is restarting", ""); + if (_general_log_events) { + _writeEvent("INFO", "system", "System is restarting", ""); + } myDebug("[SYSTEM] Restarting..."); _deferredReset(500, CUSTOM_RESET_TERMINAL); ESP.restart(); diff --git a/src/MyESP.h b/src/MyESP.h index eaf3d3993..fbef5b9e3 100644 --- a/src/MyESP.h +++ b/src/MyESP.h @@ -9,7 +9,7 @@ #ifndef MyESP_h #define MyESP_h -#define MYESP_VERSION "1.2.0" +#define MYESP_VERSION "1.2.6" #include #include @@ -87,7 +87,7 @@ extern struct rst_info resetInfo; #define MQTT_MAX_PAYLOAD_SIZE 500 // max size of a JSON object. See https://arduinojson.org/v6/assistant/ #define MQTT_MAX_PAYLOAD_SIZE_LARGE 2000 // max size of a large JSON object, like for sending MQTT log #define MYESP_JSON_MAXSIZE 2000 // for large Dynamic json files -#define MYESP_MQTTLOG_MAX 20 // max number of log entries for MQTT publishes +#define MYESP_MQTTLOG_MAX 40 // max number of log entries for MQTT publishes and subscribes #define MYESP_JSON_LOG_MAXSIZE 300 // max size of an JSON log entry // Internal MQTT events @@ -139,7 +139,9 @@ PROGMEM const char * const custom_reset_string[] = {custom_reset_hardware, cus #define CUSTOM_RESET_MAX 5 // SPIFFS -#define MYESP_SPIFFS_MAXSIZE 800 // https://arduinojson.org/v6/assistant/ +// https://arduinojson.org/v6/assistant/ +#define MYESP_SPIFFS_MAXSIZE_CONFIG 800 // max size for a config file +#define MYESP_SPIFFS_MAXSIZE_EVENTLOG 20000 // max size for the eventlog in bytes // CRASH /** @@ -212,9 +214,10 @@ typedef enum { // for storing all MQTT publish messages typedef struct { - char * topic; - char * payload; - time_t timestamp; + uint8_t type; // 0=none, 1=publish, 2=subscribe + char * topic; + char * payload; + time_t timestamp; } _MQTT_Log; typedef std::function mqtt_callback_f; @@ -291,7 +294,6 @@ class MyESP { // Crash void crashClear(); void crashDump(); - void crashTest(uint8_t t); void crashInfo(); // general @@ -317,9 +319,10 @@ class MyESP { char * _mqttTopic(const char * topic); // mqtt log - _MQTT_Log MQTT_log[MYESP_MQTTLOG_MAX]; // log for publish messages - void _printMQTTLog(); - void _addMQTTLog(const char * topic, const char * payload); + _MQTT_Log MQTT_log[MYESP_MQTTLOG_MAX]; // log for publish and subscribe messages + + void _printMQTTLog(); + void _addMQTTLog(const char * topic, const char * payload, const uint8_t type); AsyncMqttClient mqttClient; // the MQTT class uint32_t _mqtt_reconnect_delay; @@ -374,14 +377,16 @@ class MyESP { bool _changeSetting(uint8_t wc, const char * setting, const char * value); // fs and settings - void _fs_setup(); - bool _fs_loadConfig(); - bool _fs_loadCustomConfig(); - void _fs_printFile(const char * file); - void _fs_eraseConfig(); - bool _fs_writeConfig(); - bool _fs_createCustomConfig(); - bool _fs_sendConfig(); + void _fs_setup(); + bool _fs_loadConfig(); + bool _fs_loadCustomConfig(); + void _fs_eraseConfig(); + bool _fs_writeConfig(); + bool _fs_createCustomConfig(); + bool _fs_sendConfig(); + bool _fs_validateConfigFile(const char * filename, size_t maxsize, JsonDocument & doc); + bool _fs_validateLogFile(const char * filename); + fs_loadsave_callback_f _fs_loadsave_callback_f; fs_setlist_callback_f _fs_setlist_callback_f; @@ -395,11 +400,12 @@ class MyESP { char * _app_updateurl; bool _suspendOutput; bool _general_serial; - unsigned long _getUptime(); - char * _getBuildTime(); + bool _general_log_events; char * _buildTime; bool _timerequest; bool _formatreq; + unsigned long _getUptime(); + char * _getBuildTime(); bool _hasValue(char * s); void _printHeap(const char * s); diff --git a/src/custom.htm b/src/custom.htm index 01ddd4aed..d7ca2187c 100644 --- a/src/custom.htm +++ b/src/custom.htm @@ -122,19 +122,6 @@
-
- - - - -
-