Buderus KM200 Kommunikationsmodul

Begonnen von Sailor, 21 Juli 2014, 12:39:47

Vorheriges Thema - Nächstes Thema

Sailor

Hallo Arno

Zitat von: arnoaugustin am 25 Januar 2016, 10:54:18
Ich hab das gerade mal ausprobiert. Blank ohne das Modul ausprobiert. Crypt::Rijndael::decrypt macht wirklich ein exit, wenn die Datenlänge%16 != 0 ist!
$cipher->decrypt("0123456789ABCDEFXXX");
führt zum exit.
Der hier geht glatt durch:
$cipher->decrypt("0123456789ABCDEF");

In Zeile 935 sollte also sowas hier rein um zu testen ob Länge vielfaches von 16er Blocks ist.
Dann bliebe FHEM am laufen......
    $decryptData = decode_base64($decryptData);
    length($decryptData) & 0xF and return "";

Vielen Dank für Deine Nachforschungen!

Ich habe deinen Befehl nicht ganz verstanden und das daher wie folgt gelöst:


    # Remove additional encoding with base64
    $decryptData = decode_base64($decryptData);

# Check whether the length of the decryptData is NOT multiplies of 16
if (length($decryptData)%16 != 0)
{
# Return nothing which will end this subroutine
return "";
}


Ich hoffe das funtioniert, da ich den Fehler nicht nachstellen kann.

Gruss
    Sailor
******************************
Man wird immer besser...

arnoaugustin

Hallo Sailor,

das was du geschrieben hast macht natürlich das gleiche nur ohne Modulo, was normalerweise einfach langsamer ist, in dem Fall natürlich völlig egal ist.....
(Wenn Länge nicht nicht ganzzahlig durch 16 teilbar ist, dann muss eins der unteren 4 bits gesetzt sein. Also Länge&0xF ungleich null. Und genau dann wird durch and return "" zurückgekehrt. Liest sich halt schneller und spart "Tinte"  ;)

Besten Dank,

Arno


Sailor

Hallo Arno

Zitat von: arnoaugustin am 25 Januar 2016, 13:09:54
das was du geschrieben hast macht natürlich das gleiche nur ohne Modulo, was normalerweise einfach langsamer ist, in dem Fall natürlich völlig egal ist.....
(Wenn Länge nicht nicht ganzzahlig durch 16 teilbar ist, dann muss eins der unteren 4 bits gesetzt sein. Also Länge&0xF ungleich null. Und genau dann wird durch and return "" zurückgekehrt. Liest sich halt schneller und spart "Tinte"  ;)

OK, das Argument "Geschwindigkeit" überzeugt.

Geändert in


    # Remove additional encoding with base64
    $decryptData = decode_base64($decryptData);

# Check whether the length of the decryptData is NOT multiplies of 16
if (length($decryptData)&0xF != 0)
{
# Return nothing which will end this subroutine
return "";
}


Gruss
   Sailor
******************************
Man wird immer besser...

RaspII

Hi,
super, dass ihr euch dem Problem angenommen habt.
Eine Frage habe ich noch:
Kommt die Fehlermeldung weil meinen km200 Konfiguration falsch ist oder liegt das an einer falschen / unvollständigen km200-Antwort?
(Ich vermute letzteres, da die Abstürze sehr selten sind)
Gruß
RaspII


Gesendet von meinem SM-G900F mit Tapatalk

RaspII

Sailor

Hallo RasPII

Zitat von: RaspII am 25 Januar 2016, 16:50:26
Kommt die Fehlermeldung weil meinen km200 Konfiguration falsch ist oder liegt das an einer falschen / unvollständigen km200-Antwort?
(Ich vermute letzteres, da die Abstürze sehr selten sind)

Ja wenn ich das mal wüsste...

Ich vermute ebenfalls eine falsche Rückmeldung seitens der km200-Kiste.

Gruß
    Sailor
******************************
Man wird immer besser...

arnoaugustin

Zitat von: Sailor am 25 Januar 2016, 13:23:02
Hallo Arno

OK, das Argument "Geschwindigkeit" überzeugt.

