fritzconnection documentation

fritzconnection is a Python library to communicate with the AVM Fritz!Box by the TR-064 protocol. This allows to read status-informations from the box and to read and change configuration settings and state.

_images/fritzconnection-360x76.png

The available services are depending on the Fritz!Box model and the according system software. fritzconnection can list and access all available services and actions of a given box. Using fritzconnection is as easy as:

from fritzconnection import FritzConnection

fc = FritzConnection(address='192.168.178.1')
fc.reconnect()  # get a new external ip from the provider
print(fc)  # print router model informations

For more informations refer to Installation and Introduction.

Note: fritzconnection is neither related to nor supported by AVM. Also AVM reserves the right to add, modify or remove features of their products at any time without notice.

Installation

The fritzconnection package is available on PyPi and installable by pip

$ pip install fritzconnection

This installation will also install the required package requests. If this does not work (for whatever reason) requests can also installed by pip:

$ pip install requests

It is not necessary, but good practice, to do the installation in a virtual environment – either by means of venv or conda (comes with miniconda or anaconda).

fritzconnection runs with Python 3.6 or newer (older versions are not supported).

Introduction

Technically the communication with the Fritz!Box works by UPnP using SCPD and SOAP for information transfer which is based on the TR-064 protocol. The TR-064 protocol uses the concepts of services and actions. A service is a collection of actions for a given topic like WLAN-connections, registered hosts, phone calls, home-automation tasks and so on. The documentation about all services and actions is available from the vendor AVM (see Further Reading).

FritzConnection manages the inspection of a given Fritz!Box and can access all available services and corresponding actions. For some services it is required to provide the user-password for the box. The set of available services and actions may vary by router models.

The installation of fritzconnection (using pip) will also install a command line tool for the Fritz!Box api-inspection. The next sections will give an introduction to this command line tool and how to write modules on top of fritzconnection.

Internal defaults

To access the router in a local network, fritzconnection use some default values:

FRITZ_IP_ADDRESS = '169.254.1.1'
FRITZ_TCP_PORT = 49000
FRITZ_USERNAME = 'dslf-config'

The ip-adress is a fallback-value common to every fritzbox-router, regardless of the individual configuration. In case of more than a single router in the local network (i.e. multiple Fritz!Boxes building a mesh or connected by LAN building multiple WLAN access-points) the option -i (for the command line) or the keyword-parameter address (module usage) is required to address the router, otherwise it is not defined which one of the devices will respond.

Command line usage

Installing fritzconnection by pip will also install the command line tool fritzconnection to inspect the Fritz!Box-API. With the option -h this will show a help menu:

$ fritzconnection -h

FritzConnection v1.0
usage: fritzconnection [-h] [-i [ADDRESS]] [--port [PORT]] [-u [USERNAME]]
                       [-p [PASSWORD]] [-r] [-s] [-S SERVICEACTIONS]
                       [-a SERVICEARGUMENTS]
                       [-A ACTIONARGUMENTS ACTIONARGUMENTS]

Fritz!Box API Inspection:

optional arguments:
  -h, --help            show this help message and exit
  -i [ADDRESS], --ip-address [ADDRESS]
                        Specify ip-address of the FritzBox to connect
                        to.Default: 169.254.1.1
  --port [PORT]         Port of the FritzBox to connect to. Default: 49000
  -u [USERNAME], --username [USERNAME]
                        Fritzbox authentication username
  -p [PASSWORD], --password [PASSWORD]
                        Fritzbox authentication password
  -r, --reconnect       Reconnect and get a new ip
  -s, --services        List all available services
  -S SERVICEACTIONS, --serviceactions SERVICEACTIONS
                        List actions for the given service: <service>
  -a SERVICEARGUMENTS, --servicearguments SERVICEARGUMENTS
                        List arguments for the actions of a specified service:
                        <service>.
  -A ACTIONARGUMENTS ACTIONARGUMENTS, --actionarguments ACTIONARGUMENTS ACTIONARGUMENTS
                        List arguments for the given action of a specified
                        service: <service> <action>. Lists also direction and
                        data type of the arguments.

With the option -s all services available without a password are listed. In case an error gets reported like:

$ fritzconnection -s

FritzConnection v1.0
Unable to login into device to get configuration information.

an additional parameter for the router ip must be provided (newer router models use 192.168.178.1 as factory setting) by using the -i option:

$ fritzconnection -s -i 192.168.178.1

FritzConnection v1.0
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: None
Servicenames:
                    any1
                    WANCommonIFC1
                    WANDSLLinkC1
                    WANIPConn1
                    WANIPv6Firewall1

With a given password the OS-version and more services are listed. The number of services can vary depending on the router model:

$ fritzconnection -s -i 192.168.178.1 -p <password>

FritzConnection v1.0
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12
Servicenames:
                    any1
                    WANCommonIFC1
                    WANDSLLinkC1
                    WANIPConn1
                    WANIPv6Firewall1
                    DeviceInfo1
                    DeviceConfig1
                    Layer3Forwarding1
                    ...
                    X_AVM-DE_OnTel1
                    X_AVM-DE_Dect1
                    ...
                    WLANConfiguration1
                    WLANConfiguration2
                    WLANConfiguration3
                    ...
                    WANPPPConnection1
                    WANIPConnection1

Services starting with “X_AVM” are not covered by the TR-064 standard but are AVM-specific extensions.

All service-names are ending with a numeric value. In case a service is listed more than once the numeric value allows to select a specific one. Most prominent example is the WLANConfiguration service for accessing the 2.4 GHz and 5 GHz bands as well as the guest-network (given that the router-model provides these services).

Services and actions

Every service has a set of corresponding actions. The actions are listed by the flag -S with the servicename as parameter:

$ fritzconnection -i 192.168.178.1 -p <password> -S WANIPConnection1

FritzConnection v1.0
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12

