Stiebel-Eltron mit CAN-Bus unter Verwendung eines C++-Wrappers

Begonnen von juerg5524, 14 Oktober 2015, 13:43:31

Vorheriges Thema - Nächstes Thema

intershopper

Ich habe weitere Werte rechnerisch ermittelt:
Wärmstrom über den WP_WASSERVOLUMENSTOM l/min * 4,18/60 * (VLtemp -RLtemp)

WAERMELEISTUNG {
  sprintf("%.2f",(ReadingsVal($NAME,"WP_WASSERVOLUMENSTROM",0) * (4.18 / 60) * (ReadingsVal($NAME,"WPVORLAUFIST",0) -
  ReadingsVal($NAME,"RUECKLAUFISTTEMP_WP_IWS",0)))*1)
}

damit kann man in den Diagramm sehr schön die WärmeLeistung ablesen und mit der aufgenommen elektrischen Energie vergleichen. Ich greife die Leistung direkt vom Drehstromzähler ab und kann somit den realen COP errechnen.

COP_real = WAERMELEISTUNG / (aktuelle Leistung Drehstromzähler)

Gruß Frank

Araktos

#136
Hallo zusammen,

ich bin recht frisch in der FHEM Welt, was Modulprogrammierung und Perl angeht. Ich habe aber schon länger die Programme von Jürg (can_prog) bei mir im Einsatz
und wollte dies nun auch in FHEM einbinden.

Mein Aufbau:
Ich habe eine Stiebel Eltron WPL18 als Außengerät, WPM2 mit einem Heizkreis. Ein RaspberryPi3 + PiCAN2 dient dabei als Schnittstelle. Hier ist auch FHEM installiert.
Da ich sporadisch Probleme mit der Anlage habe und nicht ständig in den Keller laufen wollte, habe ich mit den can_prog und der ComfortSoft
die Möglichkeit Fehler auszulesen und Daten aufzuzeichnen. 

FHEM läuft auch auf dem RaspPi und so kam auch das 50_Elster.pm Modul zur Installation. Die Änderungen und Anpassungen in diesem Forum wurden eingepflegt,
das Modul funktioniert... Mir ist aber aufgefallen das die Systemlast am RaspPi deutlich angestiegen ist.
Ich habe mich auf die Suche gegeben und das Modul 50_Elster.pm grundliegend geändert.

Das würde ich gerne hier vorstellen.

Vorher:
Das Modul registriert sich in der $readyfnlist und somit wird von FHEM die Elster_Ready($) aufgerufen. Diese Funktion soll nun die (fehlende) Verbindung aufbauen.
Da die Verbindung bereits in der Elster_Define($) aufgebaut wurde und die Elster_Ready($) nicht richtig beendet wird, bleibt es in dieser schleife...
Zusätzlich wird bei jeden durchlauf die Elster_Read($) aufgerufen, welche Daten vom C++ Wrapper empfängt und in Readings schreibt.
Bei vielen Readings geht das ordentlich auf die CPU. Interhopper hat dem bereits entgegengewirkt, indem nur Readings geschrieben werden,
die sich auch geändert haben. Das entlastet das System, da nicht mehr so viele events gefeuert werden.

Beschreibung (Nachher):
Das Modul wurde nun wie folgt angepasst, so dass es jetzt stabiler und Ressourcenschonender laufen sollte.
Das Modul verwendet nun einen Timer, welcher in regelmäßigen Abständen die Daten abholt. Der Timer lässt sich bei der Definition übergeben.
Define Heizung Elster can0 [Timer]
Dieser wird in Sekunden angegeben und ist optional. Wird kein Wert übergeben, so wird 10s als default angenommen. Das lässt sich unter DEF später auch noch ändern.

Nach dem hinzufügen versucht das Modul über den C++ Wrapper eine Verbindung aufzubauen. Gelingt dies, wird STATE=connected gesetzt und der Aktualisierungtimer wird gestartet.
Meldet das C++ Wrapper einen Fehler, wird nach 30s versucht die Verbindung erneuert aufzubauen. STAT wird solange auf disconnected gesetzt.