Geändert in


    # Remove additional encoding with base64
    $decryptData = decode_base64($decryptData);

# Check whether the length of the decryptData is NOT multiplies of 16
if (length($decryptData)&0xF != 0)
{
# Return nothing which will end this subroutine
return "";
}


Gruss
   Sailor

Wenn du es so schreibst, dann musst Du aber entweder den &-Ausdruck klammern oder das !=0 weg lassen (wegen Operatoren Rangfolge. Binäres "&" bindet schwächer als "!=")

arnoaugustin

Hallo zusammen,

so....ich hab den KM200 jetzt auch am laufen. Die Android App ist ja wohl der absolute Witz! Damit lässt sich nicht mal auf Urlaubsmodus etc. umstellen. Abgesehen davon läuft die nur, wenn das Gateway Internetzugang hat (Auch wenn in der Doku was anderes steht). Die App kann man sich getrost sparen. Ist schon frech, wie das Gateway beworben wird, wenn man denkt, dass der Normalanwender nur die App zur Verfügung stehen hat.....
Aber wer braucht die schon die App - es gibt ja FHEM  ;D

Probleme gibts bisher keine - läuft alles wie geschmiert - auch ohne, dass das Gateway Internetzugang hat!

Das FHEM-Modul ist echt super! Großen Dank an Sailor und alle, die da Arbeit rein gesteckt haben!

Noch ne Anmerkung, da der Daten-Update immer einige Zeit dauert und man für die Plots oder Logfiles nur wenige Werte wie Vorlauf, Boilertemperatur etc. wirklich in kurzen Intervallen benötigt. Wäre es mit wenig Aufwand möglich z.B. noch ein Kurzintervall ein zu bauen zu dem spezielle Werte geholt werden?
Also etwa sowas hier:
attr myKM200 IntervalSpecialVal 60
attr myKM200 SpecialVals /heatSources/actualPower /system/sensors/temperatures/supply_t1 /system/sensors/temperatures/return /system/sensors/temperatures/hotWater_t2

Man holt also alles unwichtige z.B. nur 1x die Stunde und alles was für SVGs wichtig ist alle 60-120 Sekunden. Statische Werte kann man ja jetzt schon getrennt holen lassen. 
Vorteil wäre dass die Logfiles deutlich kleiner werden würden, und außerdem weniger Netz- bzw. Systemlast anfallen würde.

Is nur mal so ein Gedanke.

Viele Grüße
Arno

Jorge3711

#1117
Zitat von: arnoaugustin am 27 Januar 2016, 17:39:26
so....ich hab den KM200 jetzt auch am laufen. Die Android App ist ja wohl der absolute Witz! Damit lässt sich nicht mal auf Urlaubsmodus etc. umstellen. Abgesehen davon läuft die nur, wenn das Gateway Internetzugang hat (Auch wenn in der Doku was anderes steht). Die App kann man sich getrost sparen. Ist schon frech, wie das Gateway beworben wird, wenn man denkt, dass der Normalanwender nur die App zur Verfügung stehen hat.....

Buderus geht wohl eher einen anderen Weg: https://www.buderus-connect.de

Funktioniert mit meiner GB172 problemlos.

arnoaugustin

Zitat von: Jorge3711 am 28 Januar 2016, 11:15:09
Zitat von: arnoaugustin am 27 Januar 2016, 17:39:26
so....ich hab den KM200 jetzt auch am laufen. Die Android App ist ja wohl der absolute Witz! Damit lässt sich nicht mal auf Urlaubsmodus etc. umstellen. Abgesehen davon läuft die nur, wenn das Gateway Internetzugang hat (Auch wenn in der Doku was anderes steht). Die App kann man sich getrost sparen. Ist schon frech, wie das Gateway beworben wird, wenn man denkt, dass der Normalanwender nur die App zur Verfügung stehen hat.....
[/qoute]

Buderus geht wohl eher einen anderen Weg: https://www.buderus-connect.de

Funktioniert mit meiner GB172 problemlos.