Servicename:        WANIPConnection1
Actionnames:
                    GetInfo
                    GetConnectionTypeInfo
                    SetConnectionType
                    GetStatusInfo
                    GetNATRSIPStatus
                    SetConnectionTrigger
                    ForceTermination
                    RequestConnection
                    GetGenericPortMappingEntry
                    GetSpecificPortMappingEntry
                    AddPortMapping
                    DeletePortMapping
                    GetExternalIPAddress
                    X_GetDNSServers
                    GetPortMappingNumberOfEntries
                    SetRouteProtocolRx
                    SetIdleDisconnectTime

A list of all available actions with their corresponding arguments is reported by the flag -a with the servicename as parameter:

$ fritzconnection -i 192.168.178.1 -p <password> -a WANIPConnection1

This can return a lengthy output. So the arguments for a single action of a given service can also get listed with the option -A and the service- and actionname as arguments. For example the output for the service WANIPConnection1 and the action GetInfo will be:

$ fritzconnection -i 192.168.178.1 -p <password> -A WANIPConnection1 GetInfo

FritzConnection v1.0
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12

Service:            WANIPConnection1
Action:             GetInfo
Parameters:

    Name                          direction     data type

    NewEnable                        out ->     boolean
    NewConnectionStatus              out ->     string
    NewPossibleConnectionTypes       out ->     string
    NewConnectionType                out ->     string
    NewName                          out ->     string
    NewUptime                        out ->     ui4
    NewLastConnectionError           out ->     string
    NewRSIPAvailable                 out ->     boolean
    NewNATEnabled                    out ->     boolean
    NewExternalIPAddress             out ->     string
    NewDNSServers                    out ->     string
    NewMACAddress                    out ->     string
    NewConnectionTrigger             out ->     string
    NewRouteProtocolRx               out ->     string
    NewDNSEnabled                    out ->     boolean
    NewDNSOverrideAllowed            out ->     boolean

For every action all arguments are listed with their name, direction and type. (Some arguments for other services may have the direction “in” for sending data to the router.)

Module usage

FritzConnection works by calling actions on services and can send and receive action-arguments. A simple example is to reconnect the router with the provider to get a new external ip:

from fritzconnection import FritzConnection

fc = FritzConnection()  #1
fc.call_action('WANIPConnection1', 'ForceTermination')

