Buderus Logamatic Web KM200 - Reloaded

Super,

danke Maeffjus werde ich heute Abend probieren.

Hallo Maeffjus,

das auslesen scheint zu funktionieren, aber wenn ich die Schaltprogramme aufrufe gibt es Probleme. :o
Bei der Programmauswahl erhalte ich ein Fehlerfenster wo dieses bemängelt wird:

Array to String conversion in Zeile 216
und
Trying to get property ‚switchpoints‘ of non object in Zeile 216

und das dann noch in weiteren Zeilen, 223, 236 …

Hast Du da noch eine Idee?

Jein, ehrlich gesagt - nicht so wirklich :slight_smile:
Aber: Geh mal brav alle Klammern durch, ob alle da & drin sind und keine zuviel!
Ich glaube ich hatte auch sowas in der Art.

Ansonsten müssen sich die Leute mit mehr Programmierwissen mal kümmern :wink:
BTW: Kann es sein, dass du extrem viele Sachen aktualisierst? Ich hatte vor Ewigkeiten auch mal irgendwie Probleme - aber ich weiß nicht ob es das gleich war, ich Frage die in Gruppen / Blöcken ab.
Gruß,
Maeffjus

Hallo,

das Problem ist schon wenn ich Programm „A“ oder „B“ auswähle, schein irgendwie mit dem Editor Script zusammen zu hängen.

Ich schau aber mal ob ich einen Fehler bei den Klammern finde.

Moin Horst,