Besten Dank,
das kannte ich noch gar nicht.
Finde ich aber trotzdem unmöglich, dass Buderus dann theoretisch auch immer wissen kann wann ich im Urlaub bin, wann ich schlafen gehe usw.....
Wieso bauen die den Webserver nicht einfach ins Gateway, so wie man das z.B. bei jedem HP-Drucker findet.
Egal wie Embedded das Gerät auch sein mag - ohne Scripte in reinem HTML brauchts für die Nachbildung der Bedieneinheit nicht viel......

arnoaugustin

#1119
Hallo Sailor,

ich hab hier noch Probleme damit, dass alle Werte teilweise viermal geholt werden. Da dauert das Auslesen für meine paar Werte über 20 Sekunden statt 5 Sekunden die es bei mir mit dem Patch braucht. Außerdem wurden Logs und Notifies mehrfach getriggert (Daran habe ich das auch erst gemerkt).

die Config sieht so aus:

attr   myKM200 DoNotPoll /dhwCircuits/dhw1/operationMode /dhwCircuits/dhw1/status /dhwCircuits/dhw1/switchPrograms /dhwCircuits/dhw1/temperatureLevels /dhwCircuits/dhw1/workingTime /gateway /heatingCircuits/hc1/activeSwitchProgram /heatingCircuits/hc1/actualSupplyTemperature /heatingCircuits/hc1/fastHeatupFactor /heatingCircuits/hc1/operationMode /heatingCircuits/hc1/roomtemperature /heatingCircuits/hc1/status /heatingCircuits/hc1/switchPrograms /heatingCircuits/hc1/temperatureRoomSetpoint /heatSources/supplyTemperatureSetpoint /heatSources/actualCHPower /heatSources/actualDHWPower /heatSources/actualModulation /heatSources/actualPower /heatSources/actualSupplyTemperature /heatSources/applianceSupplyTemperature /heatSources/burnerModulationSetpoint /heatSources/burnerPowerSetpoint /heatSources/ChimneySweeper /heatSources/CHpumpModulation /heatSources/flameCurrent /heatSources/flameStatus /heatSources/gasAirPressure /heatSources/hs1 /heatSources/nominalCHPower /heatSources/nominalDHWPower /heatSources/numberOfStarts /heatSources/powerSetpoint /heatSources/returnTemperature /heatSources/workingTime/centralHeating /heatSources/workingTime/secondBurner /heatSources/workingTime/totalSystem /notifications /recordings /solarCircuits /system/appliance /system/brand /system/bus /system/heatSources/hs1/energyReservoir /system/heatSources/hs1/reservoirAlert /system/holidayModes /system/sensors/temperatures/chimney /system/sensors/temperatures/hotWater_t2 /system/sensors/temperatures/switch /system/systemType /system/heatSources/hs1/fuel/density /system/heatSources/hs1/fuelConsmptCorrFactor /system/heatSources/hs1/nominalFuelConsumption
attr   myKM200 IntervalDynVal 180
attr   myKM200 PollingTimeout 200
attr   myKM200 ReadBackDelay 500
attr   myKM200 verbose 4
attr   myKM200 ConsoleMessage 0


Im Log sieht man dann schon, dass etliche Services mehrfach hintereinander geholt werden und wenn ich das Device mit "list myKM200" angucke, dann werden die Services unten in den Listen mehrfach angezeigt.
list myKM200

Ich hab hier einen Patch auf Basis der neusten Version aus dem Repo, der das Problem behebt. (Frage bleibt allerdings, warum die ganzen Duplikate überhaupt entstehen - Dazu müsste ich mir das ganze aber mal wenn ich mehr Zeit genauer angucken).
Im Patch sind drei Fehlerbehebungen drin:
1) Entfernen aller Duplikate aus den Arrays über neue Modulsubroutine km200_filter_duplicates
2) Bei DoNotPoll mehrfache Leerzeichen zulassen (@KM200_DONOTPOLL) enthält sonst Leerelement wenn zwischen den Services im Attribut mehrere Leerzeichen stehen. Im Code sind noch ein paar Stellen an denen statt / / besser /\s+/ stehen sollte - nicht dass es Böse Überraschungen gibt, wenn jemand TABs oder mehrere Spaces verwendet.
3) "length($decryptData)&0xF != 0" war hie nicht korrekt, da dies auswertet wie: "length($decryptData) & (0xF != 0)" !!!!

