Buderus KM200 Kommunikationsmodul

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

Vorheriges Thema - Nächstes Thema

nobody0472

#105
Hi nochmal,

also, entschlüsselt bekommen habe ich noch nichts, denn die Nachricht, dass mein Gateway die "Files" nicht hat, kommt unverschlüsselt.
Deshalb geht auch Deine Abfrage:
   if ($response->is_success)
nicht, denn HTML kommt in jedem Falle zurück, aber eben keine Fehlernachricht gemäß RFC (wie es in Perl durch HTTP:STATUS ausgewertet wird).
Hier müssten wir den Content wohl per Hand auf folgenden String parsen, bevor wir das zum entschlüsseln geben:

<HTML><HEAD><TITLE>Gateway webserver</TITLE></HEAD><DIV ALIGN=CENTER><FONT SIZE=+4><BR><BR><BR>Sorry, the requested file does not exist on this server.</FONT></DIV></HTML>

Ein Substring davon würde ja reichen.

Die Anfrage dazu, die unsere Software absetzt, mit REST-String, ist ja auch zunächst unverschlüsselt. Nur die Antwort, die vom Gateway kommt, ist entsprechend verschlüsselt, wenn es denn die Daten hat und bereitstellen will, womit dies also der 2. Schritt ist.

Aber zu Deiner ersten Frage:
Man kann dem HASH in Perl beliebige Elemente anhängen. Ein Beispiel aus dem CUL_IR-Modul, welches ich vor Jahren geschrieben habe:

$hash->{irLearn} = 1;

Du könntest also dem HASH die Elemente zuordnen:
$hash->{id} = ....

Allerdings sind diese Klassen (id, type, ...) ja je nach REST-String mit völlig anderen Werten belegt, daher macht es aus meiner Sicht keinen Sinn, diese Klassen selbst an den HASH zu hängen.

Und zu den Readings, dies steht auf der ersten Seite in unserem Thread, im simplen Modul 71_km200:

man nimmt:
   readingsBeginUpdate($hash);
   readingsBulkUpdate( $hash, @var[0], @var[1] );   
        ......
          readingsEndUpdate( $hash, 1 );
wobei die beiden Elemente jeweils: NAME, VALUE sind.

Damit erzeugst Du die gesamte Liste der Readings.

Aber meine Frage nach der Entschlüsselung bleibt, wie hast Du es ohne CBC gemacht? Habe auch irgendwo gelesen, dass EBC und nicht CBC genutzt wird.
Kannst Du Deinen Code dazu mal posten?

Danke,
Gruß,
Olaf


Sailor

Hallo Olaf,

anbei meine Subroutine:


###START###### Subroutine Decrypt Data ########################################################################START####
sub km200_Decrypt($$$)
{
    my $decryptData             = $_[0];
    my $km200_crypt_key_private = $_[1];
my $name                    = $_[2];
       
    # Remove additional encoding with base64
    $decryptData = decode_base64($decryptData);
       
    # Create Rijndael decryption object and do the decryption
    my $cipher = Crypt::Rijndael->new($km200_crypt_key_private, Crypt::Rijndael::MODE_ECB() );
    my $deciphertext = $cipher->decrypt( $decryptData );
       
    # Remove zero padding
    $deciphertext =~ s/\x00+$//;
       
    # Remove PKCS #7 padding   
    my $decipher_len = length($deciphertext);
        my $decipher_padchar = ord(substr($deciphertext,($decipher_len - 1),1));
   
    my $i = 0;
   
    for ( $i = 0; $i < $decipher_padchar ; $i++ )
    {
        if ( $decipher_padchar != ord( substr($deciphertext,($decipher_len - $i - 1),1)))
        {
            last;
        }
    }
   
    # Return decrypted text
    if ( $i != $decipher_padchar )
    {
### Log entries for debugging purposes
Log3 $name, 5, ": km200 - decryptData1 : decipher_padchar: " .$decipher_padchar;
Log3 $name, 5, ": km200 - decryptData1 : decipher_len    : " .$decipher_len;
Log3 $name, 5, ": km200 - decryptData1 : deciphertext    : " .$deciphertext;
### Log entries for debugging purposes
        return $deciphertext;
    }
   
else
    {
$deciphertext = substr($deciphertext,0,$decipher_len - $decipher_padchar);
### Log entries for debugging purposes
Log3 $name, 5, ": km200 - decryptData2 : decipher_padchar: " .$decipher_padchar;
Log3 $name, 5, ": km200 - decryptData2 : decipher_len    : " .$decipher_len;
Log3 $name, 5, ": km200 - decryptData2 : deciphertext    : " .$deciphertext;
### Log entries for debugging purposes
        return $deciphertext;
    }
}
####END####### Subroutine Decrypt Data #########################################################################END#####


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

Sailor

Mein letzter Stand: Siehe Anhang

Jetzt ist Feierabend... Fuer heute!  ;D

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

Ralli

