Türöffner mit Euracom Fritzbox und IPS

Heute hab ich endlich geschafft mit IPS meine Haustür zu Öffnen.
Ausgangssituation:
TürAktor an Euracom per Telefon Code #071 zu Öffnen
Fritzbox 7390 an Euracom per Analog Anschluss an der Fritzbox

Über ISDN_Connect hab ich alles Möglich versucht die #071 über die Fritzbox an die Euracom zu bekommen, aber keine Chance.
Da blieb also nur die Wahlhilfe.

Ich habe mir aus den fritzbox-7270-wlan-repeater-scripts folgendes zusammenkopiert:
fritzbox.conf.php


<?php
#####################################################
#################### the config #####################
#####################################################

# set to your Fritz!Box IP address or DNS name (defaults to fritz.box), for remote config mode, use the dyndns-name like example.dyndns.org
$fritzbox_ip = 'fritz.box';

# if needed, enable remote config here
#$enable_remote_config   = true;
#$remote_config_user     = 'test';
#$remote_config_password = 'test123';

# set to your Fritz!Box password (defaults to no password)
$password    = "password";

# set the logging mechanism (defaults to console logging)
$logging     = 'console'; // output to the console
#$logging     = 'silent';  // do not output anything, be careful with this logging mode
#$logging     = 'tam.log'; // the path to a writeable logfile

# the newline character for the logfile (does not need to be changed in most cases)
$newline = (PHP_OS == 'WINNT') ? "
" : "
";


############## module specific config ###############

# set the path for the call list for the foncalls module
$foncallslist_path = dirname(__FILE__) . '/foncallsdaten.xml';

fritzbox_api.class.php

<?php
/**
* Fritz!Box API - A simple wrapper for automatted changes in the Fritz!Box Web-UI
*
* handles the new secured login/session system and implements a cURL wrapper
* new in v0.2: Can handle remote config mode via https://example.dyndns.org
* new in v0.3: New method doGetRequest handles GET-requests
*
* @author   Gregor Nathanael Meyer <Gregor [at] der-meyer.de>
* @license  http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons cc-by-sa
* @version  0.3 2010-05-19
* @package  Fritz!Box PHP tools
*/

/* A simple usage example
*
* require_once('fritzbox_api.class.php');
* try
* {
*   $fritz = new fritzbox_api('password', 'fritz-box');
*   $formfields = array(
*     'getpage'                  => '../html/de/menus/menu2.html', // the getpage parameter is mandatory
*     'tam:settings/TAM0/Active' => 1, // enables the first answering machine, any POST-field from the Web-UI can be used
*   );
*   $fritz->doPostForm($formfields);   // send the command
*   $fritz = null;                     // destroy the object to log out
* }
* catch (Exception $e)
* {
*   echo $e->getMessage();             // schow the error message in anything failed
* }
*
*/

/**
* the main Fritz!Box API class
*
*/
class fritzbox_api {
 /**
    * @var  string  the Fritz!Box password, set by the constructor
    */
 protected $password;

 /**
    * @var  bool    enable remote config mode, set by the constructor
    */
 protected $enable_remote_config;

 /**
    * @var  string  username for remote config mode, set by the constructor
    */
 protected $remote_config_user;

 /**
    * @var  string  password for remote config mode, set by the constructor
    */
 protected $remote_config_password;

 /**
    * @var  string  the Fritz!Box base URL, set by the constructor
    */
 protected $fritzbox_url;

 /**
    * @var  string  the session ID, set by method initSID() after login
    */
 protected $sid = '0000000000000000';


 /**
    * the constructor, initializes the object and calls the login method
    *
    * @access public
    * @param  string $password                the Fritz!Box password, optional, defaults to null
    * @param  string $fritzbox_ip             the Fritz!Box IP address or DNS name, optional, defaults to fritz.box
    * @param  bool   $enable_remote_config    set true to enable remote config, optional, defaults to false
    * @param  string $remote_config_user      the remote config username, mandatory, if remote config is used
    * @param  string $remote_config_password  the remote config password, mandatory, if remote config is used
    */
 public function __construct($password = null, $fritzbox_ip = 'fritz.box', $enable_remote_config = false, $remote_config_user = null, $remote_config_password = null)
 {
    $this->password = $password;
   
    if ( $enable_remote_config === true )
    {
     if ( !isset($remote_config_user) || !isset($remote_config_password) )
     {
       $this->error('ERROR: Remote config mode enabled, but no username or no password provided');
     }
     $this->fritzbox_url            = 'https://' . $fritzbox_ip;
     $this->enable_remote_config    = true;
     $this->remote_config_user      = $remote_config_user;
     $this->remote_config_password  = $remote_config_password;
    }
    else
    {
     $this->fritzbox_url            = 'http://' . $fritzbox_ip;
     $this->enable_remote_config    = false;
     $this->remote_config_user      = null;
     $this->remote_config_password  = null;
    }
   
    $this->sid = $this->initSID();
 }