Steht die Verbindung, wird die Elster_Read($) (und noch weitere Funktionen) nach Ablauf des Timers aufgerufen und die Daten verarbeitet. Die Daten kommen so rein wie diese auf dem Bus auftauchen.
Wenn sehr viele Daten kommen, steigt auch hier die CPU last an, da ich den code von Interhopper wieder entfernt habe. Besser ist es, wenn wir das Attribut event-on-change-reading  [.*] setzen. Das hat den gleichen Effekt. Der Benutzer hat aber mehr Kontrolle...

Attribute:
Es sind auch Attribute hinzugekommen.


  • autoAddReadings [on:off]
    Wenn nicht vorhanden oder auf [on] gestellt, werden alle Readings die in der Liste Elster_gets stehen, automatisch hinzugefügt
    oder aktualisiert sobald diese auf dem Bus auftauchen. Das könnten auch mal 300 Readings sein...
    Möchte man das nicht, so das Attribut auf [off] stellen.

  • autoPullReadings [Reading1 Reading2 ...]
    erwartet eine mit Leerzeichen getrennte Liste von Readings. Diese werden bei jedem durchlauf angefordert [get] und aktualisiert.
    Hier sind (noch) keine Redex ausdrücke erlaubt! Die Readings müssen auch in der Elster_gets enthalten sein!

Weitere Funktionen


  • GET [readingname]
    Über get [readingname] können Werte angefordert werden. Es wird automatisch das Reading angelegt oder aktualisiert.
    Sind diese einmal in der Readings Liste, werden diese aktualisiert, wenn neue daten empfangen werden. Damit lässt das Modul
    sehr leicht auf die eigenen Bedürfnisse anpassen, ohne hunderte uninteressanter Readings im Device zu haben.

  • GET _Fehlerliste
    Fehler werden abgerufen und formatiert im Reading 1_FehlerListe abgelegt.

  • GET _Leistung
    Leistungsdaten, die der WPM  bereitstellt, werden abgerufen und in Readings abgelegt.

  • GET _Systemzeit
    Datum und Uhrzeit des WPM.

  • SET RemoveReadingst
    Durch ein SET wird ein vorhandenes Reading entfernt. Das gleiche Ergebnis erzielt man durch die FHEM Funktion deletereading[modul][reading].

Das ist der aktuelle Stand.

ToDo´s:


  • Das Modul soweit entwickeln, das es keine ,,händische" eingriffe mehr in die 50_Elster.pm notwendig sind und alles über Parameter erfolgen kann.

  • Das Modul soweit stabil bekommen, was die verschiedenen Schnittstellen angeht. Ich konnte das nur an der PiCAN2 Testen.

  • Noch die eine oder andere Funktion einbauen; zb. Formatierte Ausgabe der Verbrauchszahlen aus dem WPM2.

  • Modul Dokumentation erstellen

Bei mir kann ich zurzeit keine Werte über den CAN Bus setzen, auch nicht über ComfortSoft.
Früher ging das.
Ich weiß noch nicht, woran das liegt. So ist die SET Funktion im Modul nicht getestet!!!

Ich hoffe das sich ein paar Leute finden, die das Modul aufspielen und Testen könnten. Freu mich auf Verbesserungsvorschläge oder Feedback.
Bitte beachtet das die Anleitungen die bei den can_progs beiliegen immer noch gültig sind und eventuell Anpassungen an dem Modul erfordern.

!!! Die Verwendung geschieht auf eigene Gefahr !!!

Gruß Niko.


Update


  • 09.02.2021 : Fehler beseitigt, dass das Attribut autoAddReadings nicht funktioniert hat.

  • 17.02.2021 : Zwei weitere GET´s (_Leistung, _Systemzeit) hinzugefügt.


Ratzefummel

Hallo Araktos,

ich habe Deine neue 50_Elster.pm seit gestern Abend im Einsatz.
Das Modul funktioniert bisher einwandfrei und macht genau das, was Du beschrieben hast. GET-Werte werden dem Timer entsprechend abgefragt und neue Readings erscheinen, wenn man es so möchte. Die Fehler-Liste ist super übersichtlich und nützlich. Ich werde weiter ausgiebig testen.