Datei zum Patchen habe ich angehängt (Falls benötigt). Diff zum händisch patchen hier:

266,267c266,267
<       @{$hash->{Secret}{KM200ALLSERVICES}}        = sort @KM200_AllServices;
<       @{$hash->{Secret}{KM200ALLSERVICESBACKUP}}  = sort @KM200_AllServices;
---
>       @{$hash->{Secret}{KM200ALLSERVICES}}        = km200_filter_duplicates(sort @KM200_AllServices);
>       @{$hash->{Secret}{KM200ALLSERVICESBACKUP}}  = km200_filter_duplicates(sort @KM200_AllServices);
481c481
<               @KM200_DONOTPOLL = split(/ /, $temp[0]);
---
>               @KM200_DONOTPOLL = split(/\s+/, $temp[0]);
752c752
<       if (length($decryptData)&0xF != 0)
---
>       if (length($decryptData)&0xF)
2344c2344
<                       @{$hash ->{Secret}{KM200ALLSERVICES}} = sort @{$hash ->{Secret}{KM200ALLSERVICES}};
---
>                       @{$hash ->{Secret}{KM200ALLSERVICES}} = km200_filter_duplicates(sort @{$hash ->{Secret}{KM200ALLSERVICES}});
2388,2390c2388,2390
<               @{$hash->{Secret}{KM200RESPONDINGSERVICES}} = @KM200_RespondingServices;
<               @{$hash->{Secret}{KM200WRITEABLESERVICES}}  = @KM200_WriteableServices;
<               @{$hash->{Secret}{KM200DYNSERVICES}}        = @KM200_DynServices;
---
>               @{$hash->{Secret}{KM200RESPONDINGSERVICES}} = km200_filter_duplicates(@KM200_RespondingServices);
>               @{$hash->{Secret}{KM200WRITEABLESERVICES}}  = km200_filter_duplicates(@KM200_WriteableServices);
>               @{$hash->{Secret}{KM200DYNSERVICES}}        = km200_filter_duplicates(@KM200_DynServices);
2803a2804,2808
>
> sub km200_filter_duplicates {
>     my %t;
>     grep(!$t{$_}++, @_);
> }
3185c3190
< =end html_DE
\ Kein Zeilenumbruch am Dateiende.
---
> =end html_DE


Viele Grüße,

Arno


arnoaugustin

Zitat von: RaspII am 25 Januar 2016, 16:50:26
Hi,
super, dass ihr euch dem Problem angenommen habt.
Eine Frage habe ich noch:
Kommt die Fehlermeldung weil meinen km200 Konfiguration falsch ist oder liegt das an einer falschen / unvollständigen km200-Antwort?
(Ich vermute letzteres, da die Abstürze sehr selten sind)
Gruß
RaspII


Gesendet von meinem SM-G900F mit Tapatalk
Denke mal, dass das Gateway gar nicht oder Falsch. Wenn man die IP von einem anderen Webserver/Host angibt (Fritzbox, Drucker, etc.), dann geht da auch auf die Bretter. Bzw. ging bevor das abgefangen worden ist.  Eigentlich sollte man den Fehler mal ans Crypt-Modul melden.
Wenn jede Funktion der was nicht passt ein exit() machen würde.....

VG
  Arno

arnoaugustin

Hallo Sailor,

es ist noch ein Fehler drin, der dazu führt dass auch ohne Duplikate alles doppelt ausgelesen wird wenn das "DoNotPoll" Attribut gesetzt wird.
Beim define eines KM200 und bei dem DoNotPoll wird ein Timer auf "km200_GetInitService" aufgezogen. Beide sind aktiv.
Nach dem Init wird dann "km200_GetInitService" nochmal aufgerufen und dort wird dann der PollTimer nocheinmal gesetzt. Es sind dann beide Timer gleichzeitig aktiv und es wird doppelt gepollt.