At first an instance of FritzConnection must be created (#1). There can be a short delay doing this because fritzconnection has to wait for the response of the router to inspect the router-specific api.

The method call_action takes two required arguments: the service- and the action-name as strings. In case that a service or action is unknown (because of a typo or incompatible router model) fritzconnection will raise a FritzServiceError. If the service is known, but not the action, then a FritzActionError gets raised.

Note

Once a FritzConnection instance has been created, it can be reused for all future call_action calls. Because instantiation is expensive (doing a lot of i/o for API inspection) this can increase performance significantly.

Let’s look at another example using an address (192.168.178.1) and calling an action (GetInfo) on a service (WLANConfiguration) that requires a password:

from fritzconnection import FritzConnection

fc = FritzConnection(address='192.168.178.1', password='the_password')
state = fc.call_action('WLANConfiguration1', 'GetInfo')

Calling the service WLANConfiguration1 without giving a password to FritzConnection will raise a FritzServiceError. Providing a wrong password will raise a FritzConnectionError.

In case that the servicename is given without a numeric extension (i.e ‘1’) fritzconnection adds the extension ‘1’ by default. So WLANConfiguration becomes WLANConfiguration1. The extension is required if there are multiple services with the same name. For backward compatibility servicenames like WLANConfiguration:1 are also accepted.

The result of calling the call_action method is always a dictionary with the argument names as keys. The values are the output-arguments from the Fritz!Box. In the above example ‘state’ will be something like this:

{'NewAllowedCharsPSK': '0123456789ABCDEFabcdef',
 'NewAllowedCharsSSID': '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz '
                        '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~',
 'NewBSSID': '98:9B:CB:2B:93:B3',
 'NewBasicAuthenticationMode': 'None',
 'NewBasicEncryptionModes': 'None',
 'NewBeaconType': '11i',
 'NewChannel': 6,
 'NewEnable': True,
 'NewMACAddressControlEnabled': False,
 'NewMaxBitRate': 'Auto',
 'NewMaxCharsPSK': 64,
 'NewMaxCharsSSID': 32,
 'NewMinCharsPSK': 64,
 'NewMinCharsSSID': 1,
 'NewSSID': 'the WLAN name',
 'NewStandard': 'n',
 'NewStatus': 'Up'}

These informations are showing a lot of details. In this example the network is up and operating on channel 6.

To activate or deactivate a network, the action SetEnable can get called. Inspection gives informations about the required arguments:

$ $ fritzconnection -i 192.168.178.1 -p <password> -A WLANConfiguration1 SetEnable

FritzConnection v1.0
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12

Service:            WLANConfiguration1
Action:             SetEnable
Parameters:

    Name                          direction     data type

    NewEnable                     -> in         boolean

Here just one argument is listed for the ‘in’-direction. That means that this argument has to be send to the router. FritzConnection sends arguments by giving them as keyword-parameters to the call_action-method:

from fritzconnection import FritzConnection

fc = FritzConnection(address='192.168.178.1', password='the_password')
fc.call_action('WLANConfiguration1', 'SetEnable', NewEnable=0)

This call will deactivate the network. As there are no arguments listed for the ‘out’-direction, call_action will return an empty dictionary without any out-argument keys (keep in mind: don’t deactivate a wireless network by not having a backup cable connection).

The call_action method also accepts a keyword-only argument with the name arguments that must be a dictionary with all input-parameters as key-value pairs. (new since 1.0)

This is convenient for calls with multiple arguments for the in-direction, or for argument names not suitable as keyword parameters (like having a dash in the name) :

arguments = {'NewEnable': 0}
fc.call_action('WLANConfiguration1', 'SetEnable', arguments=arguments)

Example: Writing a module

Let’s write a simple module using fritzconnection to report the WLAN status of a router:

from itertools import count

from fritzconnection import FritzConnection
from fritzconnection.core.exceptions import FritzServiceError


def get_wlan_status(fc):
    status = []
    action = 'GetInfo'
    for n in count(1):
        service = f'WLANConfiguration{n}'
        try:
            result = fc.call_action(service, action)
        except FritzServiceError:
            break
        status.append((service, result))
    return status


def get_compact_wlan_status(fc):
    keys = ('NewSSID', 'NewChannel', 'NewStatus')
    return [
        (service, {key[3:]: status[key] for key in keys})
        for service, status in get_wlan_status(fc)
    ]


def main(address, password):
    fc = FritzConnection(address=address, password=password)
    for service, status in get_compact_wlan_status(fc):
        print(f'{service}: {status}')


if __name__ == '__main__':
    main(address='192.168.178.1', password='the_password')

Depending on the settings this will give an output like this:

WLANConfiguration1: {'SSID': 'the_wlan_name', 'Channel': 6, 'Status': 'Up'}
WLANConfiguration2: {'SSID': 'the_wlan_name', 'Channel': 100, 'Status': 'Up'}
WLANConfiguration3: {'SSID': 'FRITZ!Box Gastzugang', 'Channel': 6, 'Status': 'Disabled'}

The modules in the fritzconnection library (modules in the lib-folder) can be used as code-examples of how to use fritzconnection.

Exceptions

FritzConnection can raise several exceptions. For example using a service not provided by a specific router model will raise a FritzServiceError. This and all other errors are defined in fritzconnection.core.exceptions and can get imported from this module (i.e. the FritzServiceError):

from fritzconnection.core.exceptions import FritzServiceError

Exception Hierarchy:

FritzConnectionException
                |
                |--> ActionError --> FritzActionError
                |--> ServiceError --> FritzServiceError
                |
                |--> FritzArgumentError
                |       |
                |       |--> FritzArgumentValueError
                |               |
                |               |--> FritzArgumentStringToShortError
                |               |--> FritzArgumentStringToLongError
                |               |--> FritzArgumentCharacterError
                |
                |--> FritzInternalError
                |       |
                |       |--> FritzActionFailedError
                |       |--> FritzOutOfMemoryError
                |
                |--> FritzSecurityError
                |
                |-->|--> FritzLookUpError
                |   |
KeyError -------+-->|
                |
                |
                |-->|--> FritzArrayIndexError
                    |
IndexError -------->|

All exceptions are inherited from FritzConnectionException. FritzServiceError and FritzActionError are superseding the older ServiceError and ActionError exceptions, that are still existing for backward compatibility. These exceptions are raised by calling unknown services and actions. All other exceptions are raised according to errors reported from the router. FritzLookUpError and FritzArrayIndexError are conceptually the same as a Python KeyError or IndexError. Because of this they are also inherited from these Exceptions.

Library Modules

The library is a package with modules on top of FritzConnection to address specific tasks. They can be used as examples on how to use FritzConnection and to write more specialised modules.

Performance considerations:

Creating a FritzConnection instance will inspect the Fritz!Box API to get informations about all availabe services and corresponding actions. As this is i/o based it’s generally slow. However this has to be done for initialisation. But once an instance is created, it can be reused for all tasks. Creating a single instance for an application may be sufficient for most tasks. For this all library classes can optionally initialised with an existing FritzConnection instance:

from fritzconnection import FritzConnection
from fritzconnection.lib.fritzhomeauto import FritzHomeAutomation
from fritzconnection.lib.fritzwlan import FritzWLAN

fc = FritzConnection(address='192.168.178.1', password=<password>)
print(fc)
# doing more stuff here
# now there is the need to get the number of devices connected by WLAN:
# FritzWLAN can be initialised with an existing FritzConnection instance
fw = FritzWLAN(fc)
print(fw.total_host_number)
# doing some homeautomation:
fh = FritzHomeAutomation(fc)
ain = '11657 0240192'  # assume the AIN of the switch is known
fh.set_switch(ain, on=True)

The next sections will describe the library modules in detail.

FritzCall

Can dial phone numbers and allows access to history of phone calls: incoming, outgoing and missed ones. Usage from the command line:

$ fritzcall -i 192.168.178.1 -p <password> -t in -d 7
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12

List of calls: in

  type   number                           date/time    duration

  ...
  a lot of entries here
  ...

The flag -t indicates the type of calls to get listed: in | out | missed. It -t is not given, all calls are listed (up to 999). The flag -d is the number of days to look back for calls e.g. 1: calls from today and yesterday, 7: calls from the complete last week.

FritzCall provides to dial numbers by the method dial. This method can also invoked by the command line with the flag -c or --call. Note: To make this work it is required to activate the dial-help service of the router first.

$ fritzcall -i 192.168.178.1 -p <password> -c <phonenumber>
dialing number: <phonenumber>
dialing done, please wait for signal.

For using a module here is an example to list all missed calls:

from fritzconnection.lib.fritzcall import FritzCall

fc = FritzCall(address='192.168.178.1', password=<password>)
calls = fc.get_missed_calls()
for call in calls:
    print(call)

Calling back the last missed call is easy:

missed_number = calls[0].Caller  # Caller attribute holds the number
fc.dial(missed_number)  # now dial it

FritzCall API

Module to access lists of recent phone calls: incoming, outgoing and missed ones.

class fritzconnection.lib.fritzcall.FritzCall(fc=None, address=None, port=None, user=None, password=None)

Can dial phone numbers and gives access to lists of recent phone calls: incoming, outgoing and missed ones. All parameters are optional. If given, they have the following meaning: fc is an instance of FritzConnection, address the ip of the Fritz!Box, port the port to connect to, user the username, password the password.

dial(number)

Dials the given number (number must be a string, as phone numbers are allowed to start with leading zeros). This method has no return value, but will raise an error reported from the Fritz!Box on failure. Note: The dial-help of the Fritz!Box must be activated to make this work.

get_calls(calltype=0, update=True, num=None, days=None)

Return a list of Call instances of type calltypes. If calltype is 0 all calls are listet. If update is True, all calls are reread from the router. num maximum number of entries in call list. days number of days to look back for calls e.g. 1: calls from today and yesterday, 7: calls from the complete last week.

get_missed_calls(update=True, num=None, days=None)

Return a list of Call instances of missed calls. If update is True, all calls are reread from the router. num maximum number of entries in call list. days number of days to look back for calls e.g. 1: calls from today and yesterday, 7: calls from the complete last week.

get_out_calls(update=True, num=None, days=None)

Return a list of Call instances of outgoing calls. If update is True, all calls are reread from the router. num maximum number of entries in call list. days number of days to look back for calls e.g. 1: calls from today and yesterday, 7: calls from the complete last week.

get_received_calls(update=True, num=None, days=None)

Return a list of Call instances of received calls. If update is True, all calls are reread from the router. num maximum number of entries in call list. days number of days to look back for calls e.g. 1: calls from today and yesterday, 7: calls from the complete last week.

class fritzconnection.lib.fritzcall.Call

Represents a call with the attributes provided by AVM. Instance attributes are Id, Type, Called, Caller, CallerNumber, CalledNumber, Name, Device, Port, Date, Duration and Count. The spelling represents the original xml-node names. Additionally the following attributes can be accessed by lowercase names: id returning the Id as integer, type returning the Type as integer, date returning the Date as datetime-instance, duration returning the Duration as timedelta-instance.

FritzHomeAutomation

Can access Homeautomation devices to read the current states and set the status of switches. Usage from the command line:

$ fritzhomeauto -i 192.168.178.1 -p <password>
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12
Status of registered home-automation devices:

Device Name             AIN                 Power[W]   t[°C]   switch
FRITZ!DECT 210 #1       '11657 0240192'        0.000    23.5   on

The optional -v flag will give a verbose report about all device informations, including the settings of radiator controls.

The -s flag can set the state of switches. This flag requires two parameters: the device identifier (AIN) and the state to set [on|off]. The following example will switch off the device with the identifier ‘11657 0240192’:

$ fritzhomeauto -i 192.168.178.1 -p <password> -s '11657 0240192' off

Example on how to get informations about the known devices by using a module:

from fritzconnection.lib.fritzhomeauto import FritzHomeAutomation

fha = FritzHomeAutomation(address='192.168.178.1', password=<password>)
info = fha.device_informations())