Anregung: Nicht jeder Wert muss unbedingt im Timer-Takt abgefragt werden. Beim Fehlerspeicher z.B. würde mir ein tägliches Intervall genügen. Vielleicht könnte man dem autoPullReadings Attribut neben dem Namen noch ein Intervall mitgeben. Ohne Intervall in Attribut gilt der Timer des DEFINE.  Z.B. attr autoPullReadings Name1:60 Name2 Name3:360
Es würde reichen, wenn die Fehlerliste nur die Fehler anzeigt und nicht alle leeren Slots.

Klasse Arbeit. Hut ab!!! Ich bin begeistert.
Danke

Gruß Frank

Araktos

Hallo Ratzefummel,

vielen Dank für das Feedback.

Ich habe noch ein wenig weiter an dem Modul geschraubt und 2 weitere Funktionen hinzugefügt. Siehe oben in meinem Post.

Zu deinen Anregungen:
Die Funktionen _Fehlerliste, _Leistung, _Systemzeit sind von dem Intervall nicht betroffen. Allein bei der _Fehlerliste schon über 100 Werte gelesen werden, habe ich darauf verzichtet. Mein Gedanke war die Fehler über ein at einmal am Tag abzurufen, oder "händisch" im Device.
Ich habe auch entfernt, das leere Zeilen angezeigt werden.

Das gleiche gilt auch für die _Systemzeit und _Leistungsdaten.

Verschiedene Intervalle bei den verschiedenen Readings ist mit deutlich mehr Aufwand verbunden. Ich müsste für theoretisch unendlich viele Readings
Timer vorsehen und diese verwalten...
Wenn es dazu bedarf gibt, kann ich mich gerne damit beschäftigen :)

Als Workaroung verwende ich FHEM Funktionen, die im Modul schon vorhanden sind:
event-on-change-reading .*  -- um weniger Events zu erzeugen,
event-min-interval [reading:int]  -- hab ich selber nicht, soll aber das machen, was du oben gemeint hats,
DBLogExklusive .* / DBLogInclusive [reading:int], [reading:int], ..  -- für Readings die ich in eine Datenbank logge.

Ich bin auch immer für Vorschläge offen und lasse mich auch gerne umstimmen ;)


Ich habe auch in der ElsterTable.inc einige Fehler gefunden und korrigiert. Ich hänge diese Datei ebenfalls oben bei.

Da bin ich mir noch nicht ganz sicher, ob ich diese Dateien auch zum Download anbieten darf. Wenn du die dies Datei verwenden möchtest,
muss diese in das can_progs kopiert werden und dann alle programme neu kompiliert werden.
Auch das mit dem Scannen und Analysieren, muss erneuert gemacht werden...

Gruß Niko.