Ich hab den Patch nochmal überarbeitet und angehängt. Das verdoppeln der Services in den Arrays dürfte dann auch vom "DoNotPoll" kommen.
Ich hab die geänderte Datei angehängt. Der der Patch im Detail:
*** fhem_svn/FHEM/73_km200.pm   2016-01-26 23:21:29.649994065 +0100
--- FHEM/73_km200.pm    2016-01-28 15:28:56.899289553 +0100
***************
*** 478,484 ****
                push @temp, "";

                ### Transform string entries seperated by blank into array
!               @KM200_DONOTPOLL = split(/ /, $temp[0]);

                ### Remove trailing slash of each item if available

--- 478,484 ----
                push @temp, "";

                ### Transform string entries seperated by blank into array
!               @KM200_DONOTPOLL = split(/\s+/, $temp[0]);

                ### Remove trailing slash of each item if available

***************
*** 749,755 ****
      $decryptData = decode_base64($decryptData);

        # Check whether the length of the decryptData is NOT multiplies of 16
!       if (length($decryptData)&0xF != 0)
        {
                # Return nothing which will end this subroutine
                return "";
--- 749,755 ----
      $decryptData = decode_base64($decryptData);

        # Check whether the length of the decryptData is NOT multiplies of 16
!       if (length($decryptData)&0xF)
        {
                # Return nothing which will end this subroutine
                return "";
***************
*** 2341,2347 ****
                                }
                        }
                        ### Sort the list of all services alphabetically
!                       @{$hash ->{Secret}{KM200ALLSERVICES}} = sort @{$hash ->{Secret}{KM200ALLSERVICES}};
                }
                ### Check whether the type is unknown
                else
--- 2341,2347 ----
                                }
                        }
                        ### Sort the list of all services alphabetically
!                       @{$hash ->{Secret}{KM200ALLSERVICES}} = km200_filter_duplicates(sort @{$hash ->{Secret}{KM200ALLSERVICES}});
                }
                ### Check whether the type is unknown
                else
***************
*** 2369,2374 ****
--- 2369,2376 ----
        ### Get the size of the array
        @KM200_InitServices       = @{$hash ->{Secret}{KM200ALLSERVICES}};
        $NumberInitServices       = @KM200_InitServices;
+         @KM200_RespondingServices = km200_filter_duplicates(@KM200_RespondingServices);
+         @KM200_WriteableServices  = km200_filter_duplicates(@KM200_WriteableServices);

        ### If the list of KM200ALLSERVICES has not been finished yet
        if ($ServiceCounterInit < ($NumberInitServices-1))
***************
*** 2395,2400 ****
--- 2397,2403 ----


                ###START###### Initiate the timer for continuous polling of dynamical values from KM200 ###################START####
+                 RemoveInternalTimer($hash);
                InternalTimer(gettimeofday()+($hash->{INTERVALDYNVAL}), "km200_GetDynService", $hash, 0);
                Log3 $name, 4, $name. " : km200 - Define: InternalTimer for dynamic values started with interval of: ".($hash->{INTERVALDYNVAL});
                ####END####### Initiate the timer for continuous polling of dynamical values from KM200 ####################END#####
***************
*** 2801,2806 ****
--- 2804,2813 ----
        }
        return undef;
  }
+ sub km200_filter_duplicates {
+     my %t;
+     grep(!$t{$_}++, @_);
+ }
  ####END####### Subroutine to download complete dynamic data set from gateway ###################################END#####

  1;
***************
*** 3182,3185 ****
  </ul></ul>

  </ul>
! =end html_DE
\ Kein Zeilenumbruch am Dateiende.
--- 3189,3192 ----
  </ul></ul>

  </ul>
! =end html_DE





Zitat von: arnoaugustin am 28 Januar 2016, 11:53:26
Hallo Sailor,

ich hab hier noch Probleme damit, dass alle Werte teilweise viermal geholt werden. Da dauert das Auslesen für meine paar Werte über 20 Sekunden statt 5 Sekunden die es bei mir mit dem Patch braucht. Außerdem wurden Logs und Notifies mehrfach getriggert (Daran habe ich das auch erst gemerkt).

usw.....


furban

Hi,