‘info’ is a list of dictionaries describing the devices:

[{'NewAIN': '11657 0240192',
  'NewDeviceId': 16,
  'NewDeviceName': 'FRITZ!DECT 210 #1',
   ...
  'NewHkrComfortVentilStatus': 'CLOSED',
   ...
  'NewMultimeterEnergy': 75,
  'NewMultimeterIsEnabled': 'ENABLED',
   ...
  'NewSwitchState': 'ON',
  'NewTemperatureCelsius': 265,
  'NewTemperatureIsEnabled': 'ENABLED',
  'NewTemperatureIsValid': 'VALID',
  'NewTemperatureOffset': 0}]

Depending on the device, different informations will get reported. Informations about a specific device can get obtained with the identifier NewAIN. The next example shows how to get the temperature in °C, taken the NewAIN from device_informations() call:

ain = '11657 0240192'
fha.get_device_information_by_identifier(ain)['NewTemperatureCelsius'] * 0.1

It is also easy to toggle a switch (like a FRITZ!DECT 200/210 device):

fha.set_switch(ain, on=True)

This will turn the switch with the given identifier on or off depending whether the parameter ‘on’ is True or False. Usecases can be to set a switch depending on the temperature or daytime.

FritzHomeAutomation API

Modul to access home-automation devices

class fritzconnection.lib.fritzhomeauto.FritzHomeAutomation(fc=None, address=None, port=None, user=None, password=None)

Interface for fritzbox homeauto service. All parameters are optional. If given, they have the following meaning: fc is an instance of FritzConnection, address the ip of the Fritz!Box, port the port to connect to, user the username, password the password.

device_informations()

Returns a list of dictionaries for all known homeauto-devices.

get_device_information_by_identifier(identifier)

Returns a dictionary with all device arguments according to the AVM documentation (x_homeauto) with the given identifier (AIN). Raise an FritzArgumentError on invalid identifier.

get_device_information_by_index(index)

Return a dictionary with all device arguments according to the AVM documentation (x_homeauto) at the given internal index. Raise a FritzArrayIndexError (subclass of IndexError) on invalid index values.

get_info

Return a dictionary with a single key-value pair: ‘NewAllowedCharsAIN’: string with all allowed chars for state variable AIN

modelname

Modelname of the router.

set_switch(identifier, on=True)

Sets a switch state on devices providing a switch state. ‘identifier’ must be the AIN of the device. ‘on’ is a boolean whether the switch should be on (True) or off (False). This method has no return value. Raise a FritzArgumentError on invalid identifier.

FritzHosts

Utility modul for FritzConnection to list the known hosts. For all known hosts the current ip, name, the MAC address and the active-state are reported. Usage from the command line:

$ fritzhosts -i 192.168.178.1 -p <password>

FritzConnection v1.0
FritzHosts for FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12:

List of registered hosts:

  n: ip               name                         mac                 status

  1: 192.168.178.36   DE-20HAR90XXXXX              00:E1:8C:9B:DF:98   -
  2: 192.168.178.33   HUAWEI-P20-Pro-xxxxxxxxxx    B4:CD:27:37:78:E4   -
     ...
 20: 192.168.178.24   fritz.repeater               C6:25:06:83:64:C5   active
 21: 192.168.178.25   fritzbox4020                 C8:0E:14:B8:71:DD   active

Example how to use FritzHost in a module to get the same output:

from fritzconnection.lib.fritzhosts import FritzHosts

fh = FritzHosts(address='192.168.178.1', password='password')
hosts = fh.get_hosts_info()
for index, host in enumerate(hosts, start=1):
    status = 'active' if host['status'] else  '-'
    ip = host['ip'] if host['ip'] else '-'
    mac = host['mac'] if host['mac'] else '-'
    hn = host['name']
    print(f'{index:>3}: {ip:<16} {hn:<28} {mac:<17}   {status}')

FritzHosts API

Modul to list the known hosts. Older versions of FritzOS lists only up to 16 entries. For newer versions this limitation is gone.

class fritzconnection.lib.fritzhosts.FritzHosts(fc=None, address=None, port=None, user=None, password=None)

