- Mitglied seit
- 22 Sep 2007
- Beiträge
- 49
- Punkte für Reaktionen
- 7
- Punkte
- 8
Anbei ein schmales Python Script zum Auslesen der SmartHome Geräte über das AVM Home Automation HTTP Interface (AHA HTTP Interface). Die Anmeldung erfolgt per MD5 oder PBKDF2 Methode. Für das Auslesen reichen Benutzerrechte "SmartHome" aus.
Das Script zeigt aktuell nur Details für Heizkörperregler, Schaltaktoren und Taster an. Weitere Geräte müssten mit Anpassung weiterer IF-Abfragen ergänzt werden. "Getdevicelistinfos" übermittelt auch Geräteinformationen von den Geräten, die am FRITZ!Smart Gateway angemeldeten sind.
Beschreibung:
Das Script zeigt aktuell nur Details für Heizkörperregler, Schaltaktoren und Taster an. Weitere Geräte müssten mit Anpassung weiterer IF-Abfragen ergänzt werden. "Getdevicelistinfos" übermittelt auch Geräteinformationen von den Geräten, die am FRITZ!Smart Gateway angemeldeten sind.
Python:
#!/usr/bin/env python3
#Import
import requests, hashlib, re
# URL der Fritzbox
fritzbox_url = "http://192.168.178.1"
# Benutzername
Username = "User"
# Passwort
Password = "123456"
# Anmeldemethode
#version=1 ist MD5
#version=2 ist PBKDF2
version = 2
# Linie ziehen
print ("------------------------------------------------------------------------")
# Anmeldemethode mit PBKDF2
# ==========================================================================================================================
if version == 2:
#Payload erzeugen
request_payload = {'version': '2'}
# Anfrage starten
request_result = requests.get(fritzbox_url + "/login_sid.lua", params=request_payload)
# Zum Debuggen, alles Ausgeben
#print (request_result.text)
# Daten herausfiltern
SID = str((request_result.text).split("<SID>")[1].split("</SID>")[0])
BlockTime = int((request_result.text).split("<BlockTime>")[1].split("</BlockTime>")[0])
Challenge = str((request_result.text).split("<Challenge>")[1].split("</Challenge>")[0])
if SID == '0000000000000000':
# SID ist 0, daher Response Erzeugen und neu anfordern: Berechnung mit PBKDF2
Challenge_split = Challenge.split("$")
#notused = int(Challenge_split[0])
iter1 = int(Challenge_split[1])
salt1 = bytes.fromhex(Challenge_split[2])
iter2 = int(Challenge_split[3])
salt2 = bytes.fromhex(Challenge_split[4])
hash1 = hashlib.pbkdf2_hmac("sha256", Password.encode(), salt1, iter1)
hash2 = hashlib.pbkdf2_hmac("sha256", hash1, salt2, iter2)
Response = Challenge_split[4] + "$" + hash2.hex()
# Daten erstellen für POST
request_data = {"username": Username, "response": Response}
# Header erstellen
request_headers = {"Content-Type": "application/x-www-form-urlencoded"}
# Und Daten anfordern
request_result = requests.post(fritzbox_url + "/login_sid.lua", data=request_data, headers=request_headers)
# Zum Debuggen, alles Ausgeben
#print (request_result.text)
SID = str((request_result.text).split("<SID>")[1].split("</SID>")[0])
BlockTime = int((request_result.text).split("<BlockTime>")[1].split("</BlockTime>")[0])
Name = str((request_result.text).split("<Name>")[1].split("</Name>")[0])
Access = int((request_result.text).split("<Access>")[1].split("</Access>")[0])
# Ausgabe der einzelnen Variablen
print ("Challenge: ",Challenge)
print ("Response: ",Response)
print ("SID: ",SID)
print ("BlockTime: ",BlockTime)
print ("Name: ",Name)
print ("Access: ",Access)
else:
# Ausgabe der einzelnen Variablen
print ("SID: ",SID)
print ("BlockTime: ",BlockTime)
# Anmeldemethode mit MD5
# ==========================================================================================================================
if version == 1:
#Payload erzeugen
request_payload = {'version': '1'}
# Anfrage starten
request_result = requests.get(fritzbox_url + "/login_sid.lua", params=request_payload)
# Zum Debuggen, alles Ausgeben
#print (request_result.text)
# Daten herausfiltern
SID = str((request_result.text).split("<SID>")[1].split("</SID>")[0])
BlockTime = int((request_result.text).split("<BlockTime>")[1].split("</BlockTime>")[0])
Challenge = str((request_result.text).split("<Challenge>")[1].split("</Challenge>")[0])
if SID == '0000000000000000':
# SID ist 0, daher Response Erzeugen und neu anfordern: Berechnung mit MD5
MD5 = hashlib.md5((Challenge + "-" + Password).encode("utf_16_le")).hexdigest()
Response = Challenge + "-" + MD5
# Daten erstellen für POST
request_data = {"username": Username, "response": Response}
# Header erstellen
request_headers = {"Content-Type": "application/x-www-form-urlencoded"}
# Und Daten anfordern
request_result = requests.post(fritzbox_url + "/login_sid.lua", data=request_data, headers=request_headers)
# Zum Debuggen, alles Ausgeben
#print (request_result.text)
SID = str((request_result.text).split("<SID>")[1].split("</SID>")[0])
BlockTime = int((request_result.text).split("<BlockTime>")[1].split("</BlockTime>")[0])
Name = str((request_result.text).split("<Name>")[1].split("</Name>")[0])
Access = int((request_result.text).split("<Access>")[1].split("</Access>")[0])
# Ausgabe der einzelnen Variablen
print ("Challenge: ",Challenge)
print ("MD5: ",MD5)
print ("Response: ",Response)
print ("SID: ",SID)
print ("BlockTime: ",BlockTime)
print ("Name: ",Name)
print ("Access: ",Access)
else:
# Ausgabe der einzelnen Variablen
print ("SID: ",SID)
print ("BlockTime: ",BlockTime)
# Getdevicelistinfos
# ==========================================================================================================================
# Linie ziehen
print ("------------------------------------------------------------------------")
# Payload erzeugen
request_payload = {'switchcmd': 'getdevicelistinfos', 'sid': SID}
# Und Daten anfordern
request_result = requests.get(fritzbox_url + "/webservices/homeautoswitch.lua", params=request_payload)
# Zum Debuggen, alles Ausgeben
#print (request_result.text)
# Teile die devices in einzelne Abschnitte
request_result_split_array = re.findall("<device (.*?)</device>", request_result.text)
for i, request_result_split in enumerate(request_result_split_array):
# Ausgabe der einzelnen Variablen
#print (request_result_split)
device_ain = str((request_result_split).split('identifier="')[1].split('" id=')[0])
device_id = int((request_result_split).split('id="')[1].split('" functionbitmask=')[0])
device_function_bitmask = int((request_result_split).split('functionbitmask="')[1].split('" fwversion=')[0])
device_firmware = str((request_result_split).split('" fwversion="')[1].split('" manufacturer=')[0])
device_manufacturer = str((request_result_split).split('manufacturer="')[1].split('" productname=')[0])
device_product_name = str((request_result_split).split('productname="')[1].split('"><present>')[0])
device_device_name = str((request_result_split).split("<name>")[1].split("</name>")[0])
device_present = str((request_result_split).split("<present>")[1].split("</present>")[0])
device_busy = str((request_result_split).split("<txbusy>")[1].split("</txbusy>")[0])
# Ausgabe der einzelnen Variablen
print ("AIN: ",device_ain)
print ("ID: ",device_id)
print ("Function bitmask: ",device_function_bitmask)
print ("Firmware version: ",device_firmware)
print ("Manufacturer: ",device_manufacturer)
print ("Product name: ",device_product_name)
print ("Device name: ",device_device_name)
print ("Present?: ",device_present)
print ("TX busy: ",device_busy)
# ab hier unvollstaendig: nur Heizkoerperregler, Schaltaktor, Taster. Andere Geraete ergaenzen...
if "<hkr>" in request_result_split:
device_battery = int((request_result_split).split("<battery>")[1].split("</battery>")[0])
device_batterylow = str((request_result_split).split("<batterylow>")[1].split("</batterylow>")[0])
device_temperature_celsius = float((request_result_split).split("<celsius>")[1].split("</celsius>")[0])/10
device_temperature_offset = float((request_result_split).split("<offset>")[1].split("</offset>")[0])/10
#Temperatur-Wert in 0,5 °C, Wertebereich: 16 – 56 -> 8 bis 28°C, z.B.: 16 <= 8°C, 17 = 8,5°C...... 56 >= 28°C, 254 = ON , 253 = OFF
device_hkr_set = float((request_result_split).split("<tsoll>")[1].split("</tsoll>")[0])/2
device_hkr_is = float((request_result_split).split("<tist>")[1].split("</tist>")[0])/2
device_hkr_absenk = float((request_result_split).split("<absenk>")[1].split("</absenk>")[0])/2
device_hkr_komfort = float((request_result_split).split("<komfort>")[1].split("</komfort>")[0])/2
device_hkr_lock = int((request_result_split).split("<lock>")[1].split("</lock>")[0])
device_hkr_devicelock = int((request_result_split).split("<devicelock>")[1].split("</devicelock>")[0])
device_hkr_errorcode = int((request_result_split).split("<errorcode>")[1].split("</errorcode>")[0])
device_hkr_windowopenactiv = int((request_result_split).split("<windowopenactiv>")[1].split("</windowopenactiv>")[0])
device_hkr_windowopenactiveendtime = int((request_result_split).split("<windowopenactiveendtime>")[1].split("</windowopenactiveendtime>")[0])
device_hkr_boostactive = int((request_result_split).split("<boostactive>")[1].split("</boostactive>")[0])
device_hkr_boostactiveendtime = int((request_result_split).split("<boostactiveendtime>")[1].split("</boostactiveendtime>")[0])
device_hkr_endperiod = int((request_result_split).split("<endperiod>")[1].split("</endperiod>")[0])
device_hkr_tchange = int((request_result_split).split("<tchange>")[1].split("</tchange>")[0])
device_hkr_summeractive = int((request_result_split).split("<summeractive>")[1].split("</summeractive>")[0])
device_hkr_adaptiveHeatingActive = int((request_result_split).split("<adaptiveHeatingActive>")[1].split("</adaptiveHeatingActive>")[0])
device_hkr_adaptiveHeatingRunning = int((request_result_split).split("<adaptiveHeatingRunning>")[1].split("</adaptiveHeatingRunning>")[0])
print ("Type: HKR")
print ("Battery: ",device_battery,"%")
print ("Battery low?: ",device_batterylow)
print ("Temperature: ",device_temperature_celsius,"°C")
print ("Temperature offset: ",device_temperature_offset,"°C")
print ("Temperature set: ",device_hkr_set,"°C")
print ("Temperature is: ",device_hkr_is,"°C")
print ("Temperature lowering: ",device_hkr_absenk,"°C")
print ("Temperature comfort: ",device_hkr_komfort,"°C")
print ("HKR lock: ",device_hkr_lock)
print ("HKR devicelock: ",device_hkr_devicelock)
print ("HKR error: ",device_hkr_errorcode)
print ("HKR Window open: ",device_hkr_windowopenactiv)
print ("HKR Window open timer:",device_hkr_windowopenactiveendtime)
print ("HKR Boost active: ",device_hkr_boostactive)
print ("HKR Boost time: ",device_hkr_boostactiveendtime)
print ("HKR endperiod: ",device_hkr_endperiod)
print ("HKR temp change: ",device_hkr_tchange)
print ("HKR summer active: ",device_hkr_summeractive)
print ("HKR adapt heating on: ",device_hkr_adaptiveHeatingActive)
print ("HKR adapt heating run:",device_hkr_adaptiveHeatingRunning)
if "<button " in request_result_split:
device_battery = int((request_result_split).split("<battery>")[1].split("</battery>")[0])
device_batterylow = str((request_result_split).split("<batterylow>")[1].split("</batterylow>")[0])
print ("Type: Button")
print ("Battery: ",device_battery,"%")
print ("Battery low?: ",device_batterylow)
if "<switch>" in request_result_split:
device_switch_state = int((request_result_split).split("<state>")[1].split("</state>")[0])
device_switch_mode = str((request_result_split).split("<mode>")[1].split("</mode>")[0])
device_switch_lock = int((request_result_split).split("<lock>")[1].split("</lock>")[0])
device_switch_devicelock = int((request_result_split).split("<devicelock>")[1].split("</devicelock>")[0])
device_simpleonoff_state = int((request_result_split).split("<devicelock>")[1].split("</devicelock>")[0])
device_powermeter_voltage = float((request_result_split).split("<voltage>")[1].split("</voltage>")[0])/1000
device_powermeter_power = float((request_result_split).split("<power>")[1].split("</power>")[0])/1000
device_powermeter_energy = float((request_result_split).split("<energy>")[1].split("</energy>")[0])/1000
device_temperature_celsius = float((request_result_split).split("<celsius>")[1].split("</celsius>")[0])/10
device_temperature_offset = float((request_result_split).split("<offset>")[1].split("</offset>")[0])/10
print ("Type: Switch")
print ("Switch state: ",device_switch_state)
print ("Switch mode: ",device_switch_mode)
print ("Switch lock: ",device_switch_lock)
print ("Switch devicelock: ",device_switch_devicelock)
print ("Simple on/off state: ",device_simpleonoff_state)
print ("Powermeter voltage: ",device_powermeter_voltage,"V")
print ("Powermeter power: ",device_powermeter_power,"W")
print ("Powermeter energy: ",device_powermeter_energy,"kWh")
print ("Temperature: ",device_temperature_celsius,"°C")
print ("Temperature offset ",device_temperature_offset,"°C")
# Linie ziehen
print ("------------------------------------------------------------------------")
#Ende
# ==========================================================================================================================
Beschreibung: