Compare commits

...

45 Commits

Author SHA1 Message Date
Christian Stade-Schuldt d7929f15fc fix up_traffic 2021-04-29 09:12:52 +02:00
Christian Stade-Schuldt 2dabb02c2c remove f-strings and one minor bug 2021-03-29 19:36:20 +02:00
Christian Stade-Schuldt 1e3e718d64
Update login for Fritz!OS 7.25 compatibility (#52)
* use username and password
* default to python3
2021-03-26 15:19:02 +01:00
Christian Stade-Schuldt eee98feeac
Merge pull request #48 from 2Fake/master
use requirements.txt to install requirements
2021-03-26 12:16:00 +01:00
Markus Bong 8ce50dfeb6 fix typo 2020-12-08 15:04:23 +01:00
Markus Bong a9058f9c74 use requirements.txt to install requirements 2020-12-08 14:56:29 +01:00
Christian Stade-Schuldt c82e99a4b4
Merge pull request #44 from oe73773/patch-1
Added "pip install lxml"
2020-12-07 10:13:36 +01:00
oe73773 d5b7a2eb64
Added "pip install lxml"
I added "pip install lxml" because it was missing on debain 10.
I added python3 requirement.
2020-07-05 20:45:26 +02:00
Christian Stade-Schuldt 2dd4e07013 make checks language agnostic. Rely on position instead. 2019-04-09 18:59:54 +02:00
Christian Stade-Schuldt 883c61e498 adapt scripts for FritzOS 7.1, scripts are Python 3 only now 2019-04-09 09:47:49 +02:00
Christian Stade-Schuldt ef6f81b426 update Readme 2018-09-12 17:07:10 +02:00
Christian Stade-Schuldt cd269783bd update Readme 2018-09-11 23:15:34 +02:00
Christian Stade-Schuldt 3364b29ec1 remove invalid parantheses 2018-07-04 01:00:36 +02:00
Christian Stade-Schuldt ee66451dcc update README 2018-03-16 19:34:18 +01:00
Christian Stade-Schuldt 34ee94ce1d update README and Contributors 2017-11-04 17:04:42 +01:00
Christian Stade-Schuldt 666e3d0a0a changes towards python 3 compatibility 2017-11-04 17:04:26 +01:00
Christian Stade-Schuldt bfdeb190f3 use lxml for parsing and better error handling 2017-11-04 17:04:00 +01:00
Christian Stade-Schuldt a2fb8f7dc7 update README 2017-10-13 20:45:19 +02:00
Christian Stade-Schuldt 5f64d24d9c Merge pull request #22 from cweiske/patch-1
Talk about the UPnP status setting
2017-10-13 20:35:36 +02:00
Christian Weiske 9264e49e27 Talk about the UPnP status setting
If you don't enable that, you'll get an exception: Unknown Service: WANIPConnection:1
2017-10-13 20:29:05 +02:00
Christian Stade-Schuldt c5cdb516d7 format readme 2017-09-06 23:42:55 +02:00
Christian Stade-Schuldt 42c1d2461d add CONTRIBUTORS.md 2017-09-06 22:58:39 +02:00
Christian Stade-Schuldt 213a64abe7 update changelog 2017-09-06 22:51:46 +02:00
Christian Stade-Schuldt 78a5a202cf move power consumption to system group 2017-09-06 22:41:27 +02:00
Christian Stade-Schuldt 9fe16979b7 formatting 2017-09-06 22:41:09 +02:00
Christian Stade-Schuldt 4e5ede6d12 Merge pull request #16 from bobvandevijver/separate-hosts
Fixes #15. Add support for separate hosts
2017-09-06 22:34:31 +02:00
Bob van de Vijver ca82415b78 Fixes #15. Add support for separate hosts 2017-09-06 22:33:15 +02:00
Christian Stade-Schuldt 209eed91ae Merge pull request #18 from bobvandevijver/remove-traffic-max
Fixes #13. Configurable traffic maximum
2017-09-06 22:28:41 +02:00
Christian Stade-Schuldt 523b83ce17 Merge pull request #19 from bobvandevijver/localization-support
Fixes #14. Added localization for english
2017-09-06 22:27:38 +02:00
Bob van de Vijver 27ea9ea8eb Fixes #14. Added localization for english 2017-09-06 22:21:50 +02:00
Bob van de Vijver c1b1d4bffa Fixes #13. Configurable traffic maximum 2017-09-06 21:35:23 +02:00
Christian Stade-Schuldt 7291edc724 Merge pull request #17 from bobvandevijver/fix-doc
Fixed doc style + removed os note on 5490
2017-09-06 21:29:51 +02:00
Bob van de Vijver 4e7a583b7a Fixed doc style + removed os note on 5490 2017-09-06 21:19:12 +02:00
Christian Stade-Schuldt 2c05d20602 Merge pull request #12 from bobvandevijver/patch-1
Added 5490 & note about language
2017-09-04 17:45:22 +02:00
Christian Stade-Schuldt 7a051bc5b8 Update README.md 2017-09-04 17:44:57 +02:00
Bob van de Vijver d8d37e9d91 Added 5490 & note about language 2017-09-03 22:16:52 +02:00
Christian Stade-Schuldt b8a8e2c343 update README 2017-06-11 22:49:27 +02:00
Christian Stade-Schuldt 859fd461e4 update readme 2017-06-11 22:23:29 +02:00
Christian Stade-Schuldt bcfed06c5e Merge branch 'master' into fritzos6.5 2017-06-11 22:19:26 +02:00
Christian Stade-Schuldt 2a1185612e fix import 2016-05-17 01:38:54 +02:00
Christian Stade-Schuldt a421008e51 fix import 2016-05-17 01:38:24 +02:00
Christian Stade-Schuldt 60fc6e7db1 use custom ip address 2016-05-17 01:30:57 +02:00
Christian Stade-Schuldt d162f8bf83 use custom ip address 2016-05-17 01:30:28 +02:00
Christian Stade-Schuldt 59fba1f701 fix one day uptime bug 2016-04-17 11:36:32 +02:00
Christian Stade-Schuldt c776ef25a9 update scripts for FRITZ!OS:131.06.36-32026 BETA 2015-12-19 11:34:21 +01:00
14 changed files with 643 additions and 363 deletions

61
.gitignore vendored Normal file
View File

@ -0,0 +1,61 @@
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/

4
CONTRIBUTORS.md Normal file
View File

@ -0,0 +1,4 @@
## fritzbox-munin contributors
- Bob van de Vijver ([bobvandevijver](https://github.com/bobvandevijver))
- Framps ([framps](https://github.com/framps))

View File

@ -1,6 +1,28 @@
# Changelog
## 7.25.0
*2021-03-26*
- Support for FritzOS!7.25 including log in via username password
## 7.0.0
*2018-09-11*
- Support for FritzOS!7.00
## 6.83.2
*2017-09-05*
- Support for German and English user interface (by: [@bobvandevijver](https://github.com/bobvandevijver))
- Support for running Fritzbox as separate host (by: [@bobvandevijver](https://github.com/bobvandevijver))
- Make maximum download and upload optional by config (by: [@bobvandevijver](https://github.com/bobvandevijver))
## 6.83.1
*2017-06-11*
- Support for FRITZ!OS 6.83. This version is not compatible with the old FRITZ!OS 6.30.
## 6.30.1
*2017-06-11*
- Initial version supporting FRITZ!OS 6.30
- Initial version supporting FRITZ!OS 6.30

123
README.md
View File

@ -1,71 +1,136 @@
# fritzbox-munin
A collection of munin plugins to monitor your AVM FRITZ!Box router. The scripts have been developed using a [FRITZ!Box 7362 SL](http://geni.us/fTyoY)(Amazon link) running FRITZ!OS 06.30.
A collection of munin plugins to monitor your AVM FRITZ!Box router. The scripts have been developed using a [FRITZ!Box 7590](http://geni.us/OO2c7S)(Amazon link) running FRITZ!OS 7.25.
If you are using the scripts on a different Fritz!Box model please let me know by
- opening an issue
- submitting a pull request
So far the following models (running FRITZ!OS 06.83) have been confirmed working:
- [FRITZ!Box 3370](http://geni.us/zh3U)
- [FRITZ!Box 5490](http://geni.us/ACtUyFt)
- [FRITZ!Box 7362 SL](http://geni.us/fTyoY)
- [FRITZ!Box 7390](http://geni.us/BlAP)
- [FRITZ!Box 7430](http://geni.us/BlAP)
- [FRITZ!Box 7490](http://geni.us/fTyoY)
- [FRITZ!Box 7530](https://geni.us/h8oqYd)
- [FRITZ!Box 7530 AX](https://geni.us/a4dS5)
- [FRITZ!Box 7560](http://geni.us/6gPZNI)
- [FRITZ!Box 7580](http://geni.us/yUYyQTE)
- [FRITZ!Box 7590](http://geni.us/OO2c7S)
If you are still running an older Fritz!OS version check out the [releases section](https://github.com/Tafkas/fritzbox-munin/releases/).
## Introduction
These python scripts are [Munin](http://munin-monitoring.org) plugins for monitoring the [Fritz!Box](http://avm.de/produkte/fritzbox/) router by AVM.
## fritzbox\_traffic
fritzbox\_traffic shows you the traffic of the WAN interface (requires fritzconnection)
fritzbox\_traffic shows you the traffic of the WAN interface (requires fritzconnection)
![http://i.imgur.com/8BwNMOL.png](http://i.imgur.com/8BwNMOL.png)
If you do not want to show the interface maximum values, add the following to your plugin-configuration:
env.traffic_remove_max true
## fritzbox\_connection\_uptime
fritzbox\_connection\_uptime shows you the connection uptime in days (requires fritzconnection)
fritzbox\_connection\_uptime shows you the connection uptime in days (requires fritzconnection)
![http://i.imgur.com/8oE1OYL.png](http://i.imgur.com/8oE1OYL.png)
## fritzbox\_cpu\_usage
fritzbox\_cpu\_usage shows you the cpu usage (requires password)
fritzbox\_cpu\_usage shows you the cpu usage (requires username & password)
![http://i.imgur.com/A9uGvWP.png](http://i.imgur.com/A9uGvWP.png)
## fritzbox\_cpu\_temperature
fritzbox\_cpu\_temperature shows you the cpu temperature (requires password)
fritzbox\_cpu\_temperature shows you the cpu temperature (requires username & password)
![http://i.imgur.com/duHYhw6.png](http://i.imgur.com/duHYhw6.png)
## fritzbox\_memory\_usage
fritzbox\_memory\_usage shows you the memory usage (requires password)
fritzbox\_memory\_usage shows you the memory usage (requires username & password)
![http://i.imgur.com/WhxrINK.png](http://i.imgur.com/WhxrINK.png)
## fritzbox\_power\_consumption
fritzbox\_power\_consumption shows you the power consumption (requires password)
fritzbox\_power\_consumption shows you the power consumption (requires username & password)
![http://i.imgur.com/a7uQzn6.png](http://i.imgur.com/a7uQzn6.png)
## fritzbox\_uptime
fritzbox\_uptime shows you the uptime in days (requires password)
fritzbox\_uptime shows you the uptime in days (requires username & password) (language dependant, see below).
![http://i.imgur.com/Jr8OibH.png](http://i.imgur.com/Jr8OibH.png)
## fritzbox\_wifi\_devices
fritzbox\_wifi\_devices shows you the number of connected wifi clients (requires password)
fritzbox\_wifi\_devices shows you the number of connected wifi clients (requires username & password) (language dependant, see below).
![http://i.imgur.com/lqvK1b2.png](http://i.imgur.com/lqvK1b2.png)
## Installation & Configuration
## Installation & Configuration
0. Pre-requesites for the fritzbox\_traffic and fritzbox\_uptime plugins is the [fritzconnection](https://pypi.python.org/pypi/fritzconnection) package. To install it
pip install fritzconnection
1. Pre-requesites for the fritzbox\_traffic and fritzbox\_uptime plugins are the [fritzconnection](https://pypi.python.org/pypi/fritzconnection) and [requests](https://pypi.python.org/pypi/requests) package. To install it
1. Copy all the scripts to =/usr/share/munin/plugins
2. Create entry in /etc/munin/plugin-conf.d/munin-node:
[fritzbox_*]
env.fritzbox_ip <ip_address_to_your_fritzbox>
env.fritzbox_password <fritzbox_password>
pip install -r requirements.txt
fritzconnection requires python3. Make sure python --version is >= 3.6.
3. Create symbolic links to /etc/munin/plugins.
2. Make sure the FritzBox has UPnP status information enabled. (German interface: Heimnetz > Heimnetzübersicht > Netzwerkeinstellungen > Statusinformationen über UPnP übertragen)
4. Restart the munin-node daemon: /etc/init.d/munin-node restart.
3. Copy all the scripts to `/usr/share/munin/plugins`
5. Done. You should now start to see the charts on the Munin pages.
4. Create entry in `/etc/munin/plugin-conf.d/munin-node`:
[fritzbox_*]
env.fritzbox_ip <ip_address_to_your_fritzbox>
env.fritzbox_username <fritzbox_username>
env.fritzbox_password <fritzbox_password>
env.traffic_remove_max true # if you do not want the possible max values
host_name fritzbox
5. Create symbolic links to `/etc/munin/plugins`.
6. Restart the munin-node daemon: `/etc/init.d/munin-node restart`.
7. Done. You should now start to see the charts on the Munin pages.
## Localization
Two scripts depend on the language selected in your fritzbox: the uptime and wifi\_devices. Currently, two locales are
supported:
1. German: `de` (default)
2. English: `en`
You can change the used locale by setting an environment variable in your plugin configuration:
env.locale en
## Different hosts for the fritzbox and your system
You can split the graphs of your fritzbox from the localhost graphs by following the next steps:
1. Use the following as your host configuration in `/etc/munin/munin.conf`
[home.yourhost.net;server]
address 127.0.0.1
use_node_name yes
[home.yourhost.net;fritzbox]
address 127.0.0.1
use_node_name no
2. Add the following to your munin-node configuration
env.host_name fritzbox
3. Restart your munin-node: `systemctl restart munin-node`
## Environment Settings
Do not forget to restart the munin-node daemon as described in step 3 of the installation instructions above.

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_connection_uptime - A munin plugin for Linux to monitor AVM Fritzbox connection uptime
Copyright (C) 2015 Christian Stade-Schuldt
@ -10,41 +10,54 @@
This plugin requires the fritzconnection plugin. To install it using pip:
pip install fritzconnection
This plugin supports the following munin configuration parameters:
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
#%# family=auto contrib
#%# capabilities=autoconf
"""
import os
import sys
from fritzconnection import FritzConnection
from fritzconnection.lib.fritzstatus import FritzStatus
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
def print_values():
try:
conn = FritzConnection()
fs = FritzStatus(address=server, user=username, password=password)
except Exception as e:
sys.exit("Couldn't get connection uptime")
uptime = conn.call_action('WANIPConnection', 'GetStatusInfo')['NewUptime']
print ('uptime.value %.2f' % (int(uptime) / 86400.0))
uptime = fs.uptime
print("uptime.value %.2f" % (int(uptime) / 86400.0))
def print_config():
print "graph_title AVM Fritz!Box Connection Uptime"
print "graph_args --base 1000 -l 0"
print 'graph_vlabel uptime in days'
print "graph_scale no'"
print "graph_category network"
print "uptime.label uptime"
print "uptime.draw AREA"
print("graph_title AVM Fritz!Box Connection Uptime")
print("graph_args --base 1000 -l 0")
print("graph_vlabel uptime in days")
print("graph_scale no'")
print("graph_category network")
print("uptime.label uptime")
print("uptime.draw AREA")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print "yes" # Some docs say it'll be called with fetch, some say no arg at all
elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == 'fetch'):
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes") # Some docs say it'll be called with fetch, some say no arg at all
elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == "fetch"):
try:
print_values()
except:

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_cpu_temperature - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,57 +9,54 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import json
import os
import re
import sys
import fritzbox_helper as fh
PAGE = '/system/ecostat.lua'
pattern = re.compile(".*/(StatTemperature)\".*=.*\"(.*?)\"")
PAGE = "ecoStat"
def get_cpu_temperature():
"""get the current cpu temperature"""
server = os.environ['fritzbox_ip']
password = os.environ['fritzbox_password']
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
sid = fh.get_sid(server, password)
data = fh.get_page(server, sid, PAGE)
m = re.search(pattern, data)
if m:
print 'temp.value %d' % (int(m.group(2).split(',')[0]))
session_id = fh.get_session_id(server, username, password)
xhr_data = fh.get_xhr_content(server, session_id, PAGE)
data = json.loads(xhr_data)
print("temp.value %d" % (int(data["data"]["cputemp"]["series"][0][-1])))
def print_config():
print "graph_title AVM Fritz!Box CPU temperature"
print "graph_vlabel degrees Celsius"
print "graph_category sensors"
print "graph_order tmp"
print "graph_scale no"
print "temp.label CPU temperature"
print "temp.type GAUGE"
print "temp.graph LINE1"
print "temp.min 0"
print "temp.info Fritzbox CPU temperature"
print("graph_title AVM Fritz!Box CPU temperature")
print("graph_vlabel degrees Celsius")
print("graph_category sensors")
print("graph_order tmp")
print("graph_scale no")
print("temp.label CPU temperature")
print("temp.type GAUGE")
print("temp.graph LINE1")
print("temp.min 0")
print("temp.info Fritzbox CPU temperature")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print 'yes'
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == 'fetch':
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes")
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == "fetch":
# Some docs say it'll be called with fetch, some say no arg at all
try:
get_cpu_temperature()
except:
sys.exit("Couldn't retrieve fritzbox cpu temperature")
get_cpu_temperature()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_cpu_usage - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,55 +9,55 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import json
import os
import re
import sys
import fritzbox_helper as fh
PAGE = '/system/ecostat.lua'
pattern = re.compile(".*/(StatCPU)\".*=.*\"(.*?)\"")
PAGE = "ecoStat"
def get_cpu_usage():
"""get the current cpu usage"""
server = os.environ['fritzbox_ip']
password = os.environ['fritzbox_password']
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
sid = fh.get_sid(server, password)
data = fh.get_page(server, sid, PAGE)
m = re.search(pattern, data)
if m:
print 'cpu.value %d' % (int(m.group(2).split(',')[0]))
session_id = fh.get_session_id(server, username, password)
xhr_data = fh.get_xhr_content(server, session_id, PAGE)
data = json.loads(xhr_data)
print("cpu.value %d" % (int(data["data"]["cpuutil"]["series"][0][-1])))
def print_config():
print "graph_title AVM Fritz!Box CPU usage"
print "graph_vlabel %"
print "graph_category system"
print "graph_order cpu"
print "graph_scale no"
print "cpu.label system"
print "cpu.type GAUGE"
print "cpu.graph AREA"
print "cpu.min 0"
print "cpu.info Fritzbox CPU usage"
print("graph_title AVM Fritz!Box CPU usage")
print("graph_vlabel %")
print("graph_category system")
print("graph_order cpu")
print("graph_scale no")
print("cpu.label system")
print("cpu.type GAUGE")
print("cpu.graph AREA")
print("cpu.min 0")
print("cpu.info Fritzbox CPU usage")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print 'yes'
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == 'fetch':
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes")
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == "fetch":
# Some docs say it'll be called with fetch, some say no arg at all
try:
get_cpu_usage()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_helper - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,85 +9,157 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
The initial script was inspired by
https://www.linux-tips-and-tricks.de/en/programming/389-read-data-from-a-fritzbox-7390-with-python-and-bash
framp at linux-tips-and-tricks dot de
New authentication supporting username and password, as well as PBKDF2 support, has been inspired by
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM%20Technical%20Note%20-%20Session%20ID_englisch.pdf
"""
import hashlib
import httplib
import re
import sys
from xml.dom import minidom
import time
USER_AGENT = "Mozilla/5.0 (U; Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0"
import requests
from lxml import etree
USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0"
LOGIN_SID_ROUTE = "/login_sid.lua?version=2"
def get_sid(server, password, port=80):
"""Obtains the sid after login into the fritzbox"""
conn = httplib.HTTPConnection(server + ':' + str(port))
class LoginState:
def __init__(self, challenge, blocktime):
self.challenge = challenge
self.blocktime = blocktime
self.is_pbkdf2 = challenge.startswith("2$")
headers = {"Accept": "application/xml",
"Content-Type": "text/plain",
"User-Agent": USER_AGENT}
initial_page = '/login_sid.lua'
conn.request("GET", initial_page, '', headers)
response = conn.getresponse()
data = response.read()
if response.status != 200:
print "%s %s" % (response.status, response.reason)
sys.exit(0)
def get_session_id(server, username, password, port=80):
""" Get a sid by solving the PBKDF2 (or MD5) challenge-response process. """
box_url = "http://{}:{}".format(server, port)
try:
state = get_login_state(box_url)
except Exception as ex:
raise Exception("failed to get challenge")
if state.is_pbkdf2:
# print("PBKDF2 supported")
challenge_response = calculate_pbkdf2_response(state.challenge, password)
else:
xml_data = minidom.parseString(data)
sid_info = xml_data.getElementsByTagName('SID')
sid = sid_info[0].firstChild.data
if sid == "0000000000000000":
challenge_info = xml_data.getElementsByTagName('Challenge')
challenge = challenge_info[0].firstChild.data
challenge_bf = (challenge + '-' + password).decode('iso-8859-1').encode('utf-16le')
m = hashlib.md5()
m.update(challenge_bf)
response_bf = challenge + '-' + m.hexdigest().lower()
else:
return sid
headers = {"Accept": "text/html,application/xhtml+xml,application/xml",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": USER_AGENT}
login_page = "/login_sid.lua?&response=" + response_bf
conn.request("GET", login_page, '', headers)
response = conn.getresponse()
data = response.read()
if response.status != 200:
print "%s %s" % (response.status, response.reason)
sys.exit(0)
else:
sid = re.search("<SID>(.*?)</SID>", data).group(1)
if sid == "0000000000000000":
print "ERROR - No SID received because of invalid password"
sys.exit(0)
return sid
# print("Falling back to MD5")
challenge_response = calculate_md5_response(state.challenge, password)
if state.blocktime > 0:
# print(f"Waiting for {state.blocktime} seconds...")
time.sleep(state.blocktime)
try:
sid = send_response(box_url, username, challenge_response)
except Exception as ex:
raise Exception("failed to login") from ex
if sid == "0000000000000000":
raise Exception("wrong username or password")
return sid
def get_page(server, sid, page, port=80):
"""Fetches a page from the Fritzbox and returns its content"""
conn = httplib.HTTPConnection(server + ':' + str(port))
def get_login_state(box_url):
""" Get login state from FRITZ!Box using login_sid.lua?version=2 """
url = box_url + LOGIN_SID_ROUTE
r = requests.get(url)
xml = etree.fromstring(r.content)
challenge = xml.find("Challenge").text
blocktime = int(xml.find("BlockTime").text)
return LoginState(challenge, blocktime)
headers = {"Accept": "application/xml",
"Content-Type": "text/plain",
"User-Agent": USER_AGENT}
page_with_sid = page + "?sid=" + sid
conn.request("GET", page_with_sid, '', headers)
response = conn.getresponse()
data = response.read()
if response.status != 200:
print "%s %s" % (response.status, response.reason)
print data
sys.exit(0)
else:
return data
def calculate_pbkdf2_response(challenge, password):
""" Calculate the response for a given challenge via PBKDF2 """
challenge_parts = challenge.split("$")
# Extract all necessary values encoded into the challenge
iter1 = int(challenge_parts[1])
salt1 = bytes.fromhex(challenge_parts[2])
iter2 = int(challenge_parts[3])
salt2 = bytes.fromhex(challenge_parts[4])
# Hash twice, once with static salt...
# Once with dynamic salt.
hash1 = hashlib.pbkdf2_hmac("sha256", password.encode(), salt1, iter1)
hash2 = hashlib.pbkdf2_hmac("sha256", hash1, salt2, iter2)
return "{}${}".format(challenge_parts[4], hash2.hex())
def calculate_md5_response(challenge, password):
""" Calculate the response for a challenge using legacy MD5 """
response = challenge + "-" + password
# the legacy response needs utf_16_le encoding
response = response.encode("utf_16_le")
md5_sum = hashlib.md5()
md5_sum.update(response)
response = challenge + "-" + md5_sum.hexdigest()
return response
def send_response(box_url, username, challenge_response):
""" Send the response and return the parsed sid. raises an Exception on error """
# Build response params
post_data = {"username": username, "response": challenge_response}
# post_data = urllib.parse.urlencode(post_data_dict).encode()
headers = {"Content-Type": "application/x-www-form-urlencoded"}
url = box_url + LOGIN_SID_ROUTE
r = requests.post(url, headers=headers, data=post_data)
# Parse SID from resulting XML.
xml = etree.fromstring(r.content)
return xml.find("SID").text
def get_page_content(server, session_id, page, port=80):
"""Fetches a page from the Fritzbox and returns its content
:param server: the ip address of the Fritzbox
:param session_id: a valid session id
:param page: the page you are regquesting
:param port: the port the Fritzbox webserver runs on
:return: the content of the page
"""
headers = {"Accept": "application/xml", "Content-Type": "text/plain", "User-Agent": USER_AGENT}
url = "http://{}:{}/{}?sid={}".format(server, port, page, session_id)
try:
r = requests.get(url, headers=headers)
r.raise_for_status()
except requests.exceptions.HTTPError as err:
print(err)
sys.exit(1)
return r.content
def get_xhr_content(server, session_id, page, port=80):
"""Fetches the xhr content from the Fritzbox and returns its content
:param server: the ip address of the Fritzbox
:param session_id: a valid session id
:param page: the page you are regquesting
:param port: the port the Fritzbox webserver runs on
:return: the content of the page
"""
headers = {
"Accept": "application/xml",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": USER_AGENT,
}
url = "http://{}:{}/data.lua".format(server, port)
data = {"xhr": 1, "sid": session_id, "lang": "en", "page": page, "xhrId": "all", "no_sidrenew": ""}
try:
r = requests.post(url, data=data, headers=headers)
except requests.exceptions.HTTPError as err:
print(err)
sys.exit(1)
return r.content

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_memory_usage - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,62 +9,63 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import json
import os
import re
import sys
import fritzbox_helper as fh
PAGE = '/system/ecostat.lua'
pattern = re.compile(".*/(StatRAM.*?)\".*=.*\"(.*?)\"")
USAGE_MAPPING = {'StatRAMCacheUsed': 'cache', 'StatRAMPhysFree': 'free', 'StatRAMStrictlyUsed': 'strict'}
PAGE = "ecoStat"
USAGE = ["strict", "cache", "free"]
def get_memory_usage():
"""get the current memory usage"""
server = os.environ['fritzbox_ip']
password = os.environ['fritzbox_password']
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
sid = fh.get_sid(server, password)
data = fh.get_page(server, sid, PAGE)
matches = re.finditer(pattern, data)
if matches:
for m in matches:
print'%s.value %d' % (USAGE_MAPPING[m.group(1)], int(m.group(2).split(',')[0]))
session_id = fh.get_session_id(server, username, password)
xhr_data = fh.get_xhr_content(server, session_id, PAGE)
data = json.loads(xhr_data)
for i, usage in enumerate(USAGE):
print("%s.value %s" % (usage, data["data"]["ramusage"]["series"][i][-1]))
def print_config():
print "graph_title AVM Fritz!Box Memory"
print "graph_vlabel %"
print "graph_args --base 1000 -r --lower-limit 0 --upper-limit 100"
print "graph_category system"
print "graph_order strict cache free"
print "graph_info This graph shows what the Fritzbox uses memory for."
print "graph_scale no"
print "strict.label strict"
print "strict.type GAUGE"
print "strict.draw AREA"
print "cache.label cache"
print "cache.type GAUGE"
print "cache.draw STACK"
print "free.label free"
print "free.type GAUGE"
print "free.draw STACK"
print("graph_title AVM Fritz!Box Memory")
print("graph_vlabel %")
print("graph_args --base 1000 -r --lower-limit 0 --upper-limit 100")
print("graph_category system")
print("graph_order strict cache free")
print("graph_info This graph shows what the Fritzbox uses memory for.")
print("graph_scale no")
print("strict.label strict")
print("strict.type GAUGE")
print("strict.draw AREA")
print("cache.label cache")
print("cache.type GAUGE")
print("cache.draw STACK")
print("free.label free")
print("free.type GAUGE")
print("free.draw STACK")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print 'yes'
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == 'fetch':
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes")
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == "fetch":
# Some docs say it'll be called with fetch, some say no arg at all
try:
get_memory_usage()

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding=utf-8
"""
fritzbox_power_consumption - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,87 +10,89 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import json
import os
import re
import sys
import fritzbox_helper as fh
PAGE = '/system/energy.lua'
pattern = re.compile(".*/(.*act?)\".*=.*\"(.*?)\"")
DEVICE_MAPPING = {'rate_abact': 'ab', 'rate_dspact': 'dsl', 'rate_sumact': 'system',
'rate_systemact': 'cpu', 'rate_usbhostact': 'usb', 'rate_wlanact': 'wifi'}
PAGE = "energy"
DEVICES = ["system", "cpu", "wifi", "dsl", "ab", "usb"]
def get_power_consumption():
"""get the current power consumption usage"""
server = os.environ['fritzbox_ip']
password = os.environ['fritzbox_password']
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
sid = fh.get_sid(server, password)
data = fh.get_page(server, sid, PAGE)
matches = re.finditer(pattern, data)
if matches:
for m in matches:
print'%s.value %d' % (DEVICE_MAPPING[m.group(1)], int(m.group(2)))
session_id = fh.get_session_id(server, username, password)
xhr_data = fh.get_xhr_content(server, session_id, PAGE)
data = json.loads(xhr_data)
devices = data["data"]["drain"]
for i, device in enumerate(DEVICES):
print("%s.value %s" % (device, devices[i]["actPerc"]))
def print_config():
print "graph_title AVM Fritz!Box Power Consumption"
print "graph_vlabel %"
print "graph_category network"
print "graph_order system cpu wifi dsl ab usb"
print "system.label system"
print "system.type GAUGE"
print "system.graph LINE12"
print "system.min 0"
print "system.max 100"
print "system.info Fritzbox overall power consumption"
print "cpu.label cpu"
print "cpu.type GAUGE"
print "cpu.graph LINE1"
print "cpu.min 0"
print "cpu.max 100"
print "cpu.info Fritzbox central processor power consumption"
print "wifi.label wifi"
print "wifi.type GAUGE"
print "wifi.graph LINE1"
print "wifi.min 0"
print "wifi.max 100"
print "wifi.info Fritzbox wifi power consumption"
print "dsl.label dsl"
print "dsl.type GAUGE"
print "dsl.graph LINE1"
print "dsl.min 0"
print "dsl.max 100"
print "dsl.info Fritzbox dsl power consumption"
print "ab.label ab"
print "ab.type GAUGE"
print "ab.graph LINE1"
print "ab.min 0"
print "ab.max 100"
print "ab.info Fritzbox analog phone ports power consumption"
print "usb.label usb"
print "usb.type GAUGE"
print "usb.graph LINE1"
print "usb.min 0"
print "usb.max 100"
print "usb.info Fritzbox usb devices power consumption"
print("graph_title AVM Fritz!Box Power Consumption")
print("graph_vlabel %")
print("graph_category system")
print("graph_order system cpu wifi dsl ab usb")
print("system.label system")
print("system.type GAUGE")
print("system.graph LINE12")
print("system.min 0")
print("system.max 100")
print("system.info Fritzbox overall power consumption")
print("cpu.label cpu")
print("cpu.type GAUGE")
print("cpu.graph LINE1")
print("cpu.min 0")
print("cpu.max 100")
print("cpu.info Fritzbox central processor power consumption")
print("wifi.label wifi")
print("wifi.type GAUGE")
print("wifi.graph LINE1")
print("wifi.min 0")
print("wifi.max 100")
print("wifi.info Fritzbox wifi power consumption")
print("dsl.label dsl")
print("dsl.type GAUGE")
print("dsl.graph LINE1")
print("dsl.min 0")
print("dsl.max 100")
print("dsl.info Fritzbox dsl power consumption")
print("ab.label ab")
print("ab.type GAUGE")
print("ab.graph LINE1")
print("ab.min 0")
print("ab.max 100")
print("ab.info Fritzbox analog phone ports power consumption")
print("usb.label usb")
print("usb.type GAUGE")
print("usb.graph LINE1")
print("usb.min 0")
print("usb.max 100")
print("usb.info Fritzbox usb devices power consumption")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print 'yes'
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == 'fetch':
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes")
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == "fetch":
# Some docs say it'll be called with fetch, some say no arg at all
try:
get_power_consumption()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_traffic - A munin plugin for Linux to monitor AVM Fritzbox WAN traffic
Copyright (C) 2015 Christian Stade-Schuldt
@ -10,72 +10,86 @@
This plugin requires the fritzconnection plugin. To install it using pip:
pip install fritzconnection
This plugin supports the following munin configuration parameters:
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
#%# family=auto contrib
#%# capabilities=autoconf
"""
import os
import sys
from fritzconnection import FritzConnection
from fritzconnection.lib.fritzstatus import FritzStatus
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
def print_values():
try:
conn = FritzConnection()
fs = FritzStatus(address=server, user=username, password=password)
except Exception as e:
sys.exit("Couldn't get WAN traffic")
down_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetTotalBytesReceived')['NewTotalBytesReceived']
print ('down.value %d' % down_traffic)
down_traffic = fs.bytes_received
print("down.value %d" % down_traffic)
up_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetTotalBytesSent')['NewTotalBytesSent']
print ('up.value %d' % up_traffic)
up_traffic = fs.bytes_sent
print("up.value %d" % up_traffic)
max_down_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetCommonLinkProperties')[
'NewLayer1DownstreamMaxBitRate']
print ('maxdown.value %d' % max_down_traffic)
if not os.environ.get("traffic_remove_max"):
max_traffic = fs.max_bit_rate
max_down_traffic = max_traffic[1]
print("maxdown.value %d" % max_down_traffic)
max_up_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetCommonLinkProperties')[
'NewLayer1UpstreamMaxBitRate']
print ('maxup.value %d' % max_up_traffic)
max_up_traffic = max_traffic[0]
print("maxup.value %d" % max_up_traffic)
def print_config():
print "graph_title AVM Fritz!Box WAN traffic"
print "graph_args --base 1000"
print "graph_vlabel bits in (-) / out (+) per \${graph_period}"
print "graph_category network"
print "graph_order down up maxdown maxup"
print "down.label received"
print "down.type DERIVE"
print "down.graph no"
print "down.cdef down,8,*"
print "down.min 0"
print "down.max 1000000000"
print "up.label bps"
print "up.type DERIVE"
print "up.draw AREA"
print "up.cdef up,8,*"
print "up.min 0"
print "up.max 1000000000"
print "up.negative down"
print "up.info Traffic of the WAN interface."
print "maxdown.label received"
print "maxdown.type GAUGE"
print "maxdown.graph no"
print "maxup.label MAX"
print "maxup.type GAUGE"
print "maxup.negative maxdown"
print "maxup.draw LINE1"
print "maxup.info Maximum speed of the WAN interface."
print("graph_title AVM Fritz!Box WAN traffic")
print("graph_args --base 1000")
print("graph_vlabel bits in (-) / out (+) per \${graph_period}")
print("graph_category network")
print("graph_order down up maxdown maxup")
print("down.label received")
print("down.type DERIVE")
print("down.graph no")
print("down.cdef down,8,*")
print("down.min 0")
print("down.max 1000000000")
print("up.label bps")
print("up.type DERIVE")
print("up.draw AREA")
print("up.cdef up,8,*")
print("up.min 0")
print("up.max 1000000000")
print("up.negative down")
print("up.info Traffic of the WAN interface.")
if not os.environ.get("traffic_remove_max"):
print("maxdown.label received")
print("maxdown.type GAUGE")
print("maxdown.graph no")
print("maxup.label MAX")
print("maxup.type GAUGE")
print("maxup.negative maxdown")
print("maxup.draw LINE1")
print("maxup.info Maximum speed of the WAN interface.")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print "yes" # Some docs say it'll be called with fetch, some say no arg at all
elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == 'fetch'):
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes") # Some docs say it'll be called with fetch, some say no arg at all
elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == "fetch"):
try:
print_values()
except:

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_uptime - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,58 +9,74 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import json
import os
import re
import sys
import fritzbox_helper as fh
PAGE = '/system/energy.lua'
pattern = re.compile(".*/(.*uptime_\w+?)\".*=.*\"(.*?)\"")
locale = os.environ.get("locale", "de")
patternLoc = {"de": r"(\d+)\s(Tag|Stunden|Minuten)", "en": r"(\d+)\s(days|hours|minutes)"}
dayLoc = {"de": "Tag", "en": "days"}
hourLoc = {"de": "Stunden", "en": "hours"}
minutesLoc = {"de": "Minuten", "en": "minutes"}
PAGE = "energy"
pattern = re.compile(patternLoc[locale])
def get_uptime():
"""get the current uptime"""
server = os.environ['fritzbox_ip']
password = os.environ['fritzbox_password']
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
sid = fh.get_sid(server, password)
data = fh.get_page(server, sid, PAGE)
matches = re.finditer(pattern, data)
if matches:
hours = 0.0
for m in matches:
if m.group(1) == "uptime_hours":
hours += int(m.group(2))
if m.group(1) == "uptime_minutes":
hours += int(m.group(2)) / 60.0
uptime = hours / 24
print "uptime.value %.2f" % uptime
session_id = fh.get_session_id(server, username, password)
xhr_data = fh.get_xhr_content(server, session_id, PAGE)
data = json.loads(xhr_data)
for d in data["data"]["drain"]:
if "aktiv" in d["statuses"]:
matches = re.finditer(pattern, d["statuses"])
if matches:
hours = 0.0
for m in matches:
if m.group(2) == dayLoc[locale]:
hours += 24 * int(m.group(1))
if m.group(2) == hourLoc[locale]:
hours += int(m.group(1))
if m.group(2) == minutesLoc[locale]:
hours += int(m.group(1)) / 60.0
uptime = hours / 24
print("uptime.value %.2f" % uptime)
def print_config():
print "graph_title AVM Fritz!Box Uptime"
print "graph_args --base 1000 -l 0"
print 'graph_vlabel uptime in days'
print "graph_scale no'"
print "graph_category system"
print "uptime.label uptime"
print "uptime.draw AREA"
print("graph_title AVM Fritz!Box Uptime")
print("graph_args --base 1000 -l 0")
print("graph_vlabel uptime in days")
print("graph_scale no'")
print("graph_category system")
print("uptime.label uptime")
print("uptime.draw AREA")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print 'yes'
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == 'fetch':
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes")
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == "fetch":
# Some docs say it'll be called with fetch, some say no arg at all
try:
get_uptime()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
fritzbox_wifi_devices - A munin plugin for Linux to monitor AVM Fritzbox
Copyright (C) 2015 Christian Stade-Schuldt
@ -9,54 +9,63 @@
[fritzbox_*]
env.fritzbox_ip [ip address of the fritzbox]
env.fritzbox_username [fritzbox username]
env.fritzbox_password [fritzbox password]
This plugin supports the following munin configuration parameters:
#%# family=auto contrib
#%# capabilities=autoconf
"""
import json
import os
import re
import sys
import fritzbox_helper as fh
PAGE = '/system/energy.lua'
pattern = re.compile("(\d+) WLAN")
locale = os.environ.get("locale", "de")
patternLoc = {"de": r"(\d+) WLAN", "en": r"(\d+) wireless LAN"}
PAGE = "energy"
pattern = re.compile(patternLoc[locale])
def get_connected_wifi_devices():
"""gets the numbrer of currently connected wifi devices"""
server = os.environ['fritzbox_ip']
password = os.environ['fritzbox_password']
server = os.environ["fritzbox_ip"]
username = os.environ["fritzbox_username"]
password = os.environ["fritzbox_password"]
sid = fh.get_sid(server, password)
data = fh.get_page(server, sid, PAGE)
m = re.search(pattern, data)
session_id = fh.get_session_id(server, username, password)
xhr_data = fh.get_xhr_content(server, session_id, PAGE)
data = json.loads(xhr_data)
m = re.search(pattern, data["data"]["drain"][2]["statuses"][-1])
if m:
connected_devices = int(m.group(1))
print 'wifi.value %d' % connected_devices
print("wifi.value %d" % connected_devices)
def print_config():
print 'graph_title AVM Fritz!Box Connected Wifi Devices'
print 'graph_vlabel Number of devices'
print 'graph_args --base 1000'
print 'graph_category network'
print 'graph_order wifi'
print 'wifi.label Wifi Connections on 2.4 & 5 Ghz'
print 'wifi.type GAUGE'
print 'wifi.graph LINE1'
print 'wifi.info Wifi Connections on 2.4 & 5 Ghz'
print("graph_title AVM Fritz!Box Connected Wifi Devices")
print("graph_vlabel Number of devices")
print("graph_args --base 1000")
print("graph_category network")
print("graph_order wifi")
print("wifi.label Wifi Connections on 2.4 & 5 Ghz")
print("wifi.type GAUGE")
print("wifi.graph LINE1")
print("wifi.info Wifi Connections on 2.4 & 5 Ghz")
if os.environ.get("host_name"):
print("host_name " + os.environ["host_name"])
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "config":
print_config()
elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf':
print 'yes'
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == 'fetch':
elif len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print("yes")
elif len(sys.argv) == 1 or len(sys.argv) == 2 and sys.argv[1] == "fetch":
# Some docs say it'll be called with fetch, some say no arg at all
try:
get_connected_wifi_devices()

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
fritzconnection
lxml
requests