 /**
    * the destructor just calls the logout method
    *
    * @access public
    */
 public function __destruct()
 {
    $this->logout();
 }


 /**
    * do a POST request on the box
    * the main cURL wrapper handles the command
    *
    * @access public
    * @param  array  $formfields    an associative array with the POST fields to pass
    * @return string                the raw HTML code returned by the Fritz!Box
    */
 public function doPostForm($formfields = array())
 {
    // add the sid, if it is already set
    if ($this->sid != '0000000000000000')
    {
     $formfields['sid'] = $this->sid;
    }    

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $this->fritzbox_url . '/cgi-bin/webcm');
    curl_setopt($ch, CURLOPT_POST, 1);
    if ( $this->enable_remote_config )
    {
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_USERPWD, $this->remote_config_user . ':' . $this->remote_config_password);
    }
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($formfields));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
 }


 /**
    * do a GET request on the box
    * the main cURL wrapper handles the command
    *
    * @access public
    * @param  array  $params    an associative array with the GET params to pass
    * @return string            the raw HTML code returned by the Fritz!Box
    */
 public function doGetRequest($params = array())
 {
    // add the sid, if it is already set
    if ($this->sid != '0000000000000000')
    {
     $params['sid'] = $this->sid;
    }    

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $this->fritzbox_url . '/cgi-bin/webcm?' . http_build_query($params));
    curl_setopt($ch, CURLOPT_HTTPGET, 1);
    if ( $this->enable_remote_config )
    {
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_USERPWD, $this->remote_config_user . ':' . $this->remote_config_password);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
 }


 /**
    * the login method, handles the secured login-process
    * newer firmwares (xx.04.74 and newer) need a challenge-response mechanism to prevent Cross-Site Request Forgery attacks
    * see http://www.avm.de/de/Extern/Technical_Note_Session_ID.pdf for details
    *
    * @access protected
    * @return string                a valid SID, if the login was successful, otherwise throws an Exception with an error message
    */
 protected function initSID()
 {
    // read the current status
    $ch = curl_init($this->fritzbox_url . '/cgi-bin/webcm?getpage=../html/login_sid.xml');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if ( $this->enable_remote_config )
    {
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ch, CURLOPT_USERPWD, $this->remote_config_user . ':' . $this->remote_config_password);
    }
    $output = curl_exec($ch);
    curl_close($ch);
    $session_status_simplexml = simplexml_load_string($output);
   
    // perhaps we already have a SID (i.e. when no password is set)
    if ($session_status_simplexml->iswriteaccess == 1)
    {
     return $session_status_simplexml->SID;
    }
    // we have to login and get a new SID
    else
    {
     // the challenge-response magic, pay attention to the mb_convert_encoding()
     $challenge = $session_status_simplexml->Challenge;
     $response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->password, "UCS-2LE", "UTF-8"));
     
     // do the login
     $formfields = array(
       'getpage'                => '../html/de/menus/menu2.html',
       'login:command/response' => $response,
     );
     $output = $this->doPostForm($formfields);
     
     // finger out an error message, if given
     preg_match('@<p class="errorMessage">(.*?)</p>@is', $output, $matches);
     if (isset($matches[1]))
     {
       $this->error(str_replace(' ', ' ', $matches[1]));
     }
     
     // finger out the SID from the response
     preg_match('@<input type="hidden" name="sid" value="([A-Fa-f0-9]{16})" id="uiPostSid">@i', $output, $matches);
     if (isset($matches[1]) && $matches[1] != '0000000000000000')
     {
       return $matches[1];
     }
     else
     {
       $this->error('ERROR: Login failed with an unknown response');
     }
    }
 }


 /**
    * the logout method just sends a logout command to the Fritz!Box
    *
    * @access protected
    */
 protected function logout()
 {
    $formfields = array(
     'getpage'                 => '../html/de/menus/menu2.html',
     'security:command/logout' => 'logout',
    );
    $this->doPostForm($formfields);
 }


 /**
    * the error method just throws an Exception
    *
    * @access protected
    * @param  string   $message     an error message for the Exception
    */
 protected function error($message = null)
 {
    throw new Exception($message);
 }


 /**
    * a getter for the session ID
    *
    * @access public
    * @return string                $this->sid
    */
 public function getSID()
 {
    return $this->sid;
 }
}

und dann ein Script in IPS angelegt


<?

require_once('fritzbox_api.class.php');
 try
 {
    $fritz = new fritzbox_api('password', 'fritz.box');
    $formfields = array(
     'getpage'                  => '../html/de/menus/menu2.html', // the getpage parameter is mandatory
     'telcfg:settings/UseClickToDial' => 1, // enables the first answering machine, any POST-field from the Web-UI can be used
     "telcfg:command/Dial"=>"*10#*##071",
     "telcfg:settings/DialPort"=>"50"
  );
  $fritz->doPostForm($formfields);   // send the command
  $fritz = null;                     // destroy the object to log out
}
catch (Exception $e)
{
  echo $e->getMessage();             // schow the error message in anything failed
}
?>

und siehe da. Der Türsummer summt.

Cool - ich bin immer wieder begeistert was alles möglich ist :slight_smile:

Meine Keymatic sollte heute eintreffen ^^

Eine Frage habe ich dann aber doch: Wenn Du einen elektrischen Türöffner hast, warum der Umweg über Fritzbox und TK Anlage ? Wäre es mit einem beliebigen Funkaktor nicht einfacher gegangen ?

Gruß
Martin

Der direktere Weg ist - sofern Homematic vorhanden - einfach einen Unterputz Funk Taster Sender an einen Relaisausgang der Telefonanlage zu hängen und damit dann über IPS die Keymatic zu triggern. Hat bei mir gleich noch den positiven Nebeneffekt dass ich über die Türsprechstelle auch gleich mitbekomme (2. Relaisausgang) wenn jemand klingelt. Damit triggere ich dann ein Skript welches vom Besucher (Kamera in der Einfahrt) gleich einen Snapshot an mich mailt.

Homematic wäre ja vorhanden, aber dann hätte ich alles neu verkabeln müssen. Da die Türklingel ja auch über die Euracom an die FritzBox geht, bekomme ich das Klingeln natürlich auch mit. Bild Mailen, umschalten des Webfront auf die Cam etc geht somit auch alles.

War keine Kritik. Ich versuche nur die Signalkette immer so kurz wie möglich zu halten weil dann weniger Fehlerquellen drin sind.

Zu viele Köche verderben die Köchin…

Hey, sowas versuch ich grade mit der Doorline zu realisieren.

Habe unter

"telcfg:command/Dial"=>"*10#*##071",

Folgendes eingetragen

"telcfg:command/Dial"=>"**1#9",

Die Doorline öffnet man in dem man sie mit **1 anruft und dann #9 drückt.
Wenn ich das Script so ausführe, klingelt mein ISDN Telefon, mit dem Hinweis im Display „**1 ruft an“

Kannst du mir deine Zeile entschlüsseln, dass ich sie an die Doorline anpassen kann?

Hallo und Frohes Fest.
Mit der *10# sage ich das der Analoge Anschluss der Frtizbox genutzt werden soll, und die Telefonanalge die da drann hängt denkt dann ein Telefon hebt ab, und dann wird #071 gewählt.

Ebenfalls frohes Fest :wink:
Das wir es sein was mir fehlt. Die TK Anlage dazwischen. Ich bekomms mit der FB alleine nicht hin…

Gesendet von meinem HTC Desire HD A9191

funktioniert bei mir nicht…
liegt wahrscheinlich am login der neuen
Firmware 5.52 Fritzbox 7390…
das api passt nicht mehr…?

Gibts da was neues?
Gruß Konny

Würde mich auch interessiert … ich bekomme das Ganze auch nicht zum laufen. Fehler sind:

PHP-Error-Warning: simplexml_load_string(): Entity: line 1: parser error : AttValue: " or ' expected
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): Entity: line 1: parser error : AttValue: " or ' expected in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string():                  ^
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string():                  ^ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): Entity: line 1: parser error : attributes construct error
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): Entity: line 1: parser error : attributes construct error in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string():                  ^
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string():                  ^ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): Entity: line 1: parser error : Couldn't find end of Start Tag META line 1
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): Entity: line 1: parser error : Couldn't find end of Start Tag META line 1 in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string():                  ^
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string():                  ^ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): Entity: line 1: parser error : Extra content at the end of the document
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): Entity: line 1: parser error : Extra content at the end of the document in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string(): <META HTTP-EQUIV=Refresh CONTENT="0; URL=/login.lua?requestedpage=../html/login_ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Warning: simplexml_load_string():                  ^
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
Warning:  simplexml_load_string():                  ^ in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 170
PHP-Error-Notice: Trying to get property of non-object
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 173
Notice:  Trying to get property of non-object in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 173
PHP-Error-Notice: Trying to get property of non-object
   Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 181
Notice:  Trying to get property of non-object in D:\IP-Symcon\scripts\fritzbox_api.class.php on line 181
ERROR: Login failed with an unknown response

Eine Idee wäre gut … ich hänge.

Obige fritzbox_api.class.php ist veraltet. Sie wirft mit der aktuellen Firmware wilde Login Fehler, wie: "PHP]PHP-Error-Warning: simplexml_load_string(): Entity: line 1: parser error : AttValue: " or ’ expected
Error in Script D:\IP-Symcon\scripts\fritzbox_api.class.php on Line 170
"

<?php
/**
 * Fritz!Box API - A simple wrapper for automatted changes in the Fritz!Box Web-UI
 * 
 * handles the new secured login/session system and implements a cURL wrapper
 * new in v0.2: Can handle remote config mode via https://example.dyndns.org
 * new in v0.3: New method doGetRequest handles GET-requests
 * new in v0.4: Added support for the new .lua forms like the WLAN guest access settings
 * new in v5.0: added support for the new .lua-loginpage in newest Fritz!OS firmwares and refactored the code
 * 
 * @author   Gregor Nathanael Meyer <Gregor [at] der-meyer.de>
 * @license  http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons cc-by-sa
 * @version  0.5.0b7 2013-01-02
 * @package  Fritz!Box PHP tools
 */


/* A simple usage example
 *
 * try
 * { 
 *   // load the fritzbox_api class
 *   require_once('fritzbox_api.class.php');
 *   $fritz = new fritzbox_api();
 
 *   // init the output message
 *   $message = date('Y-m-d H:i') . ' ';
 *   
 *   // update the setting
 *   $formfields = array(
 *     'telcfg:command/Dial'      => '**610',
 *   );
 *   $fritz->doPostForm($formfields);
 *   $message .= 'Phone ' . $dial . ' ringed.';
 * }
 * catch (Exception $e)
 * {
 *   $message .= $e->getMessage();
 * }
 *
 * // log the result
 * $fritz->logMessage($message);
 * $fritz = null; // destroy the object to log out
 */
 
/**
 * the main Fritz!Box API class
 *
 */
class fritzbox_api {
  /**
    * @var  object  config object
    */
  public $config = array();
  
