Ankündigung

Einklappen
Keine Ankündigung bisher.

Brunner EOS 7 mit BHZ 3 an KNX anbinden

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Brunner EOS 7 mit BHZ 3 an KNX anbinden

    Hallo in die Runde,

    mich nervt seit geraumer Zeit, dass unser Kaminofen seine Daten nicht mit KNX teilen will. Habe beim Einbau damals schon gesehen, dass Brunner den CAN Bus nutzt und es gibt ein paar kleine spärliche Informationen hier im Forum und im Loxone Forum.
    Jetzt ist Winter und ich will die Temperaturen auf dem Bus haben, also hab ich mich entschieden das ganze mal anzugehen und zu gucken wie weit ich komme.
    Vielleicht kann ich den einen oder anderen dazu ermutigen mitzumachen oder es sind schon Leute dabei, die ihr Wissen gerne teilen wollen. Jedenfalls wollte ich mal alles in einem Thread sammeln (hab keinen gefunden in dem das schon passiert).

    Ich probiere es aktuell auf Basis von Arduino und werde dann wahrscheinlich den Konnekting Busankoppler für den KNX-Zugang nutzen, aber das soll hier nicht das Thema sein.
    An den Bus kann jeder recht einfach ran, das schwierige ist die Entschlüsselung der Nachrichten.
    Evtl. ändern diese sich auch von Version zu Version, denn im Loxone Forum hat jemand eine ID für Aussentemp Preisgegeben, die meine Anlage nicht hat.
    Ich bin gespannt.

    Gebe nat. keine Gewähr auf die Aussagen hier, alles meine persönliche Erfahrung oder ggf. von anderen, falls eine Diskussion startet. Nachahmung auf eigene Gefahr.


    Hardware:
    • ein Breadboard (hatte ich noch rumliegen)
    • ein Lötkolben (die China Nanos brauchen noch Pinheader, sind aber im Lieferumfang)
    • Arduino Nano (billige Chinaversion) - CH340 USB Chip und ATMega328P - Kosten 16€ im 5er Pack
    • CAN Bus Shield (ebenfalls Chinaversion) - MCP2515 und TJA1050 8MHz - Kosten 8€ einzeln
    • ein paar Verbindungskabel (hatte ich auch noch)
    • ein altes KNX Kabel, das ich als CAN Bus Verlängerung vom Brunner Display benutzt habe.

    Anfangsschwierigkeiten:
    • Wenn das Display nicht mehr reagiert einfach den 120Ohm Abschlusswiderstand checken, dieser muss mit am CAN Shield stecken
    • der Arduino braucht die richtigen Daten zum Verbinden (Baud Rate muss im Script identisch sein mit dem Serial Monitor, die Taktrate des Shields muss korrekt sein, bei mir 8MHz), sonst sieht man nur Schwachsinn im Monitor
    • USB Treiber von der Arduino IDE klappt evtl nicht -> CH340 suchen und nachinstallieren
    Anschlussdiagramm habe ich von der folgenden Seite genutzt:
    https://circuitdigest.com/microcontr...e-with-arduino



    Verbindung funktioniert, ich werde zugespammt mit Daten im Format:
    ID - DLC - Data

    ID ist die Nachrichten ID. Auf dem CAN Bus ist es wurscht von wem eine Nachricht kommt. Der Inhalt zählt. Daher sollte jede ID für eine Funktion stehen (zB Brennraumtemperatur).
    DLC ist Data Length Code, also wie viele Byte Daten hängen an
    Data ist klar.

    Meine IDs fangen alle mit 8 oder 9 an, ich habe die EOS 7 Nr.1 und BHZ 3
    //edit: scheinbar hab ich eine schlechte Bibliothek verwendet. Mit einer anderen komme ich jetzt auch auf IDs die zB mit 1C anfangen wie tillscs im Loxforum https://www.loxforum.com/forum/germa...264#post189264


    to be continued...
    Zuletzt geändert von Freeman; 16.11.2019, 19:59.

    #2
    zwei IDs schon mal als Türkontakt erkannt... warum auch immer der Türkontakt 2 IDs hat.

    eine ist bei geschlossener Tür 0 und bei offener 1
    die andere ist bei geschlossener Tür 2 und bei offener 1

    Kommentar


      #3
      Ich meine, dass unser Brunner Heizeinsatz 2 Türschalter hat (vermutlich aus Sicherheitsgründen). Eventuell ist das bei dir auch so und beide werden separat gemeldet.

      Gruß

      Jochen

      Kommentar


        #4
        Hätte ich bei uns jetzt auch vermutet, allerdings hab ich den einen links unten an der Tür bei offener Tür manuell gedrückt und beide Werte haben sich verändert. Vielleicht ist da ne Kontrollschleife drin als Sicherheit.

        Habe jetzt Brennraum und Kesseltemperatur identifizieren können.

        Vielleicht weiss ja jemand warum die Kollegen im Loxone Thread den in dezimal umgerechneten Hexwert mit 0,000390625 multiplizieren, um auf die richtige Temperatur zu kommen. Die Erklärung dazu verstehe ich nicht. Aber das Ergebnis passt

        Kommentar


          #5
          Erste Temperaturen hab ich erraten und in einem kleinen AutoIT Script angezeigt.
          Dachte eigentlich ich brauche länger dafür.


          brunner_erste_tems.PNG

          Kommentar


            #6
            Update:

            Habe jetzt noch weitere Temperaturen, wie die Aussentemperatur erhalten.
            Meine ID ist leider anders, als die ID aus dem Loxforum. ggf. ändert sich das nach EOS/BHZ Version oder einfach nach dem Kontakt an dem der Sensor hängt.

            Habe jetzt auch verstanden, warum man mit 0,000390625 multipliziert. Im Loxofum steht zwar eine Erklärung, aber ich hatte sie nicht wirklich verstanden.

            Bsp.: Messwert in Hex 000A7300
            Wie tillsc im Loxforum schon geschrieben hat nutzt Brunner das letzte Byte nicht, also wäre der Messwert eher: 000A73 in Dec 2675
            Das ganze durch 10 ergibt 267,5 °C
            Die korrekte Temperatur.
            Man kann also einfach A7300 / 2560 teilen
            oder man macht A73 / 10
            wenn man multipliziert, dann nat. mit dem Kehrwert, wie wir in der Schule gelernt haben, also 1 / 2560 = 0,000390625

            Wie habe ich meine Werte jetzt herausgefunden:
            Code zum Auslesen mit dem Arduino:

            Code:
            // Copyright (c) Sandeep Mistry. All rights reserved.
            // Licensed under the MIT license. See LICENSE file in the project root for full license information.
            
            #include <CAN.h>
            
            void setup() {
              Serial.begin(115200);  // WICHTIG! Anpassen auf die Baudrate im Monitor, sonst sieht man nur Mist
              while (!Serial);
            
              Serial.println("CAN Receiver");
            
              CAN.setClockFrequency(8E6);  // WICHTIG! Da ich einen billigen CAN Bus Chip hab, an dem nur ein 8Mhz Quartz hängt, muss die ClockFrequency auf 8E6 geändert werden. Default ist 16E6 für 16 Mhz
              if (!CAN.begin(125E3)) {       // Bus Geschwindigkeit auf 125 kbps
                Serial.println("Starting CAN failed!");
                while (1);
              }
            }
            
            void loop() {
              // try to parse packet
              int packetSize = CAN.parsePacket();
             
              Serial.print(CAN.packetId(), HEX);   // Message ID
              Serial.print(";");                                   // für Excel
              Serial.print(packetSize);                    // eigentlich unwichtig
              Serial.print(";");
              while (CAN.available()) {                  // Da die Daten Byteweise gelesen werden eine Schleife
                      printHex(CAN.read(), 2);         // Die Funktion hab ich aus nem Forum, damit wird sichergestellt, dass führende Nullen geschrieben werden und man in Excel nicht durcheinanderkommt, wenn mal 00A30 da steht, obwohl es 0000A300 sein sollte
              }
              Serial.println();
              }
            }
            
            
            unsigned int printHex(unsigned int num, int precision) {
                 char tmp[16];
                 char format[128];
            
                 sprintf(format, "%%.%dX", precision);
            
                 sprintf(tmp, format, num);
                 Serial.print(tmp);
            }
            Im Serial Monitor hab ich dann die Zeitstempel angeschaltet und ca. 20 Minuten gewartet, dann war der Puffer voll.
            Autoscroll aus -> Strg+A, Strg+C und ab in Excel und eingefügt. Dann noch bei den Einfügeoptionen den Assistenten ausgewählt und mit ihm die Daten formatiert
            So hatte ich jetzt 4 Spalten
            Datum/Uhrzeit - ID - DLC - Data

            Die komplette Tabelle in eine Pivot umwandeln -> im Pivot erstellen Dialog ganz unten das Häkchen bei "dem Datenmodell hinzufügen" anklicken

            ID als Zeile
            Data als Wert -> Wertfeldoptionen und in der Liste der Aggregationsfunktionen ganz unten "Diskrete Anzahl"
            in der Tabellenspalte von ID der Pivottabelle dann Wertefilter -> Größer als 3 und man bekommt alle IDs angezeigt, die in diesen ca. 20 Minuten mehr als 3 Änderungen auf den Bus geschrieben haben... das waren bei mir ca. 15-18 Stück während eines Heizvorgangs. Damit war dann auch recht flott klar welche ID die des Brennraums und des Kessels war und dann hab ich in einem kleinen AutoIT Script einfach alles verifiziert.
            Man kann auf dem Brunner Display in die Config -> Bedienteil -> Sensoren/Offsets und sieht alles in einer Liste. Das geht sowohl für EOS als auch Heizung einmal.

            //edit
            Habe in besagter Sensorübersicht 2 Türkontakte gefunden, einer NC und einer NO
            Das erklärt dann die 2 IDs
            Zuletzt geändert von Freeman; 17.11.2019, 13:00.

            Kommentar


              #7
              Hallo
              mein Brunner Kamin hat zwei Türen ( Tunnelkamin ), beide Türen sind mit einem Kontakt kontrolliert. Gutes Projekt, habe auch die EOS 6.

              Gruss Remo

              Kommentar


                #8
                eventuel könnten die Daten mit einem ESP8266 per TCP (WLAN) an eine HA System weitergereicht werden ( in meinem Fall FHEM )
                -> http://scottsnowden.co.uk/esp8266-mc...-wifi-gateway/

                Kommentar


                  #9
                  Ich bin einer der Leute aus dem Loxone-Forum (bin allerdings kein Loxone-Mensch sondern auch KNXler). Ich habe eine EOS7 und eine BHZ3.

                  Was habe ich gemacht?

                  Ich habe auch den Brunner CAN-Bus angezapft. Dafür habe ich einen Raspberry+CAN-Board benutzt: https://www.amazon.de/gp/product/B01...?ie=UTF8&psc=1
                  Die Verbindung mit dem CAN-Bus lief recht unkompliziert und ich hatte schnell die CAN-Nachrichten im System. CAN-Nachrichten zurück schreiben tue ich aktuell nicht und ich plane es auch nicht wirklich.

                  Dann habe ich eine ganze Reihe von kleineren Scripten gebaut, die im folgenden beschrieben sind. Unterm Strich läuft das ganze bei mir seit einigen Monaten recht unkompliziert und ich habe fast alle Werte aus der BHZ und EOS live in meiner Heimautomatisierungslösung.

                  Was waren meine ersten Erkenntnisse?

                  Brunner hat, anders als beispielsweise die Automotive-Industrie, eine recht seltsame Auffassung von CAN. So hat man normalerweise innerhalb einer CAN-Nachricht (die durch den Objekt-Identifier benannt wird) mehrere "Signale". Ein Signal in einer Nachricht besteht also aus einer Zuordnung bestimmter Bits/Bytes der Daten der Nachricht zu eben diesem Signal.
                  Das Konzept der "Signale" scheint Brunner nicht zu kennen. Brunner hat, soweit ich das bei meiner BHZ3 sehe, immer nur ein einziges Signal pro Nachricht. Die einzige Besonderheit ist, dass Brunner das letzte Byte der Nachricht immer leer lässt. Das wurde ja von Freeman bereits beschrieben.

                  Ausserdem hat Brunner eine etwas eigenwillige Auffassung von Datentypen. Im Grunde verwenden die nur Integer und niemals Floats oder Bools. D.h. "True" ist "1" und "False" ist "0". Fließkommazahlen werden meist mit 10 multipliziert und zu Integer konvertiert, um eine einzelne Nachkommastelle abbilden zu können.
                  Wenn man das einmal begriffen hat lassen sich recht leicht viele der Nachrichten/Signale "echten" Daten aus der BHZ zuordnen. Das habe ich bereits für meine Anlage (BHZ3/EOS7) gemacht. Was ich aus dem Loxone-Forum weiß ist dass ältere BHZs andere CAN-Nachrichten verwenden. Mich würde allerdings sehr wunden, wenn meine Erkenntnisse jetzt nicht zu denen von Freeman (der ja auch BHZ3+EOS7 hat) passen würden.

                  Falls das jemanden Interessiert: Ich habe dazu ein kleines Python-Script gebaut, um verläufe von Werten über die Zeit grafisch darstellen zu können oder Nachrichten nach ihren aktuellen Werten filtern zu können etc: https://github.com/tillsc/python-can-plotter

                  Was habe ich mit meinen Erkenntnissen aus dem Reverse-Engineering gemacht?

                  Es gibt mehrere Standard-Formate, um CAN-Busnachrichten beschreiben zu können. Meine "Kontakte" zur Automotive-Branche sagten mir, dass DBC wohl ein ganz gutes Format dafür sei: http://socialledge.com/sjsu/index.php/DBC_Format

                  Ich habe also meine Erkenntnisse in ein CSV eingetragen und ein kleines Script zur Konvertierung nach DBC geschrieben. Das Ergebnis findet man hier: https://github.com/tillsc/brunner_can (die DBC-Files liegen hier: https://github.com/tillsc/brunner_can/tree/master/out)

                  Was kann man jetzt mit den DBC-Files machen?

                  DBC-Files sind gedacht dazu beispielsweise C-Code zu generieren. Ich benutze aber eine Python-Bibliothek, die CAN-Tools: https://pypi.org/project/cantools/
                  Das funktioniert bei mir ganz wunderbar. D.h. man lädt die DBC-Files und bekommt in Python dann vollständig "entpackte" und dekodierte Daten aus dem CAN-Bus.
                  Was man dann in Python mit den Daten macht ist im Prinzip total egal.

                  Was habe ich mit den Daten gemacht?

                  Ich habe mich dazu entschieden die Daten per MQTT in meine Heimautomatisierungslösung zu schicken. Dazu habe ich ein kleines generisches Tool geschrieben, dass DBC-Files nimmt, um CAN-Nachrichten "zu verstehen" und diese dann nach MQTT schreibt. Das Python-Programm kann man hier finden: https://github.com/tillsc/can2mqtt . Ich benutzte eine etwas sauberere Version davon, bin aber noch nicht dazu gekommen das zu veröffentlichen. Falls Interesse besteht kann ich das sehr gerne machen.

                  Was könnte jetzt jemand anderes mit meinen Erkenntnissen machen?

                  Man könnte einfach meine can2mqtt-Lösung nehmen, die DBC-Files rein legen, etwas Konfiguration anpassen und fertig. Für Support stehe ich gerne zur Verfügung.

                  Falls jemand weitere Erkenntnisse bezüglich der CAN-Daten hat würde ich die sehr gerne in die DBC-Files mit aufnehmen. Entweder per Pull-Request oder meinet wegen auch per Zuruf/Mail. Sehr gerne würde ich auch Daten zu anderen Brunner-Produkten z.B. alten BHZ-Versionen aufnehmen. Falls wirklich ein Interesse besteht können wir auch keine eine "neutrale" Github-Orga aufmachen. Ich hänge nicht daran, das unter meinem Account zu veröffentlichen.

                  Falls mich jemand davon überzeugt, dass DBC eine blöde Idee ist, baue ich den Konverter auch gerne auf ein anderes/besseres Format um. Falls aber nicht, fände ich es cool, wenn nicht jeder irgend etwas proprieträres bastelt, sondern wir ein "Standard-Format" benutzen, um den Brunner CAN-Bus gemeinsam zu dokumentieren.

                  Für Experimente in Richtung C oder sonstiger Sprachen stehe ich auch gerne zur Verfügung. Ich habe Python genommen, da es mir als die einfachste Möglichkeit erschien schnell und unkompliziert zu Ergebnissen zu kommen. Ich hänge aber weder an Python noch finde ich es besonders gut, dass in meinem Keller 24/7 ein Mini-PC läuft, der letztenendes doch recht wenig zu tun hat und die ganze Zeit Strom zieht. Das hat für mich aber aktuell nicht die höchste Priorität.

                  Kommentar


                    #10
                    Ach so: Falls Ihr Themen/Fragen/Bug direkt zu meinen Tools bzw. den DBC-Files habt, macht am besten direkt auf Github ein Ticket auf. Dann verteilen wir die Informationen nicht so über mehrere Foren.

                    Kommentar


                      #11
                      Zitat von appi Beitrag anzeigen
                      eventuel könnten die Daten mit einem ESP8266 per TCP (WLAN) an eine HA System weitergereicht werden ( in meinem Fall FHEM )
                      -> http://scottsnowden.co.uk/esp8266-mc...-wifi-gateway/
                      ja das hab ich auch noch aufm schirm. das hat thesing hier im forum sogar mit nem eigenen KNX-Stack für KNXoverIP gelöst https://knx-user-forum.de/forum/%C3%...66-knx-mit-ets

                      ich denke mein arduino nano wird dafür aber nicht die kapazität haben... der samd ist schon etwas leistungsstärker als der atmega328p
                      werde mir tills projekt mal anschaun und ggf auf meinen Pi umschwenken. der steht sowieso im serverschrank in der nähe der BHZ und langweilt sich mit seinen bisherigen aufgaben

                      die arduinos kommen dann mit BCU in ein projekt mit Temp/Feuchtesensoren.

                      Kommentar


                        #12
                        so... hab mal n bisschen drübergeschaut tillsc ... Stichprobenartig passen die IDs bei mir.
                        Ich hab jetzt den Arduino mit CAN Bus IF an meinen Pi per USB geklemmt, da ich keine Lust hatte mein CAN IF umzulöten. (Das Board liefert wohl 5V auf die GPIOs des Pi und die können keine 5V. Da der Arduino 3€ und das CAN IF 8€ gekostet haben verschmerzbar. 40€ waren mir zum Testen zu viel)

                        Ergibt sich natürlich jetzt das Problem, dass deine Scripts bei mir nicht 100 pro klappen.
                        Ich bekomme über die Serielle Schnittstelle die Daten in der Form:
                        Code:
                        ID;DLC;Data
                        Ich werd jetzt mal gucken, was ich von deinen Scripts verwenden kann. Am liebsten wäre mir nat. alles
                        aber zur Not kann ich die Daten auch mittels HTTP GET auf die Edomi bringen. Das ist evtl. bei mir sinnvoller als MQTT. Ich glaub der MQTT Baustein in Edomi ist Beta.

                        Habe die folgenden anderen/neuen IDs... mal mit Fragezeichen
                        alles andere stimmt überein.

                        Bei mir ist der Türkontakt jeweils:
                        1CB86007 Türkontakt NC
                        1CB8A014 Türkontakt NO
                        Bezeichnung habe ich aus den Infos im Display "angenommen"
                        1CB86011 Platine EOS
                        Zuletzt geändert von Freeman; 18.11.2019, 16:16.

                        Kommentar


                          #13
                          Das müsste etwa so gehen:


                          Code:
                          import cantools
                          db = cantools.database.load_file('bhz3.dbc')
                          db.decode_message(id, data)

                          Kommentar


                            #14
                            aus irgendeinem Grund meint er, dass die cantools nicht installiert sind. hab sie jetzt schon in 3 verschiedene Versionen installiert...
                            aber muss gestehen, dass ich mit python keine Erfahrung hab


                            //edit hab den Fehler gefunden... per sudo das Script ausführen aber als User die tools installieren ist wohl dumm...
                            Zuletzt geändert von Freeman; 18.11.2019, 17:56.

                            Kommentar


                              #15
                              tillsc
                              klappt leider nicht
                              Code:
                              Traceback (most recent call last):
                                File "/home/pi/.local/lib/python3.5/site-packages/cantools/database/can/database.py", line 377, in decode_message
                                  message = self._frame_id_to_message[frame_id_or_name]
                              KeyError: '0x1CB8C000'
                              
                              During handling of the above exception, another exception occurred:
                              
                              Traceback (most recent call last):
                                File "serialTest.py", line 14, in <module>
                                  db.decode_message(msgID, data)
                                File "/home/pi/.local/lib/python3.5/site-packages/cantools/database/can/database.py", line 379, in decode_message
                                  message = self._name_to_message[frame_id_or_name]
                              KeyError: '0x1CB8C000'
                              auch wenn die ID in dez oder ohne 0x davor ankommt... immer der gleiche Fehler
                              ne Idee?


                              Code:
                              import serial
                              import cantools
                              
                              db = cantools.database.load_file('bhz3.dbc')
                              s = serial.Serial('/dev/ttyUSB0', 115200)
                              while True:
                                  if s.inWaiting()>0:
                                      inputValue = s.readline().strip()
                                      array = str(inputValue).split(';')
                                      if len(array) == 3:
                                          msgID = array[0]
                                          data = array[2].rstrip("'")
                                          #print(msgID + " - " + data)
                                          db.decode_message(msgID, data)
                              Zuletzt geändert von Freeman; 18.11.2019, 19:52.

                              Kommentar

                              Lädt...
                              X