Class to list all known hosts. All parameters are optional. If given, they have the following meaning: fc is an instance of FritzConnection, address the ip of the Fritz!Box, port the port to connect to, user the username, password the password.

get_generic_host_entry(index)

Returns a dictionary with informations about a device internally registered by the position index. Index-positions are zero-based.

get_hosts_info()

Returns a list of dicts with information about the known hosts. The dict-keys are: ‘ip’, ‘name’, ‘mac’, ‘status’

get_specific_host_entry(mac_address)

Returns a dictionary with informations about a device addressed by the MAC-address.

host_numbers

The number of known hosts.

modelname

The router modelname.

FritzPhonebook

Allows read-only access to the phonebooks stored in the router (a Fritz!Box router can have more than a single phonebook). The command line interface allows inspection of the phonebooks and search for name and numbers. The flag -a will list the content of all phonebooks:

$ fritzphonebook -i 192.168.178.1 -p <password> -a

FritzConnection v1.1
FritzPhonebook for FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12

Content of phonebook: business
good customer                 0123456789
another good customer         0987654321
...
more numbers here
...

With the flags --name and --number like --name "good customer" and --number 0987654321 all phonebooks will get searched for the according entry.

Here is an example to list the entries of all phonebooks by means of a module:

from fritzconnection.lib.fritzphonebook import FritzPhonebook

fp = FritzPhonebook(address='192.168.178.1', password='password')
for phonebook_id in fp.phonebook_ids:
    contacts = fp.get_all_names(phonebook_id)
    for name, numbers in contacts.items():
        print(name, numbers)

FritzPhonebook API

Module for read-only access to the contents of the Fritz!Box phonebooks.

class fritzconnection.lib.fritzphonebook.FritzPhonebook(fc=None, address=None, port=None, user=None, password=None)

Interface to access the Fritz!Box phonebooks. All parameters are optional. If given, they have the following meaning: fc is an instance of FritzConnection, address the ip of the Fritz!Box, port the port to connect to, user the username, password the password.

get_all_names(id)

Get a dictionary with all names and their phone numbers for the phonebook with id.

get_all_numbers(id)

Get a dictionary with all phone numbers and the according names for the phonebook with id.

list_phonebooks

List of integers identifying the phonebooks. This property is defined as phonebook_ids and as list_phonebooks for backward compatibility. The property list_phonebooks is deprecated and may get removed in the future.

lookup_names(id, number)

Look up the names of the contacts with phone number number in the phonebook with id. Will raise a KeyError if the number is unknown.

lookup_numbers(id, name)

Look up the phone numbers of contact name in the phonebook with id. Returns a list of numbers. Will raise a KeyError if the name is unknown.

modelname

The router modelname.

phonebook_ids

List of integers identifying the phonebooks. This property is defined as phonebook_ids and as list_phonebooks for backward compatibility. The property list_phonebooks is deprecated and may get removed in the future.

phonebook_info(id)

Get the name, url and an optional extra id of the phonebook with integer id. Returns a dictionary with the keys name, url and xid.

FritzStatus

Reports informations about the link-status to the service provider. Usage from the command line:

$ fritzstatus -i 192.168.178.1 -p password

FritzConnection v1.0
FritzStatus for FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12:

    is linked           : True
    is connected        : True
    external ip (v4)    : 79.255.xxx.xxx
    external ip (v6)    : 2003:ee:xx:x:x
    uptime              : 190:30:56
    bytes send          : 2097630835
    bytes received      : 2866333236
    max. bit rate       : ('9.9 MBit/s', '50.5 MBit/s')

For periodic calls, an instance of FritzStatus (resp. FritzConnection) should only created once:

import time
from fritzconnection.lib.fritzstatus import FritzStatus

fc = FritzStatus(address='192.168.178.1', password='password')
while True:
    print(fc.str_transmission_rate)
    time.sleep(2)

This will report an output like this:

('992.0 bytes', '23.6 KB')
('0.0 bytes', '0.0 bytes')
('1.3 KB', '25.4 KB')
('3.7 KB', '36.4 KB')
('21.2 KB', '104.6 KB')

FritzStatus API

Modul to read status-informations from an AVM FritzBox.

class fritzconnection.lib.fritzstatus.FritzStatus(fc=None, address=None, port=None, user=None, password=None)

Class for requesting status-informations: up, down, ip, activity (bytes per second send/received). All parameters are optional. If given, they have the following meaning: fc is an instance of FritzConnection, address the ip of the Fritz!Box, the port of the Fritz!Box and the according user and password.

bytes_received

Total number of received bytes.

bytes_sent

Total number of send bytes.

external_ip

The external v4 ip-address.

external_ipv6

The external v6 ip-address.

is_connected

A boolean whether the FritzBox has established an internet-connection.

is_linked

A boolean whether the FritzBox is physically linked to the provider.

max_bit_rate

Tuple with the maximun upstream- and downstream-rate of the given connection. The rate is given in bits/sec.

max_byte_rate

Same as max_bit_rate but rate is given in bytes/sec.

max_linked_bit_rate

Tuple with the maximun upstream- and downstream-rate of the physical link. The rate is given in bits/sec.

modelname

The router modelname.

reconnect()

Makes a reconnection with a new external ip.

str_max_bit_rate

Human readable maximum of the upstream- and downstream-rate in bits/sec, as given by the provider. Value is a tuple, first item is upstream, second item is downstream.

str_max_linked_bit_rate

Human readable maximum of the physical upstream- and downstream-rate in bits/sec. Value is a tuple, first item is upstream, second item is downstream.

str_transmission_rate

Tuple of human readable transmission rate in bytes. First item is upstream, second item downstream.

str_uptime

Uptime in seconds and in human readable format.

transmission_rate

The upstream and downstream values as a tuple in bytes per second. Use this for periodical calling.

uptime

Uptime in seconds.

FritzWLAN

Module for accessing basic WLANConfiguration settings. The command line tool gives an overview of active devices:

$ fritzwlan -i 192.168.178.1 -p <password>
FRITZ!Box 7590 at ip 192.168.178.1
FRITZ!OS: 7.12
Hosts registered at WLANConfiguration1:
WLAN name: the wlan name
channel  : 6
index  active                 mac                ip  signal   speed
    0       1   E2:25:06:83:64:C5    192.168.178.24      51      86

