(Neuer Versuch, jetzt mit nbsp im Code, in der Hoffnung, dass so die Einrückungen sichtbar sind:)
Zitat von
CB187 Kann ich dir benatworten weil ich es anders nicht gefunden habe und auch nicht umsetzen konnte. Und ich weiss gar nicht ob es anders in Esphome geht. Ich find mich da ziemlich zurecht und für mich ist alles schlüssig.Läuft Fehler frei. Aber wenn du ne einfachere Lösung hast ich bin für alles offen.Man lernt ja nie aus.
Aber natürlich nur als esp version.
Also, von ESPhome habe ich keine Ahnung, von daher kann ich nicht sagen, wie ich das auf der Basis konkret umsetzen würde. Aber wenn das da nicht einfacher geht, würde ich wohl einfach kein ESPhome dafür benutzen, weil es viel zu umständlich ist!?
Ich meine, dass es irgendwie ziemlich unübersichtlich und wartungsunfreundlich ist, dieselben Informationen zigfach hinzuschreiben, leuchtet doch ein, oder nicht?
Wenn ich den Code so angucke, scheint mir aber zum Beispiel schonmal unnötig, beim Parsen der empfangenen Nachrichten für jedes Register die gleichen Felder zu prüfen!?
Also z.B. statt:
#Erzeugte
Energie gesamt
- can_id: 0x180
then:
- lambda: |-
if(x[2]==0xFA and x[3]==0x09 and x[4] ==0x30) {
float temperature =float((float((int((x[6])+( (x[5])<<8))))));
id(Erzeugte_Energie_Gesamt).publish_state(temperature);
ESP_LOGD("main", "
Temperature received over can is %f", temperature);
}
#Umwälzpumpe
- can_id: 0x180
then:
- lambda: |-
if(x[2]==0xFA and x[3]==0xC0 and x[4] ==0xF7) {
float temperature =float((float((int((x[6])+( (x[5])))))));
id(Umwaelzpumpe).publish_state(temperature);
ESP_LOGD("main", "Temperature received over can is %f", temperature);
}
würde doch reichen:
- can_id: 0x180
then:
- lambda: |-
if(x[2]==0xFA){
if(x[3]==0x09 and x[4] ==0x30) { #Erzeugte Energie gesamt
float temperature =float((float((int((x[6])+( (x[5])<<8))))));
id(Erzeugte_Energie_Gesamt).publish_state(temperature);
ESP_LOGD("main", "Temperature received over can is %f", temperature);
}else if(x[3]==0xC0 and x[4] ==0xF7) { #Umwälzpumpe
float temperature =float((float((int((x[6])+( (x[5])))))));
id(Umwaelzpumpe).publish_state(temperature);
ESP_LOGD("main", "Temperature received over can is %f", temperature);
}
}
was man weiter vereinfachen könnte zu:
- can_id: 0x180
then:
- lambda: |-
if(x[2]==0xFA){
uint16_t id = (x[3] << 8) | x[4];
if(id==0x0930) { #Erzeugte Energie gesamt
float temperature =float((float((int((x[6])+( (x[5])<<8))))));
id(Erzeugte_Energie_Gesamt).publish_state(temperature);
ESP_LOGD("main", "Temperature received over can is %f", temperature);
}else if(id==0xC0F7) { #Umwälzpumpe
float temperature =float((float((int((x[6])+( (x[5])))))));
id(Umwaelzpumpe).publish_state(temperature);
ESP_LOGD("main", "Temperature received over can is %f", temperature);
}
}
Also, und das natürlich nicht nur für die zwei Felder, sondern für alle Felder, die unter Adresse 0x180 sind.
Außerdem vermute ich mal , dass die Konvertierung bei 0xc0f7 so falsch ist? Ich kenne das Feld bisher nicht, und bei meiner Heizung ist es im Moment 0. Das sieht aber auf den ersten Blick aus wie ein Fehler, der typischerweise leicht passiert, wenn man soviel Code dupliziert. Soweit die korrekte Konvertierung hier identisch sein sollte, könnte man die natürlich auch zusammenziehen. Und das .publish_state braucht man doch wahrscheinlich auch nur einmal?!
Also am Ende in Richtung sowas:
- can_id: 0x180
then:
- lambda: |-
if(x[2]==0xFA){
id_type_whatever field;
switch((x[3] << 8) | x[4]){
case 0x0930: #Erzeugte Energie gesamt
field = id(Erzeugte_Energie_Gesamt);
break;
case 0xC0F7: #Umwälzpumpe
field = id(Umwaelzpumpe);
break;
}
if(field){
float temperature =float((float((int((x[6])+( (x[5])<<8))))));
field.publish_state(temperature);
ESP_LOGD("main", "Temperature received over can is %f", temperature);
}
}
Also, keine Ahnung, was für einen Typ id(...) ergibt und ob der NULL sein kann und so (ich gehe davon aus, das ist C++?), aber die grundsätzliche Idee wäre halt, so viel wie möglich von dem Code zu vereinheitlichen. Noch einfacher geht das mglw., wenn Du dazu Hilfsfunktionen definieren kannst. IIRC hat modernes C++ auch Lambdas? Also, wenn Du keine globalen Hilfsfunktionen definieren kannst, wäre das vielleicht ein Weg.
Außerdem wäre es vielleicht sinnvoll, zu prüfen, ob die Nachricht überhaupt an einen selbst gerichtet ist? So, wie ich den Code verstehe, würdest Du ja auch die Nachricht akzeptieren, wenn sie an jemand anderes geht, was möglicherweise zu wirren Effekten führen könnte?! Zumal Du ja nichtmal zu prüfen scheinst, ob die Nachricht überhaupt eine Lese-Antwort ist, und im Zweifel auch z.B. einen Lese-Request akzeptieren würdest, solange er von der richtigen Adresse kommt? IIRC schreibt doch manchmal auch die
Regelung an die Bedieneinheit, das würde dann doch zu fehlerhaften Daten führen!?