  /**
    * @var  string  the session ID, set by method initSID() after login
    */
  protected $sid = '0000000000000000';
  
  
  /**
    * the constructor, initializes the object and calls the login method
    * 
    * @access public
    */
  public function __construct($config_version = 'standard')
  {
    // init the config object
    $this->config = new fritzbox_api_config();
    
    if ( $config_version != 'standard' )
    {
      // try autoloading the $config_version_config
      if ( file_exists(__DIR__ . '/fritzbox_user_' . $config_version . '.conf.php') && is_readable(__DIR__ . '/fritzbox_user_' . $config_version . '.conf.php') )
      {
        require_once(__DIR__ . '/fritzbox_user_' . $config_version . '.conf.php');
      }
      else
      {
        $this->error('Could not load ' . __DIR__ . '/fritzbox_user_' . $config_version . '.conf.php');
      }
    }
    else
    {
      // try autoloading the config
      if ( file_exists(__DIR__ . '/fritzbox_user.conf.php') && is_readable(__DIR__ . '/fritzbox_user.conf.php') )
      {
        require_once(__DIR__ . '/fritzbox_user.conf.php');
      }
    }
    
    // make some config consistency checks
    if ( $this->config->getItem('enable_remote_config') === true )
    {
      if ( !$this->config->getItem('remote_config_user') || !$this->config->getItem('remote_config_password') )
      {
        $this->error('ERROR: Remote config mode enabled, but no username or no password provided');
      }
      $this->config->setItem('fritzbox_url', 'https://' . $this->config->getItem('fritzbox_ip'));
    }
    else
    {
      $this->config->setItem('fritzbox_url', 'http://' . $this->config->getItem('fritzbox_ip'));
      $this->config->setItem('old_remote_config_user', null);
      $this->config->setItem('old_remote_config_password', null);
    }
    
    $this->sid = $this->initSID();
  }
  
  
  /**
    * the destructor just calls the logout method
    * 
    * @access public
    */
  public function __destruct()
  {
    $this->logout();
  }
  
  
  /**
    * do a POST request on the box
    * the main cURL wrapper handles the command
    * 
    * @param  array  $formfields    an associative array with the POST fields to pass
    * @return string                the raw HTML code returned by the Fritz!Box
    */
  public function doPostForm($formfields = array())
  {
    $ch = curl_init();
    if ( isset($formfields['getpage']) && strpos($formfields['getpage'], '.lua') > 0 )
    {
      curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . $formfields['getpage'] . '?sid=' . $this->sid);
      unset($formfields['getpage']);
    }
    else
    {
      // add the sid, if it is already set
      if ($this->sid != '0000000000000000')
      {
        $formfields['sid'] = $this->sid;
      }   
      curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . '/cgi-bin/webcm');
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    if ( $this->config->getItem('enable_remote_config') )
    {
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      // support for pre FRITZ!OS 5.50 remote config
      if ( !$this->config->getItem('use_lua_login_method') )
      {
        curl_setopt($ch, CURLOPT_USERPWD, $this->config->getItem('remote_config_user') . ':' . $this->config->getItem('remote_config_password'));
      }
    }
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($formfields));
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
  }
  
  
  /**
    * do a GET request on the box
    * the main cURL wrapper handles the command
    * 
    * @param  array  $params    an associative array with the GET params to pass
    * @return string            the raw HTML code returned by the Fritz!Box
    */
  public function doGetRequest($params = array())
  {
    // add the sid, if it is already set
    if ($this->sid != '0000000000000000')
    {
      $params['sid'] = $this->sid;
    }    
  
    $ch = curl_init();
    if ( strpos($params['getpage'], '.lua') > 0 )
    {
      $getpage = $params['getpage'] . '?';
      unset($params['getpage']);
    }
    else
    {
      $getpage = '/cgi-bin/webcm?';
    }
    curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . $getpage . http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPGET, 1);
    if ( $this->config->getItem('enable_remote_config') )
    {
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      // support for pre FRITZ!OS 5.50 remote config
      if ( !$this->config->getItem('use_lua_login_method') )
      {
        curl_setopt($ch, CURLOPT_USERPWD, $this->config->getItem('remote_config_user') . ':' . $this->config->getItem('remote_config_password'));
      }
    }
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
  }
  
  
  /**
    * the login method, handles the secured login-process
    * newer firmwares (xx.04.74 and newer) need a challenge-response mechanism to prevent Cross-Site Request Forgery attacks
    * see http://www.avm.de/de/Extern/Technical_Note_Session_ID.pdf for details
    * 
    * @return string                a valid SID, if the login was successful, otherwise throws an Exception with an error message
    */
  protected function initSID()
  {
    // determine, wich login type we have to use
    if ( $this->config->getItem('use_lua_login_method') == true )
    {
      $loginpage = '/login_sid.lua';
    }
    else
    {
      $loginpage = '../html/login_sid.xml';
    }
    
    // read the current status
    $session_status_simplexml = simplexml_load_string($this->doGetRequest(array('getpage' => $loginpage)));
    
    if ( !is_object($session_status_simplexml) || get_class($session_status_simplexml) != 'SimpleXMLElement' )
    {
      $this->error('Response of initialization call ' . $loginpage . ' in ' . __FUNCTION__ . ' was not xml-formatted.');
    }
    
    // perhaps we already have a SID (i.e. when no password is set)
    if ( $session_status_simplexml->SID != '0000000000000000' )
    {
      return $session_status_simplexml->SID;
    }
    // we have to login and get a new SID
    else
    {
      // the challenge-response magic, pay attention to the mb_convert_encoding()
      $challenge = $session_status_simplexml->Challenge;
      
      // do the login
      $formfields = array(
        'getpage'                => $loginpage,
      );
      if ( $this->config->getItem('use_lua_login_method') )
      {
        if ( $this->config->getItem('enable_remote_config') )
        {
          $formfields['username'] = $this->config->getItem('remote_config_user');
          $response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->config->getItem('remote_config_password'), "UCS-2LE", "UTF-8"));
        }
        else
        {
          if ( $this->config->getItem('username') )
          {
            $formfields['username'] = $this->config->getItem('username');
          }
          $response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->config->getItem('password'), "UCS-2LE", "UTF-8"));
        }
        $formfields['response'] = $response;
      }
      else
      {
        $response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->config->getItem('password'), "UCS-2LE", "UTF-8"));
        $formfields['login:command/response'] = $response;
      }
      $output = $this->doPostForm($formfields);
      
      // finger out the SID from the response
      $session_status_simplexml = simplexml_load_string($output);
      if ( !is_object($session_status_simplexml) || get_class($session_status_simplexml) != 'SimpleXMLElement' )
      {
        $this->error('Response of login call to ' . $loginpage . ' in ' . __FUNCTION__ . ' was not xml-formatted.');
      }
      
      if ( $session_status_simplexml->SID != '0000000000000000' )
      {
        return (string)$session_status_simplexml->SID;
      }
      else
      {
        $this->error('ERROR: Login failed with an unknown response.');
      }
    }
  }
  
  
  /**
    * the logout method just sends a logout command to the Fritz!Box
    * 
    */
  protected function logout()
  {
    if ( $this->config->getItem('use_lua_login_method') == true )
    {
      $this->doGetRequest(array('getpage' => '/home/home.lua', 'logout' => '1'));
    }
    else
    {
      $formfields = array(
        'getpage'                 => '../html/de/menus/menu2.html',
        'security:command/logout' => 'logout',
      );
      $this->doPostForm($formfields);
    }
  }
  
  
  /**
    * the error method just throws an Exception
    * 
    * @param  string   $message     an error message for the Exception
    */
  public function error($message = null)
  {
    throw new Exception($message);
  }
  
  
  /**
    * a getter for the session ID
    * 
    * @return string                $this->sid
    */
  public function getSID()
  {
    return $this->sid;
  }
  
  /**
    * log a message
    * 
    * @param  $message  string  the message to log
    */
  public function logMessage($message)
  {
    if ( $this->config->getItem('newline') == false )
    {
      $this->config->setItem('newline', (PHP_OS == 'WINNT') ? "
" : "
");
    }
  
    if ( $this->config->getItem('logging') == 'console' )
    {
      echo $message;
    }
    else if ( $this->config->getItem('logging') == 'silent' || $this->config->getItem('logging') == false )
    {
      // do nothing
    }
    else
    {
      if ( is_writable($this->config->getItem('logging')) || is_writable(dirname($this->config->getItem('logging'))) )
      {
        file_put_contents($this->config->getItem('logging'), $message . $this->config->getItem('newline'), FILE_APPEND);
      }
      else
      {
        echo('Error: Cannot log to non-writeable file or dir: ' . $this->config->getItem('logging'));
      }
    }
  }
}