ich versuche gerade mit set die Warmwassertemperatur zeitabhängig zu steuern scheitere aber daran das ich halt nicht genug Ahnung von FHEM habe
Ich dachte mir das das so ungefähr so aussehen müsste

define Wassertemperatur at *17:15 set "KM200","/dhwCircuits/dhw1/temperatureLevels/high","40"

Aber da sehe ich nur ein

2016.01.30 17:20:00 3: Wassertemperatur: Please define "KM200","/dhwCircuits/dhw1/temperatureLevels/high","40" first

im Logfile.
Hat einer einen Tipp wie da die richtige Syntax ist?

Danke

Frank




furban

Zitat von: furban am 30 Januar 2016, 17:28:41
Hi,

ich versuche gerade mit set die Warmwassertemperatur zeitabhängig zu steuern scheitere aber daran das ich halt nicht genug Ahnung von FHEM habe
Ich dachte mir das das so ungefähr so aussehen müsste

define Wassertemperatur at *17:15 set "KM200","/dhwCircuits/dhw1/temperatureLevels/high","40"

Aber da sehe ich nur ein

2016.01.30 17:20:00 3: Wassertemperatur: Please define "KM200","/dhwCircuits/dhw1/temperatureLevels/high","40" first

im Logfile.
Hat einer einen Tipp wie da die richtige Syntax ist?

Danke

Frank

OK. Kaum schreit man um hilfe hat man die richtige Syntax doch noch selbst gefunden. Es war wohl einfach

define Wassertemperatur at *17:37 set KM200 /dhwCircuits/dhw1/temperatureLevels/high 55

arnoaugustin

Hallo Sailor,

wennn ich das Attribut DoNotPoll verwende, dann kann ich keinen Werte mehr setzen/lesen der unter DoNotPoll stehen. Damit ist die gesammte Kommunikation praktisch auf die übrigen Werte beschränkt. Wenn man Beispielsweise die Firmwareversion lesen will, diese aber nicht immer abpollen lassen will, dann ist das derzeit nicht möglich.
Schön ist natürlich, dass man mit dem DoNotPoll die ganzen Werte raus werfen kann, die irgendwie in Verschiedenen URL-Pfaden mehrfach auftauchen, bzw. gleiche Bedeutung haben.
Ich hab daher mal etwas rumgespielt mit einem "PollOnly"-Attribut:

attr myKM200 PollOnly \
/system/sensors/temperatures/return \
/system/sensors/temperatures/supply_t1


Es soll hier z.B. nur Vor- und Rücklauftemeratur regelmäßig gepollt werden, trotzdem soll man man z.B. noch Zeitprogramme setzen können, oder per "get" andere Werte abfragen.
Das lässt sich recht einfach implementieren, wenn man überall wo  @{$hash->{Secret}{KM200DYNSERVICES}} zugewiesen wird einfach folgendes macht:


my @a=split(/\s+/,AttrVal($hash->{NAME},"PollOnly",""));
if(@a) {
    @{$hash->{Secret}{KM200DYNSERVICES}}=@a;
} else {
    @{$hash->{Secret}{KM200DYNSERVICES}}=@KM200_DynServices;
}


Kann man das evtl. noch einbauen?
Derzeit ist die Situation etwas ungünstig, da eben nur auf Werte zugegriffen werden kann die nicht im DoNotPoll stehen.
Hätte auch noch weiteren Vorschlag - sorry ;-) z.B. sowas hier:

attr myKM200 ReplaceReadings /system/sensors/temperatures/return:Ruecklauf /system/sensors/temperatures/supply_t1:Vorlauf

Also ersetzen von allen Readings gegen "Kurzreadings". Das macht Lesbarkeit, Scripten, Logfiles wesentlich handlicher. In den Logs hätte man dann auch schöne gut lesbare kurze Namen.
Das Attribut würde man beim Init in zwei Umsetzungs-Hashes parsen. Überall wo Readings generiert werden oder beim Set und Get wird aus dem Servicenamen der Kurzname gebildet, bzw. aus dem Kurznamen wieder der Servicename. Falls in den Hashes kein Übersetzungsname steht nimmt man einfach den langen Servicenamen.

VG
  Arno