1
0
Fork 0

Erste Fassung

This commit is contained in:
Anna Christina Naß 2017-07-11 14:29:20 +02:00
commit dba0ef4a4e
2 changed files with 156 additions and 0 deletions

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# fritz_temperatur
## Allgemein
Dieses Script fragt die Temperatur eines an die FritzBox angeschlossenen Sensors ab.
Getestet wurde es mit einer FritzBox 7390 mit FritzOS 6.83 und einem Comet DECT-Heizkörperregler.
Das Script benötigt folgende Parameter:
-H Hostname oder IP der FritzBox
-U Benutzername zum Einloggen an der FritzBox (z.B. administrator)
-P Das Paßwort des eben genannten Benutzers
-A Die ID des Sensors.
Die Sensor-ID kann man über die Web-Oberfläche der FritzBox abfragen:
- Menü Heimnetz => Smart Home
- Beim gewünschten Sensor auf "Bearbeiten" (Stift-Symbol) klicken
- Die "Identifikationsnummer" ist die benötigte ID. Leerzeichen aus der ID entfernen.
## Voraussetzungen
Das Script ist in Python3 geschrieben und benötigt die folgenden Debian-Pakete:
* python3
* python3-urllib
Getestet wurde mit Debian 8 (Jessie).

127
fritz_temp Executable file
View File

@ -0,0 +1,127 @@
#!/usr/bin/python3
# get target temperature from AVM/Comet Dect Heizkoerperregler (Heating Device)
# need Fritz!OS 6.50+
import getopt
import re
import requests
import sys
import xml.etree.ElementTree as etree
import urllib.parse
from hashlib import md5
DEBUG=False
def OK(text):
print("OK: " + text)
sys.exit()
def Warning(text):
print("WARNING: " + text)
sys.exit()
def Critical(text):
print("CRITICAL: " + text)
sys.exit()
def OptionsError():
Critical("Error: not all required options are given.\n -H <hostname>\n -U <username>\n -P <password>\n -A <ID of device>")
def debug(text):
if DEBUG == True:
print("DEBUG: " + text)
def get_sid(loginurl, username, password):
if not username:
username=''
# get challenge string
response = requests.get(loginurl)
if response.status_code == 200:
tree = etree.fromstring(response.content)
challenge = tree.find("Challenge").text
sid = tree.find("SID").text
debug("challenge: " + challenge)
debug("sid: " + sid)
else:
Critical("Error: GetSid failed")
if len(sid) > 0 and re.search("^0+$", sid) and challenge:
debug("Get new SID")
# sid is null, got challenge
sid = ""
# build password response
pwd = challenge + "-" + password
# UTF-16LE encoding as required
pwd = pwd.encode("UTF-16LE")
# md5hash on top
m = md5()
m.update(pwd)
# final answer string
challenge_response = challenge + "-" + m.hexdigest()
debug("challenge_response: " + challenge_response)
# send to box
url = loginurl + "?username=" + username + "&response=" + challenge_response
response = requests.get(url)
#print(response.content)
# check answer
tree = etree.fromstring(response.content)
sid2 = tree.find("SID").text
debug("SID: " + sid2)
if (len(sid2) > 0) and not re.search("^0+$", sid2):
# is not null, bingo!
return sid2
else:
# use existing sid if sid matches an hex string
if (len(sid) > 0) and re.search("^[0-9a-f]+$", sid):
return sid
host = None
username = None
password = None
ain = None
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], 'H:U:P:A:')
except getopt.GetoptError as err:
OptionsError()
for opt, arg in opts:
if opt == "-H":
host = arg
elif opt == "-U":
username = arg
elif opt == "-P":
password = arg
elif opt == "-A":
ain = arg
if not host or not username or not password or not ain:
OptionsError()
# build urls and login
# - login_sid.lua for fritzos 5.50+
loginurl = "http://" + host + "/login_sid.lua"
ahaurl = "http://" + host + "/webservices/homeautoswitch.lua"
sid = get_sid(loginurl, username, password);
if not sid:
Critical("Error: Login invalid or failed")
#query actual state
rain = urllib.parse.quote(ain)
url = ahaurl + '?ain=' + rain + '&sid=' + sid + '&switchcmd=gettemperature';
http_response = requests.get(url)
if http_response.status_code == 200:
# check answer
answer = http_response.content.decode().strip()
debug("Antwort: " + answer)
temperatur = float(answer) / 10
temp_str = "{0:<3.1f}".format(temperatur)
OK("Temperatur: " + temp_str + " | temp=" + temp_str)
else:
Critical("Error: Query failed.")