Hosts registered at WLANConfiguration2:
WLAN name: the wlan name
channel  : 36
index  active                 mac                ip  signal   speed
    0       1   A0:99:9B:10:09:81    192.168.178.28      91    1300

Example to get the total number of known WLAN-devices for all WLANConfigurations:

from fritzconnection.lib.fritzwlan import FritzWLAN

fw = FritzWLAN(address='192.168.178.1', password='password')
print(fw.total_host_number)

FritzWLAN API

Module to get informations about WLAN devices.

class fritzconnection.lib.fritzwlan.FritzWLAN(fc=None, address=None, port=None, user=None, password=None, service=1)

Class to list all known wlan devices. All parameters are optional. If given, they have the following meaning: fc is an instance of FritzConnection, address the ip of the Fritz!Box, port the port to connect to, user the username, password the password. The service parameter specifies the configuration in use. Typically this is 1 for 2.4 GHz, 2 for 5 GHz and 3 for a guest network. This can vary depending on the router model and change with future standards.

alternative_channels

Alternative channels (as string)

channel

The WLAN channel in use

channel_infos()

Return a dictionary with the keys NewChannel and NewPossibleChannels indicating the active channel and alternative ones.

get_generic_host_entry(index)

Return a dictionary with informations about the device internally stored at the position ‘index’.

get_hosts_info()

Returns a list of dictionaries with information about the known hosts. The dict-keys are: ‘auth’, ‘mac’, ‘ip’, ‘signal’, ‘speed’

get_specific_host_entry(mac_address)

Return a dictionary with informations about the device with the given ‘mac_address’.

host_number

Number of registered wlan devices for the active WLANConfiguration.

set_channel(number)

Set a new channel. number must be a valid channel number for the active WLAN. (Valid numbers are listed by alternative_channels.)

ssid

The WLAN SSID

total_host_number

Total NewAssociatedDeviceIndexumber of registered wlan devices for all WLANConfigurations.

Structure and API

fritzconnection is structured into subpackages:

fritzconnection --|-- cli
                  |-- core --|-- devices
                  |          |-- exceptions
                  |          |-- fritzconnection
                  |          |-- processor
                  |          |-- soaper
                  |          |-- utils
                  |
                  |-- lib
                  |-- tests

The package cli implements the entry-points for command line usage, the tests are in the tests package and the library modules are in lib. The implementation of fritzconnection itself is structured in the core package.

Public API

The public interface is provided by the FritzConnection class and the exceptions module.

As a shortcut FritzConnection can get imported by:

from fritzconnection import FritzConnection

fritzconnection

Module to communicate with the AVM Fritz!Box.

class fritzconnection.core.fritzconnection.FritzConnection(address='169.254.1.1', port=49000, user=None, password=None, timeout=None)

Main class to set up a connection to the Fritz!Box router. All parameters are optional. address should be the ip of a router, in case that are multiple Fritz!Box routers in a network, the ip must be given. Otherwise it is undefined which router will respond. If user and password are not provided, the environment gets checked for FRITZ_USERNAME and FRITZ_PASSWORD settings and taken from there, if found.

The optional parameter timeout is a floating number in seconds limiting the time waiting for a router response. This is a global setting for the internal communication with the router. In case of a timeout a requests.ConnectTimeout exception gets raised. (New in version 1.1)

call_action(service_name, action_name, *, arguments=None, **kwargs)

Executes the given action of the given service. Both parameters are required. Arguments are optional and can be provided as a dictionary given to ‘arguments’ or as separate keyword parameters. If ‘arguments’ is given additional keyword-parameters as further arguments are ignored. If the service_name does not end with a number (like 1), a 1 gets added by default. If the service_name ends with a colon and a number, the colon gets removed. So i.e. WLANConfiguration expands to WLANConfiguration1 and WLANConfiguration:2 converts to WLANConfiguration2. Invalid service names will raise a ServiceError and invalid action names will raise an ActionError.

modelname

Returns the modelname of the router.

static normalize_name(name)

Returns the normalized service name. E.g. WLANConfiguration and WLANConfiguration:1 will get converted to WLANConfiguration1.

reconnect()

Terminate the connection and reconnects with a new ip.

services

Dictionary of service instances. Keys are the service names.

system_version

Returns system version if known, otherwise None.

exceptions

Exceptions can get imported by:

from fritzconnection.core.exceptions import FritzServiceError
# or:
from fritzconnection.core.exceptions import *

The latter style is often discouraged because of possible namespace-pollution, less clarity about the origin of imported objects and potential name clashings. By using a * import fritzconnection will just import exceptions starting with Fritz in their names.

Exception Hierarchy:

FritzConnectionException
                |
                |--> ActionError --> FritzActionError
                |--> ServiceError --> FritzServiceError
                |
                |--> FritzArgumentError
                |       |
                |       |--> FritzArgumentValueError
                |               |
                |               |--> FritzArgumentStringToShortError
                |               |--> FritzArgumentStringToLongError
                |               |--> FritzArgumentCharacterError
                |
                |--> FritzInternalError
                |       |
                |       |--> FritzActionFailedError
                |       |--> FritzOutOfMemoryError
                |
                |--> FritzSecurityError
                |
                |-->|--> FritzLookUpError
                |   |
KeyError -------+-->|
                |
                |
                |-->|--> FritzArrayIndexError
                    |
IndexError -------->|

Module defining fritzconnection specific exceptions.

exception fritzconnection.core.exceptions.FritzConnectionException

Base Exception for communication errors with the Fritz!Box

exception fritzconnection.core.exceptions.FritzActionError

Exception raised by calling nonexisting actions.

exception fritzconnection.core.exceptions.FritzActionFailedError

Exception raised by the box unable to execute the action properly. Inherits from the more generic FritzInternalError.

exception fritzconnection.core.exceptions.FritzArgumentCharacterError

Exception raised by arguments with invalid characters. Inherits from the more generic FritzArgumentValueError.

exception fritzconnection.core.exceptions.FritzArgumentError

