FritzBox mit SOAP auslesen und steuern

Gerne :slight_smile:

Deine Frage erklärt sich von selbst, wenn du mal die „//“ vor dem print_r($result) entfernst :wink:

GetInfo gibt ein Array zurück mit den Werten die dann per print ausgegeben werden. Einer davon ist der „NewUpTime“ Wert :wink:

Grüße,
Chris

Oder einfach in den ganzen XMLs der Box nachsehen. Dort stehen alle Befehle und Parameter.
Siehe dazu die ersten Posts.
Michael

hat sich erledigt

Hallo Zusammen,
wie kann man die „Wake on LAN“ Funktion der FritzBox aufrufen?
Habe das Thema bereits durchsucht, wurde jedoch leider nicht fündig.

Oder kann man per IPS direkt eine „Wake on LAN“ Message verschicken?
Das wäre mir natürlich noch lieber, da die IP-Adresse des Zielrechners bekannt und fest ist.

Du brauchst dafür aber die MAC.
Über die FB habe ich da was fertiges (Beta).
Michael

Sieht wild aus, aber funktioniert.
Damit habe ich bis jetzt alles wach bekommen :smiley:


function WakeOnLan($mac_address){
   $addr = "192.168.10.14";
	$cidr = "24";
	$port = "9";

	// Prepare magic packet: part 1/3 (defined constant)
 	$buf="";
 	for($a = 0; $a < 6; $a++) $buf .= chr(255); // the defined constant as represented in hexadecimal: FF FF FF FF FF FF (i.e., 6 bytes of hexadecimal FF)
 	//Check whether $mac_address is valid
 		$mac_address = strtoupper($mac_address);
 		$mac_address = str_replace(":", "-", $mac_address);

	 if((!preg_match("/([A-F0-9]{2}[-]){5}([0-9A-F]){2}/", $mac_address)) || (strlen($mac_address) != 17)){
 		$error = "Input error: Pattern of MAC-address is not \"xx-xx-xx-xx-xx-xx\" (x = digit or letter).<br>
";
 		return $error; // false
 		}
 	else{
 		// Prepare magic packet: part 2/3 (16 times MAC-address)
 		$addr_byte = explode('-', $mac_address); // Split MAC-address into an array of (six) bytes
 		$hw_addr="";
 		for($a = 0; $a < 6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a])); // Convert MAC-address from bytes to hexadecimal to decimal
 			$hw_addr_string = "";

		for($a = 0; $a < 16; $a++) $hw_addr_string .= $hw_addr;
 			$buf .= $hw_addr_string;
 		}

	 // Resolve broadcast address
 	if (filter_var ($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){ // same as (but easier than):  preg_match("/\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b/",$addr)
 		// $addr has an IP-adres format
 		}
 	else{
 		// Whitespaces confuse name lookups
 		$addr=trim($addr);
 		// If you pass to gethostbyname() an:
 		//	unresolvable domainname, gethostbyname() returns the domainname (rather than 'false')
 		//	IP address, gethostbyname() returns that IP address.
 		if(gethostbyname($addr) == $addr){
 			// $addr is NOT a resolvable domainname
 			$error = "Input error: host name of broadcast address is unresolvable.<br>
";
 			return $error; // false
 			}
 		else{
 			// $addr IS a resolvable domainname
 			$addr = gethostbyname($addr);
 			}
 		}

	 // Store input value for cookie
 	$resolved_addr = $addr;
 	// If $cidr is set, replace $addr for its broadcast address
 	if($cidr != ""){
 		// Check whether $cidr is valid
 		if((!ctype_digit($cidr)) || ($cidr < 0) || ($cidr > 32)){
 			$error = "Input error: CIDR subnet mask is not a number within the range of 0 till 32.<br>
";
 			return $error; // false
 			}

		 // Convert $cidr from one decimal to one inverted binary array
 		$inverted_binary_cidr = "";
 		for($a = 0; $a < $cidr; $a++) $inverted_binary_cidr .= "0"; // Build $inverted_binary_cidr by $cidr * zeros (this is the mask)
 			$inverted_binary_cidr = $inverted_binary_cidr.substr("11111111111111111111111111111111", 0, 32-strlen($inverted_binary_cidr)); // Invert the mask (by postfixing ones to $inverted_binary_cidr untill 32 bits are filled/ complete)
 			$inverted_binary_cidr_array = str_split($inverted_binary_cidr); // Convert $inverted_binary_cidr to an array of bits

		 // Convert IP address from four decimals to one binary array
 		$addr_byte = explode('.', $addr); // Split IP address into an array of (four) decimals
 		$binary_addr = "";
 		for($a = 0; $a < 4; $a++){
 			$pre = substr("00000000", 0, 8-strlen(decbin($addr_byte[$a]))); // Prefix zeros
 			$post = decbin($addr_byte[$a]); // Postfix binary decimal
 			$binary_addr .= $pre.$post;
 			}

		 $binary_addr_array = str_split($binary_addr); // Convert $binary_addr to an array of bits
 		// Perform a bitwise OR operation on arrays ($binary_addr_array & $inverted_binary_cidr_array)
 		$binary_broadcast_addr_array = "";
 		for($a = 0; $a < 32; $a++) $binary_broadcast_addr_array[$a] = ($binary_addr_array[$a] | $inverted_binary_cidr_array[$a]); // binary array of 32 bit variables ('|' = logical operator 'or')
 			$binary_broadcast_addr = chunk_split(implode("", $binary_broadcast_addr_array),8,"."); // build binary address of four bundles of 8 bits (= 1 byte)
 			$binary_broadcast_addr = substr($binary_broadcast_addr,0,strlen($binary_broadcast_addr)-1); // chop off last dot ('.')
 			$binary_broadcast_addr_array = explode(".", $binary_broadcast_addr); // binary array of 4 byte variables
 			$broadcast_addr_array = "";

		for($a = 0; $a < 4; $a++) $broadcast_addr_array[$a] = bindec($binary_broadcast_addr_array[$a]); // decimal array of 4 byte variables
 			$addr = implode(".", $broadcast_addr_array); // broadcast address
 			}

	 // Check whether $port is valid
 	if((!ctype_digit($port)) || ($port < 0) || ($port > 65536)){
 		$error = "Input error: Port is not a number within the range of 0 till 65536.<br>
";
 		return $error; // false
 		}

	 // Check whether UDP is supported
 	if(!array_search('udp', stream_get_transports())){
 		$error = "No magic packet can been sent, since UDP is unsupported (not a registered socket transport).<br>
";
 		return $error; // false
 		}

	 if(function_exists('fsockopen')){
 		// Try fsockopen function - To do: handle error 'Permission denied'
 		$socket=fsockopen("udp://" . $addr, $port, $errno, $errstr);
 		if($socket){
 			$socket_data = fwrite($socket, $buf);
 			if($socket_data){
 				$function = "fwrite";
 				$sent_fsockopen = "OK (fsockopen)" ;
 				fclose($socket);
 				unset($socket);
 				return $sent_fsockopen; // true
 				}
 			else{
 				echo "Using 'fwrite()' failed, due to error: '".$errstr."' (".$errno.")<br>
";
 				fclose($socket);
 				unset($socket);
 				}
 			}
 		else{
 			echo "Using 'fsockopen()' failed, due to denied permission.<br>
";
 			unset($socket);
 			}
 		}

	 // Try socket_create function
 	if(function_exists('socket_create')){
 		$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // create socket based on IPv4, datagram and UDP
 		if($socket){
 			$level = SOL_SOCKET; // to enable manipulation of options at the socket level (you may have to change this to 1)
 			$optname = SO_BROADCAST; // to enable permission to transmit broadcast datagrams on the socket (you may have to change this to 6)
 			$optval = true;
 			$opt_returnvalue = socket_set_option($socket, $level, $optname, $optval);

			 if($opt_returnvalue < 0){
 				$error = "Using 'socket_set_option()' failed, due to error: '".socket_strerror($opt_returnvalue)."'<br>
";
 				return $error; // false
 				}

			 $flags = 0;
 			// To do: handle error 'Operation not permitted'
 			$socket_data = socket_sendto($socket, $buf, strlen($buf), $flags, $addr, $port);
 			if($socket_data){
 				$function = "socket_sendto";
 				$socket_create = "OK (create)";
 				socket_close($socket);
 				unset($socket);
 				return $socket_create; // true
 				}
 			else{
 				$error = "Using 'socket_sendto()' failed, due to error: '".socket_strerror(socket_last_error($socket))."' (".socket_last_error($socket).")<br>
";
 				socket_close($socket);
 				unset($socket);
 				return $error; // false
 				}
 			}
 		else{
 			$error = "Using 'socket_create()' failed, due to error: '".socket_strerror(socket_last_error($socket))."' (".socket_last_error($socket).")<br>
";
 			return $error; // false
 			}
 		}
 	else{
 		$error = "No magic packet has been sent, since no functions are available to transmit it.<br>
";
 		return $error; // false
 		}
 	}