N(Zgazucs

#139
Hallo,

ich bin neu hier und stoße wegen meiner Tecalor TSBC 200, TTL 15 ACS, WPM4 und FEK zu Euch. Dazu möchte ich mit Euch meine ersten Eindrücke zum CAN-Setup teilen. Fragen werden sicherlich in Zukunft von mir noch kommen.

Den CAN Bus zapfe ich z.Zt. direkt am FEK ab und nutze dazu einen Raspberry 4B mit PiCAN2 Erweiterung und Raspberry Pi OS Lite. Aussagen im Netz, dass PiCAN2 mit einem Raspberry 4 nicht funktioniert, sind falsch.

Linux raspberrypi 5.10.17-v7l+ #1403 SMP Mon Feb 22 11:33:35 GMT 2021 armv7l GNU/Linux


Unter Hinzufügen von

dtparam=spi=off
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi0-2cs


nach

/boot/config.txt

wird der PiCAN2 erkannt und mit dem Anlegen des can0 interfaces in

/etc/network/interfaces

mit folgendem Inhalt

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

# CAN-Bus
auto can0
iface can0 can static
  bitrate 50000


wird das can0 interface bei jedem Boot automatisch aktiviert. Ich bitte zu beachten, dass die hier im Forum kolportierte 20000 bit/s Baudrate bei mir nicht funktioniert und ich stattdessen 50000 bit/s Baudrate nutze.

Ein erster Scan mit CAN ID 780 brachte folgendes magere Ergebnis:

pi@raspberrypi:~/can_progs $ ./can_scan can0 780
elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

list of valid can id's:

  100 (8000 = 502-02-)
  401 (8000 = 501-02-)
  500 (4604 = 70-04)



Das Nutzen der Sender CAN ID 680, welche ausdrücklich nicht für WPM3 empfohlen wird, war da ergiebiger:

pi@raspberrypi:~/can_progs $ ./can_scan can0 680
elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

list of valid can id's:

  000 (8000 = not available)
  100 (8000 = 502-02-)
  180 (8000 = 449-04-)
  200 (8000 = 449-04-)
  201 (8000 = 449-04-)
  202 (8000 = 449-04-)
  301 (8000 = 449-04-)
  302 (8000 = not available)
  303 (8000 = not available)
  304 (8000 = 449-04-)
  401 (8000 = 501-02-)
  480 (8000 = 449-04-)
  500 (8000 = 446-04-)
  601 (8000 = 449-04-)
  602 (8000 = not available)
  603 (8000 = not available)
  604 (8000 = 449-04-)
  605 (8000 = 449-04-)
  606 (8000 = 449-04-)


Ein ausführlichen Scan habe ich mit scan.txt angehängt.

Die ersten Fragestellungen, die mich nun umtreiben sind:

  • wie kann ich meine Zirkulationspumpe über CAN schalten
  • zu welchen Geräten gehören die ermittelten CAN IDs

Ich freue mich über Hilfestellung, ansonsten schaue ich mal wie weit ich selber komme und berichte dann hier.

Gruß

Araktos

Hallo N(Zgazucs,

ich habe mir dein scan mal in den Simulator geladen, aber seltsamerweise kann ComfortSoft keine Geräte finden.
Könnest du bei Gelegenheit aus ein scan mit der ID 780 machen. Vielleicht ist da was anders.

Ich habe im Code noch folgendes gefunden was eventuell helfen könnte:


...
my $direkt    = "000";
my $kessel    = "180";
my $bedien_1  = "301";
my $bedien_2  = "302";
my $manager   = "480";
my $heiz      = "500";
my $mischer_1 = "601";
my $mischer_2 = "602";
...


In der Elster Tabelle findet sich diesen Kommentar:

  { "SOFTWARE_VERSION"                                 , 0x019a, 0},
  { "SPEICHER_ZEIT_STATUS"                             , 0x019b, 0},
// HK1 Pumpe:         0x0001
// HK2 Punpe:         0x0002
// Mischer auf:       0x0004
// Mischer zu:        0x0008
// Quellenpumpe:      0x0010
// Solarpumpe:        0x0020
// 2. WE:             0x0040
// Zirkulationspumpe: 0x0080
  { "INFO_TYP"                                         , 0x019c, 0},
  { "MISCHERPARAMETER_ZU"                              , 0x019d, 0},
  { "WW_BETRIEB"                                       , 0x019e, 0},


Der Kommentar bezieht sich auf das Register 0x019c.
Wenn du die Zirkulationspumpe über das Panel ein und ausschalten kannst, würde ich das tun und diesen Wert beobachten.
Wenn es der richtige ist, sollte er sich ändern.
Danach kannst du versuchen über CAN den Wert zu setzen.

Gruß Niko.


N(Zgazucs

#141
Hi Niko,

danke für Dein erstes Feedback. Im Anhang findest Du die Scans mit der CAN ID 700 bzw. 780. Nach meinem ersten Eindruck stellen diese keine weiteren Informationen, über den Scan mit der CAN ID 680 heraus, bereit.

Soweit ich den Austausch hier im Thread und auch in anderen Foren verstanden habe, kann ComfortSoft mit WPM3 und neuer nicht umgehen.

Dein Vorschlag
{"INFO_TYP", 0x019c, 0}
zu nutzen, scheint vielversprechend zu sein. Im Moment resultiert das bei mir in 0x81 und könnte dazu passen, dass sowohl die HK1- und Zirkulationspumpe bei Abfrage eingeschaltet waren.

Allerdings um die Zirkulationspumpe damit an- oder auszuschalten, ist das vermutlich nicht der richtige Weg. "INFO TYP" lässt eher darauf schließen, dass man hier abfragen und nicht setzen/schreiben kann. Würde auch wenig Sinn machen, da man sonst unbeabsichtigt beim Schalten der Zirkulationspumpe die anderen Pumpenzustände überschreibt. Hier muss ich noch auf die Suche gehen, welcher Index der Richtige sein könnte. Das muss ich vermutlich mitsniffen, wenn ich am WPM die Pumpe schalte.

Ich bin weiterhin offen für weitere Vorschläge.

Gruß

Araktos

Hallo N(Zgazucs,

was mir gerade noch durch den Kopf ging:

Du hast schon recht der Index "INFO..." deutet auch eine Information hin :)
Andersrum, der Ausgang für die Zirkulationspumpe ist auf dem WPM. Würde ich das WPM Designen, würde ich den direkten Ausgang nicht über CAN schalten lassen...
Der Ausgang wird durch das Programm im WPM geschaltet. Die Uhrzeiten sollten aber über CAN gesetzt werden können.

Was ist wen du die Zeiten setzt und der Rest macht der WPM3?

Gruß Niko.

N(Zgazucs

#143
Exakt Niko,

das ist auch das was mir vorschwebt, nur ein bisschen angepasst. Ich programmiere die Zeiten der Zirkulationspumpe durchgängig 24 Stunden am Tag und schalte dann entsprechend der WPM Einstellungen

Zirkulationspumpe Aus
bzw.
Zirkulationspumpe Programm

Ich werde weiter berichten, sobald ich mal Zeit habe die Befehle am Raspy mitzuschneiden, während ich die Befehle am WPM auslöse.

Ein weiteres Problem ist bei mir auch noch das Auslesen der relativen Luftfeuchte und Raumtemperatur meiner Fernbedienung FET. Da weiß ich noch nicht, wie ich am Besten vorgehe :-(

Gruß

N(Zgazucs

So langsam laufe ich mich warm.

Wem es hilft, die relative Luftfeuchte und die Raumtemperatur des FEKs bekommt man über

  { "RAUMTEMPERATUR_FEK"                               , 0x4ec7, et_dec_val},
  { "LUFTFEUCHTE_FEK"                                  , 0x4ec8, et_dec_val},


Das FEK hat bei mir die CAN ID 401.

./can_scan can0 680 401.4ec7
elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

value: 00d2  (RAUMTEMPERATUR_FEK  21.0)


./can_scan can0 680 401.4ec8
elster-kromschroeder can-bus address scanner and test utility
copyright (c) 2014 Jürg Müller, CH-5524

value: 021e  (LUFTFEUCHTE_FEK  54.2)

momad

Hallo zusammen,

auch bei mir klappt alles wunderbar , siehe unten  :)
Schreiben (SET) klappt auch bisher getestet nur RAUMSOLL.
Lässt sich eigentlich den SG Ready Modus (PV Anlage Überschuss nutzen) hier auch via CAN-BUS ansteuern?
Falls ja hat es jemanden bereits probiert und welches Wert sollte hierfür aktiviert werden?

robob

#146
Hallo zusammen.
Ich bin neu hier im Forum und hab mir ein Projekt vorgenommen, meine Stiebel Eltron WPF 07 in die Haussteuerung zu integrieren.
Dazu bin ich sehr schnell auf die Seite juerg5524.ch gestoßen und letztendlich in diesem Forum gelandet.

Mein Vorhaben ist, einen ESP32 Microcontroller mit einem MCP2515 auszustatten.
Dieser wird vom fertigen ESP-Home Projekt (https://esphome.io/components/canbus.html) supportet.
Und das ESP-Home Projekt ist wiederum ausgezeichnet im Home-Assistant (https://www.home-assistant.io/) integriert.
Mein Home-Assistant erlaubt mir, meine KNX-Haussteuerung zu regeln und z.B. Heizungsstellwerte zu kontrollieren oder Temperatur-Regler zu steuern.
Über ESP-Home habe ich auch Bodentemperaturfühler eingebunden und die Daten werden via Home Assistant an den KNX Heizungsregler gesendet.

Die wesentliche Arbeit für mich ist also zunächst mich gründlich Einzulesen, den ESP32 an den CAN-Bus der Heizung zu hängen und hoffentlich Daten über ESP-Home zu scannen und an den HomeAssistant zu übermitteln. Vorteil an der ganzen Sache: Die Anzeige der Daten, die ich von der Heizung erhalte übernimmt der Home Assistant in der fertigen Webanwendung.
Außerdem ist der ESP32 preislich unschlagbar günstig.
Auf der Seite von Jürg habe ich ein Paket mit dem Beinamen ESP32 gefunden aber leider noch keine näheren Infos dazu entdeckt.
Wie weit ist denn das Projekt schon fortgeschritten? Wo gibt es nähere Infos dazu? Oder hat schon jemand etwas ähnliches umgesetzt?

Vincent82

#147
Hallo robob,

ich nutze ESPHOME mit einem ESP8266 und lese damit seit einigen Tagen die Daten aus meiner Stiebel Eltron Wärmepumpensteuerung aus und visualisiere sie in Home Assistant.
Das funktioniert mittlerweile gut.

Wir scheinen uns sehr gut zu ergänzen, denn als nächsten Schritt möchte ich gerne einen KNX Fussbodenheizungsregler einsetzen und habe auch schon so wie Du überlegt, einen ESPHome Temperatursensor zu verwenden, denn der ist ja deutlich günstiger als die KNX Lösungen.

Ich poste hier einfach mal meine Esphome Configuration, welche noch recht chaotisch ist, denn als Python Programmierer kenne ich eigentlich keinen Switch Case  ;):

globals:
  - id: el_aufnahmeleistung_ww_tag_wh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_tag_wh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_ww_tag_kwh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_tag_kwh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_wh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_wh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_kwh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_kwh_flag
    type: bool
    restore_value: yes 
  - id: el_aufnahmeleistung_ww_total_kWh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_total_kWh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_ww_total_mWh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_total_mWh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_kWh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_kWh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_mWh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_mWh_flag
    type: bool
    restore_value: yes

sensor:
  - platform: template
    name: "Außentemperatur"
    id: temperature_kitchen
    unit_of_measurement: "°C"
    icon: "mdi:water-percent"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
  - platform: template
    name: "Stromverbrauch Warmwasser heute"
    id: daily_electric_energy_water
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "measurement"
    accuracy_decimals: 3
  - platform: template
    name: "Stromverbrauch Heizung heute"
    id: daily_electric_energy_heating
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "measurement"
    accuracy_decimals: 3   
  - platform: template
    name: "Stromverbrauch Warmwasser total"
    id: total_electric_energy_water
    unit_of_measurement: "mWh"
    device_class: "energy"
    state_class: "measurement"
    accuracy_decimals: 3
  - platform: template
    name: "Stromverbrauch Heizung total"
    id: total_electric_energy_heating
    unit_of_measurement: "mWh"
    device_class: "energy"
    state_class: "measurement"
    accuracy_decimals: 3
   
binary_sensor:
  - platform: template
    name: "EVU Sperre"
    id: "evu_lock"
 
time:
  - platform: homeassistant
    id: homeassistant_time
    on_time:
     
      - seconds: 50
        then:
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x1c,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x1d,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x20,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x21,0x00,0x00 ]
              can_id: 0x680
          - delay: 10s
          - lambda: |-
              if (id(el_aufnahmeleistung_ww_total_mWh_flag) and id(el_aufnahmeleistung_ww_total_kWh_flag)){
              id(el_aufnahmeleistung_ww_total_mWh) += id(el_aufnahmeleistung_ww_total_kWh_float);
              id(total_electric_energy_water).publish_state(id(el_aufnahmeleistung_ww_total_mWh));
              };
              id(el_aufnahmeleistung_ww_total_mWh_flag)=false;
              id(el_aufnahmeleistung_ww_total_kWh_flag)=false;
          - lambda: |-
              if (id(el_aufnahmeleistung_heiz_total_mWh_flag) and id(el_aufnahmeleistung_heiz_total_kWh_flag)){
              id(el_aufnahmeleistung_heiz_total_mWh) += id(el_aufnahmeleistung_heiz_total_kWh_float);
              id(total_electric_energy_heating).publish_state(id(el_aufnahmeleistung_heiz_total_mWh));
              };
              id(el_aufnahmeleistung_heiz_total_mWh_flag)=false;
              id(el_aufnahmeleistung_heiz_total_mWh_flag)=false;       

          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x1b,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x1a,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x1e,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x09,0x1f,0x00,0x00 ]
              can_id: 0x680
          - delay: 10s
          - lambda: |-
              if (id(el_aufnahmeleistung_ww_tag_kwh_flag) and id(el_aufnahmeleistung_ww_tag_wh_flag)){
              id(el_aufnahmeleistung_ww_tag_kwh) += id(el_aufnahmeleistung_ww_tag_wh_float);
              id(daily_electric_energy_water).publish_state(id(el_aufnahmeleistung_ww_tag_kwh));
              };
              id(el_aufnahmeleistung_ww_tag_kwh_flag)=false;
              id(el_aufnahmeleistung_ww_tag_wh_flag)=false;
          - lambda: |-
              if (id(el_aufnahmeleistung_heiz_tag_kwh_flag) and id(el_aufnahmeleistung_heiz_tag_wh_flag)){
              id(el_aufnahmeleistung_heiz_tag_kwh) += id(el_aufnahmeleistung_heiz_tag_wh_float);
              id(daily_electric_energy_heating).publish_state(id(el_aufnahmeleistung_heiz_tag_kwh));
              };
              id(el_aufnahmeleistung_heiz_tag_kwh_flag)=false;
              id(el_aufnahmeleistung_heiz_tag_wh_flag)=false;
          - canbus.send:
              data: [ 0xa1, 0x14, 0xfa,0x00,0x74,0x00,0x00 ]
              can_id: 0x680
          - lambda: |-
              ESP_LOGD("main", "EVU Sperre requested");
       
spi:
  id: McpSpi
  clk_pin: GPIO16
  mosi_pin: GPIO5
  miso_pin: GPIO4

canbus:
  - platform: mcp2515
    id: my_mcp2515
    spi_id: McpSpi
    cs_pin: GPIO14
    can_id: 4
    bit_rate: 20kbps
    on_frame:
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xA0 and x[1]==0x79 and x[2]==0x0C) {
              float temperature =float(float((int((x[4])+( (x[3])<<8))))/10);
              id(temperature_kitchen).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }
    - can_id: 0x514
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x09) {
              if(x[4]==0x1b){
              id(el_aufnahmeleistung_ww_tag_kwh) =float(int((x[6])+( (x[5])<<8)));
              id(el_aufnahmeleistung_ww_tag_kwh_flag)=true;
              ESP_LOGD("main", "el_aufnahmeleistung_ww_tag_kwh received over can is %f", id(el_aufnahmeleistung_ww_tag_kwh));}
              else if(x[4]==0x1f){
                id(el_aufnahmeleistung_heiz_tag_kwh) =float(int((x[6])+( (x[5])<<8)));
                id(el_aufnahmeleistung_heiz_tag_kwh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_tag_kwh received over can is %f", id(el_aufnahmeleistung_heiz_tag_kwh));}
              else if(x[4]==0x1d){
              id(el_aufnahmeleistung_ww_total_mWh) =float(int((x[6])+( (x[5])<<8)));
              id(el_aufnahmeleistung_ww_total_mWh_flag)=true;
              ESP_LOGD("main", "el_aufnahmeleistung_ww_total_mWh received over can is %f", id(el_aufnahmeleistung_ww_total_mWh));}
              else if(x[4]==0x21){
                id(el_aufnahmeleistung_heiz_total_mWh) =float(int((x[6])+( (x[5])<<8)));
                id(el_aufnahmeleistung_heiz_total_mWh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_total_mWh received over can is %f", id(el_aufnahmeleistung_heiz_total_mWh));}
            }

    - can_id: 0x514
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x09) {
              if (x[4]==0x1a){
                id(el_aufnahmeleistung_ww_tag_wh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_ww_tag_wh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_ww_tag_kwh received over can is %f", id(el_aufnahmeleistung_ww_tag_wh_float));}
              else if (x[4]==0x1e){
                id(el_aufnahmeleistung_heiz_tag_wh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_heiz_tag_wh_flag) = true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_tag_wh received over can is %f", id(el_aufnahmeleistung_heiz_tag_wh_float));}
              else if (x[4]==0x1c){
                id(el_aufnahmeleistung_ww_total_kWh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_ww_total_kWh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_ww_total_kkWh received over can is %f", id(el_aufnahmeleistung_ww_total_kWh_float));}
              else if (x[4]==0x20){
                id(el_aufnahmeleistung_heiz_total_kWh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_heiz_total_kWh_flag) = true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_total_kWh received over can is %f", id(el_aufnahmeleistung_heiz_total_kWh_float));}
              }
              if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x00 and x[4]==0x74){
              if(x[5]==0x80 and x[6]==0x00){
                id(evu_lock).publish_state(false);
                }
              else{
                id(evu_lock).publish_state(true);
              };
            };

Vincent82

Zitat von: momad am 12 Mai 2021, 13:21:33
Hallo zusammen,

auch bei mir klappt alles wunderbar , siehe unten  :)
Schreiben (SET) klappt auch bisher getestet nur RAUMSOLL.

Hallo author=momad, Dein Screenshot sieht so aus als wäre er von Home Assistant. Wenn dem so ist, könntest Du einmal beschreiben, wie Du das technisch gelöst hast?


robob

#149
Hallo Vincent,

klar, gerne gebe ich unten Hinweise zu den Temperaturfühlern.
Woher weiß ich, welche Adresse mein FEK bzw. meine Heizung hat?
Nutzt du auch einen Pegelwandler wie bei ESPHome (https://esphome.io/components/canbus.html?highlight=can#mcp2515-component) empfohlen, oder betreibst du deinen Aufbau ohne Pegelwandler?
Könntest du evtl. Fotos von deinem Aufbau schicken?
Ich möchte bei der Heizung nichts kaputt machen.
Danke für die Config. Langsam komme ich dahinter, mit dem File "Telegramm-Aufbau.txt" von Jürg.




Ich nutze als Temperatursensoren die DS18B20 (1-wire).
Die gibt es z.B. bei Amazon oder dem Onlinehändler der Wahl Edelstahlummantelt mit entsprechendem Kabel.
Die Sensoren habe ich im Estrich verlegt, indem ich an ein Ende eines Kabelschlauches eine passende Kupferhülse verlegt hab. Damit der Fühler auch tatsächlich die Estrichtemperatur misst, hab ich etwas Graphitpaste als Wärmeleitpaste in die Endhülsen gegeben.
Hier ein Link zu den Kupferhülsen: https://www.etherma.com/de/produkte/26881

Die DS18B20 lassen sich über 1-wire parasitär betreiben und haben eine eigene Adresse für den seriellen Bus. Man kommt also mit 2 Adern aus.
Die Fühler werden auf der ESP-Home Seite ganz gut beschrieben inklusive Beispielcode: https://esphome.io/components/sensor/dallas.html

Wichtig ist folgender Eintrag, der den jeweiligen verwendeten Pin beschreibt:

dallas:
  - pin: GPIO4


Und dann noch die Beschreibung der Sensoren mit der jeweiligen Adresse.
Die Adresse bekommt man raus, indem man die Fühler zunächst ohne Adressangabe betreibt und sich das Logfile ansieht.
Diese ist v.a. wichtig, wenn mehrere Fühler am gleichen Gerät hängen.

sensor:
  - platform: dallas
    address: 0x11012032E38A2028
    name: "T.HzgVorlaufDG"
  - platform: dallas
    address: 0x17012032C8D95828
    name: "T.HzgRücklaufDG"


Einmal konfiguriert erscheinen die Fühler normalerweise direkt im Home-Assistant.
Vom Home-Assistant übertrage ich die Fühlertemperaturen dann an den KNX-Bus, indem ich in der config.yaml den Abschnitt "expose" wie folgt editiere

    expose:

      - type: 'temperature'
        entity_id: 'sensor.t_hzgvorlaufdg'
        address: '3/0/5'

      - type: 'temperature'
        entity_id: 'sensor.t_hzgrucklaufdg'
        address: '3/0/6'