Quick & dirty API implementation for the AVM FRITZ!Box using Golang and REST.
Warning: There is no official API for some of these functions (except any smarthome-related stuff). This means, consistency across software-versions or different routers/repeaters is not guaranteed.
This repository (structure, authentication) is based on Philipp Franke's implementation (go-fritzbox).
I added parsing for some endpoints and made some of his code worse in the process ;)
Issues, Pull Requests and E-Mails are always welcome.
I accept suggestions for any new endpoints.
This library works with FRITZ!OS 7.56 with the 6690 Cable. The smarthome-implementations (DECT) are stable and compatible with all versions and routers, except for any Pya endpoints and endpoints explicitely marked as unstable. These endpoints are neither consistent across versions nor backwards-compatible. They may also break unexpectedly.
Smarthome: Using the official http-API, some types of smarthome-devices have been implemented. See the separate readme.
Clientlist:
-
GetCLientList
Get all currently connected devices in a list. -
Profile
is empty by default (see Docs for more info)
Device: SetIP
, SetName
Profiles: GetAvailableProfiles
, GetProfileUIDFromDevice
, SetProfileForDevice
Logs: GetEventLog
, GetEventLogUntil
Statistics: GetTrafficStats
Custom Requests: (See examples)
I will eventually come around to writing a proper documentation. For now, you can look at the examples and check the godoc.
pip install selenium-wire
Try running the script using commandline-args:
python pyAdapter/main.py OK;DEBUG;LOGIN http://192.168.178.1/ <current SID>
You can get an SID by logging into the Fritzbox in your brower and right-click + copying the link from (for example) one of the buttons in the top right (MyFritz, Fritz!Nas). The SID is contained in the link.
Remove the Debug if executing in headless (for example when connected via ssh):
python pyAdapter/main.py OK;LOGIN http://192.168.178.1/ <current SID>
Arguments can be given to the ChromeDriver like so:
python pyAdapter/main.py OK;DEBUG;ARGS --no-sandbox|--disable-gpu|disable-dev-shm-usage;LOGIN http://192.168.178.1/ <current SID>
If there are crashes, no-sandbox
, disable-gpu
and/or disable-dev-shm-usage
are usually good arguments to try.
If that works and logs into the FritzBox, it should be okay to start the PyAdapter from the Go-Program.
This Library is a Project I maintain and develop based on my personal needs. It's public because there aren't many maintained alternatives, not because I'm necessarily proud of its implementation. Code quality is not great, especially older code. There are no tests, because what I would really like to test (whether what I'm sending the FritzBox is still correct, for example after a FritzOS-Update) is very difficult to implement. For example, for Testing if changing the Name for a Device works, I would have to get some Device, change the Name, check if it worked, then change it back, without breaking anything in my internal Network. Doing this in a way that would also allow other people to execute these Tests is even more difficult.
There are two (three) types of API-Endpoints used in this libary:
- DECT: These are the endpoints used for smarthome-devices. They are documented in
the official documentation
and usually do not change. These Endpoints are implemented in the
smarthome_
-parts of this package and their respective Functions have the PrefixDECT
. - Frontend Endpoints: POST-Request are sent to the FritzBox mimicking the Requests the Front-End would send during
normal
User Interaction. Because the required Parameters seem to change semi-regularly, all of these Endpoints are unstable
and may break
at any time. They are usually marked as
Unstable
in their GoDoc. In the beginning I was planning to use this type of Request for most of the Functionality I needed, but I quickly ran into a Roadblock with the Requests' Parameters. For Example when editing a Device, the Request sent by the Frontend always contains all the Devices' Parameters, even if they haven't changed. This means, no matter what Setting you want to change, you would have to get all the Parameters for a Device, change the one you want to change, then send all the Parameters back to the FritzBox. While sometimes, Parameters are optional in the Request, the FritzBox seems to reset these Params to their default if you don't send them. This proved basically impossible, because I would have to manually parse the Parameters for every Request from the respective Setting Pages HTML, then convert them to the Format the Request expects. Doing this for every Setting, and for every Value the given Setting can be set to, is unfeasible. Instead, this Type of Request is only used for Endpoints that fetch and parse Data, like theGetClientList
-Endpoint (There are still older Endpoints that use this Type of Request, but I'm planning to change them at some point). - PYA Endpoints: What I came up with for the Problem described above are PYA Endpoints, where PYA stands for Python Adapter. When wanting to use PYA Endpoints, a PyAdapter-Struct has to be created and started. This will start the Python-Script which in turn starts a headless Chromedriver and listens to commands on stdin. The Chromedriver is used to send an "empty" Request to the FritzBox in order to retrieve the required Parameters, which are then returned to the Go-Program. After the Parameters have been retrieved, it is then simple to change the Parameter of the Setting we want to change and send the Post-Request to the FritBox. Retrieving the Parameters takes some Time (1-3 seconds), but generally, it's not much slower than some of the Endpoints of the official Smarthome-API. To improve the Time it takes to retrieve the Parameters, the PyAdapter is started concurrently to the Go-Program, meaning the Chromedriver is already started and logged in to the Fritzbox, which takes up to 7 seconds total. This means a "cold" start, where the PyAdapter first has to start and log in before sending the request can take up to 10 seconds. Further improvements to Speed can be made by caching the parameters, which I plan on doing at some point. However, caching will only work if no manual changes are made in the FritzBox-Interface to the given Device, because this would invalidate the cached Parameters and thus lead to the manual changes being overridden on the next change request. Currently the PYA expects the Webdriver in the PyAdapter directory or in the Path.
- Better documentation
- Pya Cache
- Implementing more smarthome-capabilities/HanFun-interfaces
- Implementing endpoints for smarthome-templates (
gettemplatelistinfos
,applytemplate
)
See Philipp's example here