Vielen Dank!

@Nall chan

Ich versuche gerade die Liste der Netzwerkgeräte aus meiner Box zu bekommen.
Allerdings erhalte ich immer nur 16 Einträge zurück, und nicht an die 30 wie es auch Geräte im Netzwerk sind

Ich bekomme auch nur 16 Geräte allerdings mit dem Script aus dem betreffenden Post auch nur in folgender Ausgabe:

Anzahl der Hosts: 16
Index: 0
bool(false)
-------------
Index: 1
bool(false)
-------------
etc.

Ich habe mir um Platz zu sparen Popups für diverse Statusanzeigen erstellt, welche über einen Button getriggert werden wie z.B.:

Das Selbe hätte ich nun noch gern als Liste der verbundenen Geräte. Ist es möglich eine Liste mit IP/Namen der verbundenen Geräte auszulesen ?

Gruß

André

Abend!

Wie im Thread schon mal angemerkt wurde, gehen bei der aktuellen Fritzbox Firmware nur 16 Hosts Einträge. Ist ein Limit von Fritz. Erst mit einer der letzten Labor-Firmware-Versionen wurde dieses Limit aufgehoben, damit bekomme ich alle Host-Einträge (über 50) ausgelesen und angezeigt.

Wer also alle Geräte im LAN/WLAN sehen möchte, muss die aktuelle Labor-Firmware einspielen. Dies geht aber nur mit einer aktuellen Fritzbox.

Ich hoffe, dass das auch irgendwann/bald in die „normale“ Firmware einfließt und dann für alle verfügbar ist.

Grüße,
Chris

Ja, so etwas habe ich schon fertig. Ist allerdings etwas grösser das Projekt und nich nicht fertig. Bin aber endlich wieder am Ball.

Wenn du die Chance hast auf die Labor FW der Fritte zu gehen, hast du schon mal das 16er Limit erschlagen.

Michael

OK . Klingt gut. Aber wie finde ich die IP’s???

Gruß André

Du musst diese Daten einzeln per ‚GetGenericHostEntry‘ holen.

Ist etwas aus dem Zusammenhang gerissen, da es aus meinem aktuellen Projekt ist, aber vielleicht hilft es dir :slight_smile:
Ist so aber kein P & P.
Da hier viele Funktionen und Konstanten verwendet werden, welche globaler Bestandteil sind und hier nun fehlen.
Aber Vorsicht, die FB verkraftet nur eine gewisse Anzahl von (quasi) Gleichzeitigen Anfragen.
Gerade wenn du viele Scripte hast, welche die FB per SOAP quälen.
Ich habe dafür extra eine Art Warteschleife gebaut; die fehlt hier.


$service['uri'] = 'urn:dslforum-org:service:Hosts:1';
$service['location'] ='http://'.FB_HOST.':'.FB_PORT.'/upnp/control/hosts';
$action="GetHostNumberOfEntries";
$HostNumber =  FB_SoapAction($service,$action);
if ($HostNumber === false) return;
ini_set('max_execution_time', (int)ini_get('max_execution_time')+($HostNumber*5));
// $HostNumber = Anzahl aller Geräte
$action="GetGenericHostEntry";
for ($i=0;$i< $HostNumber; $i++)
{
$param = new SoapParam($i,"NewIndex");
$result =  FB_SoapAction($service,$action,$param);
if ($result === false)
{
IPS_Sleep(20);
$result =  FB_SoapAction($service,$action,$param);
}
if ($result === false)
{
if ($_IPS['SENDER'] == "WebFront") echo "Error READ of ".$service['location']."->".$action.PHP_EOL;
else IPS_LogMessage("FritzBox","Error READ of ".$service['location']."->".$action);
return;
}
if ($result["NewMACAddress"] == '') continue;
$ident = strtoupper(FB_GetIdent($result["NewMACAddress"]));
$id = @IPS_GetObjectIDByIdent($ident,$parent);
if ($id ==0)
{
$id = FB_GetOrCreateVariable($parent,$ident,$result["NewHostName"]." (".$result["NewIPAddress"].")",0,"~Switch");
}
SetValueBoolean($id,(bool)$result["NewActive"]);
}