ich vermute mal, dass du das Skript Funktionen meinst oder? Ich habe damals in dem Bereich die Klammerung so angepasst:

			if($global['sp_prog']->prog->{$global['programm']}->switchPoints == "empty"){   // wenn Speicher leer (Programm noch nicht geladen)
				$empty = true;
				meldung("010", 2);
				$taganzeige = "keine Daten vorhanden, bitte Programm laden ...";
				$wocheanzeige = "keine Daten vorhanden, bitte Programm laden ...";
				}

			elseif($global['sp_prog']->prog->{$global['programm']}->switchPoints == "noprog"){   // wenn Speicher leer (Programm wurde geladen)
            $noprog = true;
				meldung("011", 2);
				$taganzeige = "keine Daten vorhanden, bitte Programm erstellen ...";
				$wocheanzeige = "keine Daten vorhanden, bitte Programm erstellen ...";

				// Auswahl-Zeit-Slot auf Anzahl der belegten Slots beschränken
   				change_profil($profile['AuswahlSchaltpunkt'], 1, 0, 0, 0, "Slot ", "", "", "");

				SetValue($global['sp_editID'], '{"slotmax_act":0,"slotday_act":{"Mo":0,"Tu":0,"We":0,"Th":0,"Fr":0,"Sa":0,"Su":0},"switchPoints":[{"dayOfWeek":"Mo","setpoint":"0","time":0}]}');
				}

			elseif(array_key_exists($global['programm'], $global['sp_prog']->prog) and $empty == false and $noprog == false){   // wenn Parameter im Speicher vorhanden
				if($global['sp_prog']->prog->{$global['programm']}->write == 0){
			      $noedit = true;
			      meldung("013", 2);
					}
				else{
				   meldung("012", 2);
				   }
            $global['sp_edit']->slotmax_act = $global['sp_prog']->prog->{$global['programm']}->slotmax_act;
            $global['sp_edit']->slotday_act = $global['sp_prog']->prog->{$global['programm']}->slotday_act;
				$global['sp_edit']->switchPoints = $global['sp_prog']->prog->{$global['programm']}->switchPoints;
					SetValue($global['sp_editID'], json_encode($global['sp_edit']));

         // Profilanzeige erstellen

Ferner gibt es noch die Stelle mit dem each Befehl der in PHP 7 auch nicht mehr zur Verfügung steht :wink:

/*------------------------------------------------------------------------------
	Funktion HTML-Tabellen Wochenprofil und Tagesprofil erstellen
------------------------------------------------------------------------------*/
function anzeige_erstellen($set = true){
Global $global, $color, $profile;

	$sp_edit = json_decode(GetValue($global['sp_editID']));

// Wochenprofil
// -------------

	// Schaltpunkte auslesen
	foreach($sp_edit->switchPoints as $key => $array){
		$tmpprog[$array->dayOfWeek][] = $array;
		foreach ($tmpprog[$array->dayOfWeek] as $key => $pos) {
			$lastkey = $key;
		}
		$tmpprog[$array->dayOfWeek][$lastkey]->time = date("H:i", strtotime(floor($array->time/60).":".($array->time%60)));
	}
		//print_r($tmpprog);

	// Schaltpunkte auslesen
/*	foreach($sp_edit->switchPoints as $key => $array){
		$tmpprog[$array->dayOfWeek][] = $array;
		$pos = each($tmpprog[$array->dayOfWeek]);
		$tmpprog[$array->dayOfWeek][$pos['key']]->time = date("H:i", strtotime(floor($array->time/60).":".($array->time%60)));
	}
		print_r($tmpprog);
*/

Ich erhalte keine Fehlermeldungen mehr nutze das Programm aber eigentlich auch nicht, da die Steuerung über Homematic erfolgt.

Gruß
Hans

Hallo Hans,

danke für die Scripte, ich probiere das nachher aus , wenn ich zu Hause bin.

Hallo Hans,

klappt leider nicht.

Ich habe Deine Code-Schnipsel bei mir im Script ersetzt, aber leider bekomme ich immer noch den gleichen Fehler. :mad:
Das Script mit der Fehlermeldung ist das Funktions-Script.

Dann wird bei mir das Editor Script als Fehlerhaft markiert :confused:

Hallo Horst,

soll das heißen, dass der Fehler im Skript Funktionen immer noch unverändert auftritt? Das kann ich mir eigentlich nicht vorstellen da es bei mir funktioniert. Bist du sicher, dass du alles so angepasst hast? Ansonsten nochmals alles posten was an Fehlern kommt.

Im Editor Skript habe ich vor längerer Zeit nur die Min- Max-Werte der Schaltlevels auskommentiert, da es diese bei unserer Therme nicht gibt.

Gruß
Hans

Würde ich gerne machen, aber wie bekomme ich den Inhalt des Widgets kopiert?
Ich habe mal ein Screenshot ran gehangen.

Script 17345 ist das Funktions-Script.

Zeile 216 ist diese:

if($global['sp_prog']->prog->{$global['programm']}->switchPoints == "empty"){   // wenn Speicher leer (Programm noch nicht geladen) 

Hallo Horst,

genau so funktioniert es bei mir. Ich habe das geändert als die 5.x Version im Beta Stadium war. Es war sehr aufwendig rauszubekommen, welche Daten vom Typ Array und welche vom Typ StdClassObject sind. Letztendlich kannst du das nur ermitteln, wenn du in deiner Version dir die Datenstruktur anzeigen lässt um zu sehen, wo der Fehler liegen könnte :frowning:

Die Randbedingungen sind recht verschieden, da die generierten Variablen vom Typ der Therme und auch der Firmware des Gateways abhängen.

Ich habe eben extra nochmals die WebFront Version aufgerufen (ich habe noch eine Version für IPSView) um zu sehen, ob es da Probleme gibt, aber das funktioniert im Prinzip bei mir unter Windows 10. Wie erwähnt nutze ich das aber nicht mehr aktiv.

Dein Footer zeigt Diving - wo taucht ihr denn? Im Ohlenstedter See? :smiley:

Gruß
Hans

Da werde ich wohl überfordert sein. Naja mal sehen, das auslesen funktioniert ja.

Nee, da waren wir noch nicht zum tauchen. :rolleyes: Woher kennst Du den, kommst Du aus der Ecke?
2x im Jahr in Hurghada, gelegentlich dann auch in Deutschland.
Waren gerade letzte Woche im Sundhäuser See in Nordhausen.

Du tauchst auch?

Hallo Horst,

die benachbarte Hansestadt ist nicht weit weg :wink:

Ich habe vor 25 Jahren mal auf den Malediven einen Tauchschein gemacht - das war schon echt irre was es zu sehen gab. Coral bleaching war damals dort noch kein Thema. Ich bin aber kein aktiver Taucher.

Ich habe mein Buderus Gateway vor kurzem aus Versehen auf FW 04.04.05 gebracht und hatte dann auch gleich wieder ein paar Stellen die angepasst werden mussten - ja, man sollte nichts ändern :slight_smile:

Gruß
Hans

Du meinst aber nicht HB? Dann wären wir ja fast Nachbarn. :smiley:

Hallo Horst,

doch oder kennst du noch eine andere Hansestadt in der Nähe von der ich nichts weiß? :smiley:

Gruß
Hans

Dann sollten wir uns mal über PN unterhalten geht jetzt etwas am Thema vorbei.

kein Problem :slight_smile:

Hallo zusammen,

auch nach mehrmaligem Lesen des Threads, ist mir der aktuelle Stand der Dinge hinsichtlich „funktioniert unter IPS 4.4“ nicht ganz klar.
Das Skript zum Anlegen der Variablen tut nichts, einzig folgende Meldung erscheint:
KM 200.JPG

Den AES-Key für das Kommunikationsskript hatte ich mir entsprechend generieren lassen, das Passwort hatte ich hierbei ohne die „-“ zwischen den Viererblöcken eingegeben.
Der Zugriff per App funktioniert.

Irgendwas habe ich jetzt in der ganzen Litanei überlesen oder evtl. noch einen grundlegenden „Hänger“.
Kann mir jemand auf die Sprünge helfen ?

Danke im Voraus.

<?
include_once( "10163 /*[Skripte\KM 200 Komm neu]*/.ips.php" ); // KM200 Gateway
$RootCategoryID = 16808 /*[KM 200 Var]*/;
$km200_REST_URLs = array(   '/gateway',    '/system',    '/heatingCircuits',    '/solarCircuits',    '/heatSources',);
function CreateCategory( $Name, $Ident = '', $ParentID = 0 )
{
   global $RootCategoryID;
   echo "CreateCategory: ( $Name, $Ident, $ParentID ) 
";
    if ( '' != $Ident )
    {
        $CatID = @IPS_GetObjectIDByIdent( $Ident, $ParentID );
        if ( false !== $CatID )
        {
            $Obj = IPS_GetObject( $CatID );
            if ( 0 == $Obj['ObjectType'] ) // is category?
                return $CatID;
        }
    }
    $CatID = IPS_CreateCategory();
    IPS_SetName( $CatID, $Name );
    IPS_SetIdent( $CatID, $Ident );
   if ( 0 == $ParentID )
        if ( IPS_ObjectExists( $RootCategoryID ) )
            $ParentID = $RootCategoryID;
        IPS_SetParent( $CatID, $ParentID );
    return $CatID;
}

function SetVariable( $VarID, $Type, $Value )
{
    switch( $Type )
    {
        case 0: // boolean
            SetValueBoolean( $VarID, $Value );
            break;
      case 1: // integer
            SetValueInteger( $VarID, $Value );
            break;
        case 2: // float
            SetValueFloat( $VarID, $Value );
            break;
        case 3: // string
            SetValueString( $VarID, $Value );
            break;
    }
}

function CreateVariable( $Name, $Type, $Value, $Ident = '', $ParentID = 0 )
{
    echo "CreateVariable: ( $Name, $Type, $Value, $Ident, $ParentID ) 
";
    if ( '' != $Ident )
    {
        $VarID = @IPS_GetObjectIDByIdent( $Ident, $ParentID );
        if ( false !== $VarID )
        {
            SetVariable( $VarID, $Type, $Value );
            return;
        }
    }
    $VarID = @IPS_GetObjectIDByName( $Name, $ParentID );
    if ( false !== $VarID ) // exists?
    {
        $Obj = IPS_GetObject( $VarID );
        if ( 2 == $Obj['ObjectType'] ) // is variable?
        {
            $Var = IPS_GetVariable( $VarID );
            if ( $Type == $Var['VariableValue']['ValueType'] )
            {
                SetVariable( $VarID, $Type, $Value );
                return;
            }
        }
    }
    $VarID = IPS_CreateVariable( $Type );
    IPS_SetParent( $VarID, $ParentID );
    IPS_SetName( $VarID, $Name );
    if ( '' != $Ident )
        IPS_SetIdent( $VarID, $Ident );
    SetVariable( $VarID, $Type, $Value );
}



function Traverse_REST_URL( $REST_Service, $ParentID = 0 )
{
    $Name = $REST_Service;
    $REST_Obj = km200_GetData( $REST_Service );
    if( NULL == $REST_Obj )
    {
        echo "Service $REST_Service returned NULL
";
        return;
    }
    $Ident = str_replace( '/', '0', $REST_Obj->id );
   if ( property_exists( $REST_Obj, 'writeable' ) )
        if( 0 !== $REST_Obj->writeable )
            $Name .= " (writeable)";
        if ( property_exists( $REST_Obj, 'recordable' ) )
            if( 0 !== $REST_Obj->writeable )
                $Name .= " (recordable)";
    switch( $REST_Obj->type )
     {
         case 'refEnum':           // create category
             $CatID = CreateCategory( $Name, $Ident, $ParentID );          // loop through enum array
             foreach( $REST_Obj->references as $SubService )
             Traverse_REST_URL( $SubService->id, $CatID ); // recurse
             break;
        case 'moduleList':           // create category
            $CatID = CreateCategory( $Name, $Ident, $ParentID );          // loop through values array
            foreach( $REST_Obj->values as $Modules )
                CreateVariable( $Modules->Name, 3, $Modules->Version, $Ident . "0" . $Modules->Token, $CatID );
            break;
        case 'floatValue':
            CreateVariable( $Name, 2, $REST_Obj->value, $Ident, $ParentID );
            break;
        case 'stringValue':
            CreateVariable( $Name, 3, $REST_Obj->value, $Ident, $ParentID );
            break;
        case 'switchProgram':
            CreateVariable( $Name, 3, "switchProgram, toDo!", $Ident, $ParentID );
            break;
        default:
            echo "$Name ist Typ $REST_Obj->type !
";
            CreateVariable( $Name + $REST_Obj->type, 3, (string) $REST_Obj->value, $Ident, $ParentID );
            break;
    }
}


foreach( $km200_REST_URLs as $REST_Service )
    Traverse_REST_URL( $REST_Service, $RootCategoryID )

und das hier:

<?php

// IP Adresse oder DNS-Hostname des KM200
define( "km200_gateway_host", '192.168.1.35', true );
// Port des KM200, nur bei Zugriff über Internet mit Portweiterleitung am Router ändern!
define( "km200_gateway_port", '80', true );



/*

Für die Einbindung des Schlüssels zur Kommunikation mit dem KM200 gibt es mehrere Möglichkeiten.

1. PHP only
  Online unter https://ssl-account.com/km200.andreashahn.info/
  mit Geräte- und Benutzer-Passwort den AES-Key ausrechnen lassen und folgende Zeile in das Coding einbinden:

define( "km200_crypt_key_private", hex2bin( '1f733c2af8c855981e84bb2952a77f0dc04cc65abf979b733ec8a6724c0c0369' ), true );

  Hier den Parameter von hex2bin durch den eigenen AES-Key ersetzen

2. IP Symcon-Modul, Passwörter in den Moduleigenschaften
  Online unter https://ssl-account.com/km200.andreashahn.info/ das IP Symcon-Modul herunter laden, entpacken und
  im IP Symcon Verzeichnis im Unterordner "modules" installieren. Falls der Ordner nicht vorhanden ist diesen
  einfach vorab erstellen. Den IP Symcon-Dienst stoppen und wieder starten.

  Nun über das Kontextmenü "Objekt hinzufügen->Instanz hinzufügen" unter "(Sonstige)" die Instanz
  "AES-Key-Generator for KM200 Web Gateway" auswählen.

  In den Moduleigenschaften Geräte- und Benutzer-Passwort setzen und folgende Zeile in das Coding einbinden:

define( "km200_crypt_key_private", hex2bin( KM200_GetAESKey( Modul-ID ) ), true );

  Hier den Parameter "Modul-ID" durch die Objekt-ID des Moduls ersetzen

3. IP Symcon-Modul, Passwörter über den Funktionsaufruf
  Das IP Symcon-Modul wie unter 2. beschrieben herunterladen, installieren und eine Instanz erzeugen.

  Unabhängig von den Moduleigenschaften kann der Schlüssel über eine Funktion mit Geräte- und Benutzer-
  Passwort als Parameter erzeugt werden. Dies ist z.B. wünschenswert, wenn das Benutzer-Passwort nicht
  gespeichert werden sondern jedes mal nteraktiv abgefragt werden soll.

  Hierfür folgende Zeile in das Coding einbinden:

define( "km200_crypt_key_private", hex2bin( KM200_GetAESKeyWithPasswords( Modul-ID, BenutzerPasswort, GerätePassword ) ), true );

  Hier den Parameter "Modul-ID" durch die Objekt-ID des Moduls ersetzen sowie entsprechend Benutzer-
  und Geräte-Passwort.

*/

// Hier nochmals alle drei Varianten, bitte nur GENAU EINE auskommentieren und anpassen!
// define( "km200_crypt_key_private", hex2bin( '21D3CF8751ED6BB163BE8C7CDE20210E0C2F9378C0DA3108F0673987B0D63E37' ), true );
// define( "km200_crypt_key_private", hex2bin( KM200_GetAESKey( Modul-ID ) ), true );
// define( "km200_crypt_key_private", hex2bin( KM200_GetAESKeyWithPasswords( Modul-ID, BenutzerPasswort, GerätePassword ) ), true );
define( "km200_crypt_key_private", hex2bin( '34cd07cc65998d7c1d864d911a865722622ff9602ee77879c5a2cdae9d2b6096' ), true );

function km200_Encrypt( $encryptData )
{
    // add PKCS #7 padding
    $blocksize = mcrypt_get_block_size(
        MCRYPT_RIJNDAEL_128,
        MCRYPT_MODE_ECB
    );
    $encrypt_padchar = $blocksize - ( strlen( $encryptData ) % $blocksize );
    $encryptData .= str_repeat( chr( $encrypt_padchar ), $encrypt_padchar );
    // encrypt
    return base64_encode(
        mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128,
            km200_crypt_key_private,
            $encryptData,
            MCRYPT_MODE_ECB,
            ''
        )
    );
}

function km200_Decrypt( $decryptData )
{
    $decrypt = (
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            km200_crypt_key_private,
            base64_decode( $decryptData ),
            MCRYPT_MODE_ECB,
            ''
        )
    );
    // remove zero padding
    $decrypt = rtrim( $decrypt, "\x00" );
    // remove PKCS #7 padding
    $decrypt_len = strlen( $decrypt );
    $decrypt_padchar = ord( $decrypt[ $decrypt_len - 1 ] );
    for ( $i = 0; $i < $decrypt_padchar ; $i++ )
    {
        if ( $decrypt_padchar != ord( $decrypt[$decrypt_len - $i - 1] ) )
        break;
    }
    if ( $i != $decrypt_padchar )
        return $decrypt;
    else
        return substr(
            $decrypt,
            0,
            $decrypt_len - $decrypt_padchar
        );
}

function km200_GetData( $REST_URL )
{
    $options = array(
        'http' => array(
           'method' => "GET",
           'header' => "Accept: application/json
" .
                        "User-Agent: TeleHeater/2.2.3
"
        )
    );
    $context = stream_context_create( $options );
    $content = @file_get_contents(
        'http://' . km200_gateway_host . ':' . km200_gateway_port . $REST_URL,
        false,
        $context
    );

    if ( false === $content )
        return false;
    return json_decode(
        km200_Decrypt(
            $content
        )
    );
}

function km200_SetData( $REST_URL, $Value )
{
    $content = json_encode(
        array(
            "value" => $Value
        )
    );
    $options = array(
        'http' => array(
           'method' => "PUT",
            'header' => "Content-type: application/json
" .
                        "User-Agent: TeleHeater/2.2.3
",
            'content' => km200_Encrypt( $content )
        )
    );
    $context = stream_context_create( $options );
    @file_get_contents(
        'http://' . km200_gateway_host . ':' . km200_gateway_port . $REST_URL,
        false,
        $context
    );
}


Kann mir niemand helfen ?

Du hast eine PN. :slight_smile:

Hat geklappt,
vielen Dank für die Unterstützung.