class fritzbox_api_config {
  protected $config = array();


  public function __construct()
  {
    # use the new .lua login method in current (end 2012) labor and newer firmwares (Fritz!OS 5.50 and up)
    $this->setItem('use_lua_login_method', true);
    
    # set to your Fritz!Box IP address or DNS name (defaults to fritz.box), for remote config mode, use the dyndns-name like example.dyndns.org
    $this->setItem('fritzbox_ip', 'fritz.box');


    # if needed, enable remote config here
    #$this->setItem('enable_remote_config', true);
    #$this->setItem('remote_config_user', 'test');
    #$this->setItem('remote_config_password', 'test123');


    # set to your Fritz!Box username, if login with username is enabled (will be ignored, when remote config is enabled)
    $this->setItem('username', false);
    
    # set to your Fritz!Box password (defaults to no password)
    $this->setItem('password', false);


    # set the logging mechanism (defaults to console logging)
    $this->setItem('logging', 'console'); // output to the console
    #$this->setItem('logging', 'silent');  // do not output anything, be careful with this logging mode
    #$this->setItem('logging', 'tam.log'); // the path to a writeable logfile


    # the newline character for the logfile (does not need to be changed in most cases)
    $this->setItem('newline', (PHP_OS == 'WINNT') ? "
" : "
");
  }
  
  /* gets an item from the config
   *
   * @param  $item   string  the item to get
   * @return         mixed   the value of the item
   */
  public function getItem($item = 'all')
  {
    if ( $item == 'all' )
    {
      return $this->config;
    }
    elseif ( isset($this->config[$item]) )
    {
      return $this->config[$item];
    }
    return false;
  }
  
  /* sets an item into the config
   *
   * @param  $item   string  the item to set
   * @param  $value  mixed   the value to store into the item
   */
  public function setItem($item, $value)
  {
    $this->config[$item] = $value;
  }
}


Jetzt kommen neue Fehler :slight_smile: … aber obiger Fehler ist schon mal weg.