Michael

Danke :slight_smile:
Schaue mich mir mal näher an :wink:

Gruß André

… so. Hab´s jetzt. Danke für den Hinweis Nall chan.

Mit der neuen Firmware (Labor für FB 7490) bekomme ich jetzt alle Devices und kann diese als aktiv/nicht aktiv filtern.

Anbei das Script, falls es jemand benötigt.Gedacht ist es platzsparend als Popup, welches über einen Button getriggert wird. Also noch die WFC-ID eintragen.

<?

/*//////////////////////////////////////////////////////////////////////////////
Fritzbox Script Netzwerkübersicht                                          @2015
/*//////////////////////////////////////////////////////////////////////////////

//Definitionen//////////////////////////////////////////////////////////////////

$fritzboxIP = "fritz.box"; //falls umbenannt IP eintragen
$fritzboxPort = "49000"; //konstant
$login = ""; //ggf. eintragen
$password = ""; //ggf. eintragen

////////////////////////////////////////////////////////////////////////////////

$client = new SoapClient(
    null,
    array(
        'location'   => "http://".$fritzboxIP.":".$fritzboxPort."/upnp/control/hosts",
        'uri'        => "urn:dslforum-org:service:Hosts:1",
        'noroot'     => True,
        'login'      => $login,
        'password'   => $password
    )
);
print_r($client);

$NumberOfHosts = $client->GetHostNumberOfEntries();

for ($i=0;$i<$NumberOfHosts;$i++)
	{
	$Host = $client->GetGenericHostEntry(new SoapParam($i,'NewIndex'));
	print_r($Host);
	$Hosts[] = $Host;
	}

/*Muster des Array://///////////////////////////////////////////////////////////
    [0] => Array
				(
				    [NewIPAddress] => XXX.XXX.XXX.XXX
				    [NewAddressSource] => DHCP
				    [NewLeaseTimeRemaining] => ......
				    [NewMACAddress] => XX:XX:XX:XX:XX:XX
				    [NewInterfaceType] => 802.11
				    [NewActive] => 1
				    [NewHostName] => .......
				)

Struktur des Popup / Tabelle:

--------------------------------------------------------------------------------
|Netzwerkübersicht: [Anzahl]Aktive Geräte                                      |
--------------------------------------------------------------------------------
|  Nr  |  Interface  |        Name        |    IPAddress    |    MACAddress    |
--------------------------------------------------------------------------------
|      |             |                    |                 |                  |
--------------------------------------------------------------------------------
/*//////////////////////////////////////////////////////////////////////////////

$table = '<tr><th>Nr.</th><th>Interface</th><th>Name</th><th>IPAddress</th><th>MACAddress</th></tr>';

for ($i=0;$i<$NumberOfHosts;$i++)
	{
	if($Hosts[$i]['NewActive'] == 1)
		{
		$NewInterfaceType = $Hosts[$i]['NewInterfaceType'];
		$NewHostName      = $Hosts[$i]['NewHostName'];
		$NewIPAddress     = $Hosts[$i]['NewIPAddress'];
		$NewMACAddress    = $Hosts[$i]['NewMACAddress'];

		$ActiveDevices[]  = $Hosts[$i]['NewHostName'];


		$table .= '<tr><td>'.$i.'</td><td>'.$NewInterfaceType.'</td><td>'.$NewHostName.'</td><td>'.$NewIPAddress.'</td><td>'.$NewMACAddress.'</td></tr>';
		}
	}
//print_r($table);
print_r($ActiveDevices);

$WFC_Content = '<!DOCTYPE html>
<html>
<head>
<style>
table {
    width:80%;
    height:80%;
	 margin-left: auto;
	 margin-right: auto;
	 margin-top: auto;
	 margin-bottom: auto;
}
table, th, td {
    border: 1px solid black;
    border-collapse: collapse;
}
th, td {
    padding: 5px;
    text-align: left;
    width:auto;
}
table#t01 tr:nth-child(even) {
    background-color: #eee;
	 color: black;
}
table#t01 tr:nth-child(odd) {
	 background-color:#fff;
	 color: black;
}
table#t01 th	{
    background-color: grey;
    color: white;
}
</style>
</head>
<body>