Das sieht doch sehr vielversprechend aus  :)
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

Rockojfonzo

Sailor, kannst Du nochmal Deine letzte Version posten? Danke!
FHEM auf Shuttle XS 35V2 mit CUL und HM-LGW
9 x HM-CC-RT-DN; 2 x HM-LC-SW4-DR; 3 x HM-WDS30-OT2-SM; 3 x HM-SEC-SD; 1 x HM-LC-Bl1PBU-FM; 1 x HM-LC-SW1-PL2;1 x HM-LC-SW1-FM; 2 x HM-SEC-SC-2

nobody0472

HI all,

so, ein Update meiner Situation mit dem KM50:

Ich habe vorhin mal nen Sniffer in den Verkehr gehängt, und festgestellt, dass nicht das KM50 das Problem ist, sondern mein Perl.

Wir nutzen zur Zeit folgenden Code, um den HTTP-Request zu bauen:

   my $ua = LWP::UserAgent->new;
   my $options = HTTP::Headers->new(
     Accept => 'application/json'
   );
   $options->user_agent('TeleHeater/2.2.3');
   $ua->default_headers($options);

Da wir aber den LWP::UserAgent von Perl nutzen, erzeugt der HEADER über Options bei mir KEINEN korrekten User-Agent String.
Im Request steht sowas drin, wie "libwww-perl/5.08...".

Ich habe daraufhin den Code wie folgt geändert:
   my $ua = LWP::UserAgent->new;
   my $options = HTTP::Headers->new(
     Accept => 'application/json'
   );
   $ua->default_headers($options);
   $ua->agent('TeleHeater/2.2.3');

und siehe da ... mein KM50 redet nun auch mit mir.
Werde mich nun mit der Decrypt von SAILOR befassen, und die Readings passend aufbauen.
Gibt's dazu bereit Sample-Code aus deinem obigen Beispiel?

Ich plädiere dafür, dass ihr auch mal meinen obigen USER-AGENT Code versucht, um evtl. auf eine einheitliche Version zu kommen.

Danke,
Gruß,
Olaf

nobody0472

Und noch ein Update,

nach momentanem Stand stürzt FHEM beim Versuch des Entschlüsselns ab. Ich habe noch nicht genau gefunden wo, aber die Decrypt läuft bei mir so nicht.
Werde auch dies mal debuggen.

LG

nobody0472

Hi all,

so, ich habs nun noch nicht ganz soweit wie Sailor, und der Code ist extrem hässlich, aber ich kann was zum testen anbieten:

Was macht das Modul?
Es fragte EINIGE Werte bei der Definition ab, und schreibt die Antworten ins LOG.
Ich habe in den REST-Services die Sammel-Übersichten auskommentiert, da diese URIs zurück liefern, und keine Werte. Diese kann man aber mit abfragen, die Routine gibt die Daten korrekt aus.
Der EINZIGE Wert, bei dem mein System noch abstürzt ist: "/heatSources/flameCurrent"
Den habe ich auch auskommentiert. Wo das Problem liegt, weiss ich noch nicht.
SOLAR habe ich nicht, daher auskommentiert.

Was das Modul alles NICHT macht:
Es schreibt keine Readings, es macht kein Intervall, es unterstützt weder SET noch GET.

Momentan ging es mir darum, beim DEFINE, einmal alle Werte zu holen.
Das Dingen läuft für meine KM50 mit einem Heizkreis und Öl-Brenner.

Was solltet ihr testen:
a) läuft es bei euch überhaupt (define <name> km200 <ip-address> <interval> <Geräte-PW> <persönliches-PW>)
b) mit welchen REST-Services könnt ihr arbeiten
c) was gibt eure Anlage zurück
d) was hättet ihr gern noch

Soviel zum Stand. Ich weiss, dass es vom Code her übel ist. Ich räume auf, sobald ich mehr weiß, und ob es bei anderen geht. Dann kann ich System in den Code bringen. Ich plane einzelne RESTs per GET zu unterstützen, ähnlich auch für SETs, und ein "ALL" für alle Werte.
INTERVAL sollte für alle Werte gelten, allerdings kann man eigene ATs schreiben, der nur einzelne Werte dann holt.

Danke,
Gruß,
Olaf

Rockojfonzo

Super-Olaf! Danke!

Neu ist ja "Crypt::Rijndael", musste ich noch installieren.