Exception raised by invalid arguments.

exception fritzconnection.core.exceptions.FritzArgumentStringToLongError

Exception raised by arguments with invalid string length for the string being to long. Inherits from the more generic FritzArgumentValueError.

exception fritzconnection.core.exceptions.FritzArgumentStringToShortError

Exception raised by arguments with invalid string length for the string being to short. Inherits from the more generic FritzArgumentValueError.

exception fritzconnection.core.exceptions.FritzArgumentValueError

Exception raised by arguments with invalid values. Inherits from the more generic FritzArgumentError.

exception fritzconnection.core.exceptions.FritzArrayIndexError

Addressing an entry in an internal array by index failed. Inherits from IndexError. So IndexError can also be used for exception handling.

exception fritzconnection.core.exceptions.FritzInternalError

Exception raised by panic in the box.

exception fritzconnection.core.exceptions.FritzLookUpError

Lookup for id or entry in existing internal array failed. Inherits from KeyError. So KeyError can also be used for exception handling.

exception fritzconnection.core.exceptions.FritzOutOfMemoryError

Exception raised by memory shortage of the box. Inherits from the more generic FritzInternalError.

exception fritzconnection.core.exceptions.FritzSecurityError

Authorization error or wrong security context.

exception fritzconnection.core.exceptions.FritzServiceError

Exception raised by calling nonexisting services.

Legathy Exceptions:

exception fritzconnection.core.exceptions.ActionError

Exception raised by calling nonexisting actions. Legathy Exception. Use FritzActionError instead.

exception fritzconnection.core.exceptions.ServiceError

Exception raised by calling nonexisting services. Legathy Exception. Use FritzServiceError instead.

Internal API

The devices-, processor- and soaper-module don’t provide a public interface and are used internally.

devices

Implements the DeviceManager for physical and virtual devices. Every physical device (a router) has a set of virtual subdevices.

class fritzconnection.core.devices.DeviceManager(timeout=None)

Knows all data about the device and the subdevices, including the available services. Takes an optional timeout parameter to limit the time waiting for a router response.

add_description(source)

Adds description data about the devices and the according services. ‘source’ is a string with the xml-data, like the content of an igddesc- or tr64desc-file.

load_service_descriptions(address, port)

Triggers the load of the scpd files of the services, so they known their actions.

modelname

Take the root-device of the first description and return the according modelname. This is the name of the Fritz!Box itself. Will raise an IndexError if the method is called before descriptions are added.

scan()

Scans all available services defined by the description files. Must get called after all xml-descriptions are added.

system_version

Returns a tuple with version, display and buildnumber from the first description providing this informations. Returns None if no system informations are available.

processor

Module to parse and store the device description and the service data provided by xml and the scpd protocol based on xml. Names partly violate PEP8 representing node-names from xml description files.

class fritzconnection.core.processor.Action

Every Action has a name and a list of arguments.

arguments

Returns the action-arguments as a dict. argument-names are the keys and the argument objects are the values. The dictionary gets cached.

class fritzconnection.core.processor.ActionList(storage)

Collection of actions of a service. The Action instances are stored in the Scpd.actions attribute.

class fritzconnection.core.processor.Argument

An argument with name, direction and relatedStateVariable attributes.

class fritzconnection.core.processor.ArgumentList(storage)

Collects the arguments for an action.

class fritzconnection.core.processor.Description(root)

Root class for a given description information as the content from the files igddesc.xml or tr64desc.xml.

services

Returns dictionary with the known services as values and the according service-names as keys.

system_buildnumber

Returns the buildnumber or None. This information is only available by the ‘tr64desc.xml’ file.

system_display

Returns the system display-string or None. This information is only available by the ‘tr64desc.xml’ file.

system_version

Returns the system version of the Fritz!Box as a string like ‘7.10’ or None. This information is only available by the ‘tr64desc.xml’ file.

class fritzconnection.core.processor.Device

Storage for devices attributes and device subnodes. Subnodes are the serviceList and the deviceList. The services provided by a device are collected in services. Subdevices are collected in devices. All instance attributes are public for read only use.

class fritzconnection.core.processor.DeviceList(storage)

Collection of sub-devices of a device. The Device instances are stored in the device.devices attribute of the parent device.

class fritzconnection.core.processor.InstanceAttributeFactory(cls)

Non data descriptor returning instances of ‘cls’ and registering these instances in the ‘_storage’ attribute of the calling instance.

class fritzconnection.core.processor.Scpd(root)

Provides informations about the Service Control Point Definitions for every Service. Every Service has one instance of this class for accessing the description of it’s own actions and the according parameters. Root class for processing the content of an scpd-file.

actions

Returns a dictionary with the actions from the actions-list. The action-names are the keys and the actions themself are the values.

state_variables

Returns a dictionary with the state_variable name as keys and the StateVariable itself as value.

class fritzconnection.core.processor.Service

Class describing a service.

actions

Returns all known actions of this service as a dictionary. Action names are keys, the action objects are the values. Caches the dictionary once retrieved from _scpd.

load_scpd(address, port, timeout=None)

Loads the scpd data

state_variables

Returns all known stateVariables of this service as a dictionary. Names are keys, the stateVariables objects are the values. Caches the dictionary once retrieved from _scpd.

class fritzconnection.core.processor.ServiceList(storage)

Collection of Service instances for a device. The service instances are stored in the device.services attribute.

class fritzconnection.core.processor.ServiceStateTable(storage)

Collection of stateVariables.

class fritzconnection.core.processor.SpecVersion

Specification version from the schema device or service informations.

class fritzconnection.core.processor.StateVariable

Represents a stateVariable with the attributes name, dataType, defaultValue, allowedValueList and allowedValueRange.

class fritzconnection.core.processor.Storage(storage)

Baseclass for classes working with InstanceAttributeFactory.

class fritzconnection.core.processor.SystemVersion

Information about the Fritz!OS version of the Fritz!Box. Information is just provided by the ‘tr64desc.xml’ file.

version

Returns system version as string like ‘7.10’ or None if system version is unknown.

class fritzconnection.core.processor.ValueSequencer(sequence_name)