<table id="t01">
'.$table.'
</table>

</body>
</html>';

$WFC_Header = "Netzwerkübersicht: ".count($ActiveDevices)." aktive Geräte";

$WFC_ID = 47627 /*[WebFront]*/;//WFC-ID eintragen !!!

WFC_SendPopup($WFC_ID, $WFC_Header, $WFC_Content);

?>

Gruß André

Hallo zusammen,

ich möchte wetten es wurde schon irgendwo beschrieben, aber ich sehe nach 26 Seiten den Wald vor Bäumen nicht mehr.

Ich habe ein Skript, welches mir die aktuelle Anruferliste anzeigt. Da ich selber nicht der profi Programmierer bin sind die skripte nur kopiert…Danke an euch!!!:slight_smile:

Ich würde jetzt noch gern die Anrufliste aus webfront löschen können.

Eine weitere Frage ist für euch Profis wahrscheinlich banal…
Ich lese den WLAN Gastzugang so aus:


$client1 = new SoapClient(
    null,
    array(
        'location'   => "http://".$fritzbox_ip.":49000/upnp/control/wlanconfig3",
        'uri'        => "urn:dslforum-org:service:WLANConfiguration:3",
        'noroot'     => True,
        'login'      => $fritzbox_Username,
        'password'   => $fritzbox_Password
    )
);

echo $client1->GetInfo()['NewEnable'];


Wie kann ich jetzt das Ergebnis in eine boolsche Variable bringen??
so gehts ja nit (da soap variable:


if ($client1['NewEnable'] == "0")
{
SetValueBoolean(28753 /*[Funktionen\Allgemein\System Status\Fritzbox SOAP\Gastzugang]*/, $client1);
}

Kann mir da jemand auf die Sprünge helfen??:smiley:

Nimm mal die IF Abfrage raus und ändere das SetValueBoolean hinter dem Komma so:
boolval($client[‚NewEnable‘])

Anruf Liste löschen habe ich noch nie ausprobiert. Kann aber gerade nicht nachsehen (Win10 Upgrades laufen noch…)
Michael

Hallo und danke für die schnelle Antwort.

Habe es so gemacht:



$client1 = new SoapClient(
    null,
    array(
        'location'   => "http://".$fritzbox_ip.":49000/upnp/control/wlanconfig3",
        'uri'        => "urn:dslforum-org:service:WLANConfiguration:3",
		  'noroot'     => True,
        'login'      => $fritzbox_Username,
        'password'   => $fritzbox_Password
    )
);

echo $client1->GetInfo()['NewEnable'];

SetValueBoolean(28753 /*[Funktionen\Allgemein\System Status\Fritzbox SOAP\Gastzugang]*/, boolval($client1['NewEnable']));


Leider ohne Erfolg:

Fatal error: Call to undefined function boolval() in H:\IP-Symcon\scripts\50182.ips.php on line 20
IPS-Err-PHP 2015-08-18 20:37:37.321 Error: Call to undefined function boolval() Error in Script H:\IP-Symcon\scripts\50182.ips.php on Line 20 134 in scripts\IPSLibrary\app\core\IPSLogger\IPSLogger.inc.php (call IPSLogger_Out) 33 in scripts\IPSLibrary\app\core\IPSLogger\IPSLogger_PhpErrorHandler.inc.php (call IPSLogger_Err) 121 in scripts\IPSLibrary\app\core\IPSLogger\IPSLogger_PhpErrorHandler.inc.php (call IPSLogger_PhpErrorHandler) in IPSLogger_PhpFatalErrorHandler
Abort Processing during Fatal-Error: Call to undefined function boolval()
Error in Script H:\IP-Symcon\scripts\50182.ips.php on Line 20

Sorry mein Fehler… hatte die Variable anders im Kopf.
Am Handy gerade schlecht zu tippen; aber so in 1h gibt es dann die Auflösung :wink:
Michael

So klappts:

SetValueBoolean(28753 /*[Funktionen\Allgemein\System Status\Fritzbox SOAP\Gastzugang]*/, (bool)$client1->GetInfo()['NewEnable']);

Grüße,
Chris

Danke fürs einspringen…