Beim define keine Probleme, auf der Leitung ist dann erst mal gut Verkehr
(via tcpdump ganz viel/oft:
0x0020:  5010 3fce 1ab6 0000 4854 5450 2f31 2e30  P.?.....HTTP/1.0
0x0030:  2032 3030 2054 6865 2072 6571 7565 7374  .200.The.request
0x0040:  2068 6173 2073 7563 6365 6564 6564 0d0a  .has.succeeded..
0x0050:  436f 6e74 656e 742d 5479 7065 3a20 6170  Content-Type:.ap
0x0060:  706c 6963 6174 696f 6e2f 6a73 6f6e 0d0a  plication/json..
0x0070:  0d0a 0d0a 4d6d 394d 6f4c 6554 5a62 4c49  ....Mm9MoLeTZbLI
0x0080:  7051 6f4b 4c2b 2b43 7a43 4d6e 4d2b 3138  pQoKL++CzCMnM+18
usw. usw.

Leider weiß ich nicht, wie ich prüfen kann, ob die Entschlüsselung klappt. :-(

Im Log habe ich 21 mal
2014.10.25 22:24:24 1: PERL WARNING: Character in 'c' format wrapped in pack at ./FHEM/73_km200.pm line 307.
FHEM auf Shuttle XS 35V2 mit CUL und HM-LGW
9 x HM-CC-RT-DN; 2 x HM-LC-SW4-DR; 3 x HM-WDS30-OT2-SM; 3 x HM-SEC-SD; 1 x HM-LC-Bl1PBU-FM; 1 x HM-LC-SW1-PL2;1 x HM-LC-SW1-FM; 2 x HM-SEC-SC-2

nobody0472

Danke fürs Feedback,

das zeigt, dass die Request korrekt sind, und Dein Web-Modul passend antwortet. Aber leider Dein Perl den PACK Befehl (zusammenstellen des MD-Salts für die Entschlüsselung) so nicht durchführt.

Daher noch keine Entschlüsselung. Wie das kommt, muss ich erst recherchieren.

Danke trotzdem, ich bleibe dran.

Gruß,
Olaf

Sailor

#115
So,

jetzt aber mal meine Version.

Bitte den Kasten "List of open Problems" beachten:


########################################################################################################################
# List of open Problems
#
# *Reading KM200 service "/heatSources/flameCurrent" or "/system/appliance/flameCurrent" causes fhem to crash
# *Set function: missing and seems not to hand over values to central heating system
# *Get function: dropdown list does not show all services
# *Many values in readings make no sense at all
# *Cannot read or change attribute for example in order to change interval to other values than default value of 300s
#
########################################################################################################################


Es werden wegen der laufenden Entwicklungsphase noch jede Menge Logs auf Verbose Level 5 erzeugt.
Ausserdem auch auf der Konsole.

Ansonsten geht alles ausser die set-Funktion.

Da beiss ich mir zur Zeit die Zaehne aus...

Fuer heute ist schluss.

Gruss vom "hintern-Deich" mit viel Sturmflutwasser davor!
    Sailor

******************************
Man wird immer besser...

nobody0472

HI all,

danke an Sailor. Ein paar Unterschiede kann man schon sehen:

Bei Sailor wir PACK bereits mit C* verwendet (unsigned char), bei mir "nur" "c*". Mag ein Grund sein.
Darüber hinaus baut Sailor den HTTP-Header anders als ich. Das funzt bei meiner KM50 nicht, wohin gegen bei seiner KM200 das wohl geht (mag aber auch am Perl liegen).

Die Probleme mit Flame/current sind gleich.
Super, dass wir Versionen zum Vergleich haben. So können wir auf verschiedene Weisen testen, und schauen, was geht.

Bei Sailor fällt auf:
Wenn eine REST-Anfrage NICHTS zurück liefert (NO-Success), so schlägt die Abfrage nach JSON->{"value"} fehl.
Zumindest bei mir steigt FHEM dann aus. Hier brauchen wir ein robustes, universelles Vorgehen.

Freue mich auf weitere Debugs anderer User.

LG,
Olaf

nobody0472

#117
HI all,
habe auf Sailors Version weiter gearbeitet, da sie einfach viel weiter entwickelt ist.
Habe Fail-Safes eingebaut, den Header für KM50 integriert und INTERVAL im Define wieder aufgenommen.

Sollte jetzt auch korrekt aussteigen, wenn keine Kommunikation mit dem Gateway geht, oder wenn ein Dienst nicht verfügbar ist.

Siehe ChangeLog. Bitte um Tests allerseits.

Gruß,
Olaf

ergerd

Hallo an alle,

ich bin begeistert, auch bei mir funktioniert es jetzt!

Vielen Dank an die Entwickler!

Grüße
Rainer
FHEM auf RasPi 4, CUNO, ZigBee, 1Wire2WLAN, DS2423, C-Control II, Buderus KM200, LaCrosseGateway, PCA301, ConBee II, LuftdatenInfo, OneWireGW, Div. ESPs u. Shellys

Sailor

Zitat von: ergerd am 26 Oktober 2014, 08:03:24
Hallo an alle,

ich bin begeistert, auch bei mir funktioniert es jetzt!

Vielen Dank an die Entwickler!

Grüße
Rainer

Hallo Rainer

keine Ursache! Aber Vorsicht, viele Werte sind irgendwie trotz Lesbarkeit einfach nur Bockmist.

Ich arbeite dran!

M
******************************
Man wird immer besser...