Data descriptor storing a value (assigned as attribute value) in a given sequence.

fritzconnection.core.processor.process_node(obj, root)

Take an object and a root of nodes. The node.text of nodes with the same name as an instance-attribute of ‘obj’ are set as values for the corresponding instance-attribute. If the attribute is a callable, processing the node gets delegated to the callable (which in turn calls process_node).

fritzconnection.core.processor.processor(cls)

Class decorator to add the functionality of calling ‘process_node’ on invoking an instance as a callable.

soaper

Module handling the SOAP based communication with the router.

class fritzconnection.core.soaper.Soaper(address, port, user, password, timeout=None)

Class making the soap on its own to communicate with the FritzBox. Instead of ham, spam and eggs, it’s hopelessly addicted to soap.

For accessing the Fritz!Box the parameters address for the router ip, port, user and password are required. The optional parameter timeout will limit the time Soaper waits for a router response. (These parameters will get set by FritzConnection,)

execute(service, action_name, arguments)

Builds the soap request and returns the response as dictionary. Numeric and boolean values are converted from strings to Python datatypes.

get_body(service, action_name, arguments)

Returns the body by template substitution.

parse_response(response, service, action_name)

Extracts all known parameters of the given action from the response and returns this as a dictionary with the out-parameter names as keys and the corresponding response as values. Will raise an ActionError on unknown action_name.

fritzconnection.core.soaper.boolean_convert(value)

Converts a string like ‘1’ or ‘0’ to a boolean value

fritzconnection.core.soaper.datetime_convert(value)

Converts a string in ISO 8601 format to a datetime-object.

fritzconnection.core.soaper.raise_fritzconnection_error(response)

Handles all responses with status codes other than 200. Will raise the relevant FritzConnectionException with the error code and description if available

fritzconnection.core.soaper.uuid_convert(value)

Strips the leading ‘uuid:’ part from the string.

Further Reading

Informations about the TR-064 protocol with services and actions as well as AVM-specific extensions are listet at the AVM support-page (at present in german language only).

Version History

1.1

  • FritzConnection takes a new optional parameter timeout limiting the time waiting for a router response.
  • FritzPhonebook module rewritten for Python 3 without lxml-dependency and added again to the library (missing in version 1.0).
  • Library module FritzStatus adapted to Python 3.

1.0.1

  • Bugfix in fritzinspection for command line based inspection of the Fritz!Box API.

1.0

  • Requires Python 3.6 or newer. The 0.8.x release is the last version supporting Python 2.7 and Python 3 up to 3.5
  • The lxml library is no longer a dependency.
  • New project layout. Library modules are now located in the new lib package.
  • Rewrite of the description parser.
  • Errors reported by the Fritz!Box are now raising specific exceptions.

0.8.4

  • Bugfix in connection.reconnect(). This bug has been introduced with version 0.8.0. For versions 0.8.0 to 0.8.3 ‘reconnect’ requires a password because of a changed service call.
  • Documentation updated.

0.8.3

  • Fix broken test (new in version 0.8.0)
  • Minor code enhancements

0.8.2

  • Unified version numbering of the modules.
  • ServiceError, ActionError and AuthorizationError are also importable from the package.
  • Some code cleanup.

Changes in the development process: .hgignore removed and .gitignore added, changes in setup.py, readme changed to restructured text.

As Atlassian has announced to drop support for mercurial on bitbucket und will remove the according repositories (in June 2020), development of fritzconnection has converted from hg to git and the repository has been transfered to github. Unfortunately the issue- and discussion-history will be lost this way (even by keeping the new git-repository at bitbucket).

0.8.1

FritzStatus: bugfix requiring a password in combination with fritzconnection >= 0.8.0

FritzStatus: added the external_ipv6 attribute

FritzStatus: added the max_linked_bit_rate attribute for the physical rate. Also added the str_max_linked_bit_rate attribute for a more readable output. (password must be provided for these infomations)

FritzConnection: added the AuthorizationError exception.

0.8.0

Bugfix how servicenames are extracted from the xml-description files. However, the api has not changed.

The requirements are now fixed for lxml (4.3.4) and requests (2.22.0) as these versions are still supporting python 2.7

0.7.1 - 0.7.3

Bugfixes, no new features or other changes.

0.7.0

FritzConnection does now check for the environment variables FRITZ_USER and FRITZ_PASSWORD in case that neither user nor password are given.

FritzStatus now accepts user and password as keyword-parameters. Keep in mind, that FritzBoxes may return different informations about the status depending whether these are gathered with or without a password.

0.6.5

There is a new attribute package_version:

>>> import fritzconnection
>>> fritzconnection.package_version
0.6.5

Because every module of the fritzconnection-package has it’s own version, version-history of the package gets confusing over time. From now on every change of the content of the package is indicated by the the package-version. Every unchanged module keeps it’s version. So i.e. the recent package-version is 0.6.5 but the fritzconnection-module is still in version 0.6 cause nothing has changed in this module since then.

0.6

FritzConnection now uses long qualified names as servicename, i.e. WLANConfiguration:1 or WLANConfiguration:2. So these servicenames can now be used to call actions on different services with the same name:

>>> connection = FritzConnection()
>>> info = connection.call_action('WANIPConnection:2', 'GetInfo')

For backward compatibility servicename-extensions like ‘:2’ can be omitted on calling ‘call_action’. In this case FritzConnection will use the extension ‘:1’ as default.

On calling unknown services or actions in both cases KeyErrors has been raised. Calling an unknown service (or one unaccessible without a password) will now raise a ServiceError. Calling an invalid action on a service will raise an ActionError. Both Exceptions are Subclasses from the new FritzConnectionException. The Exception classes can get imported from fritzconnection:

>>> from fritzconnection import ServiceError, ActionError

Authors

Additional authors having contributed to this project:

License

As an open source and non profit software fritzconnection has the liberal MIT-License (“Expat License”). So basically, you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.

In short that means:

  • You are allowed to download, install and use the software for free, even for commercial products.
  • You are entirely at your own risk.

Here is the long version:

Copyright (c) 2012-2019 Klaus Bremer

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.