Last active
April 1, 2020 19:56
-
-
Save lassem/7b6612d325976802c19e8e519f26ced4 to your computer and use it in GitHub Desktop.
ABB Free@Home getall.xml parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import xml.etree.ElementTree as ET | |
import json | |
f = open('mastermessage.xml', 'r', encoding="utf-8") | |
root = ET.parse(f) | |
functions = {} | |
strings = {} | |
devices = {} | |
channelDescriptions = {} | |
def findName(nameId): | |
sid = int(nameId, 16) | |
return strings[sid] if sid in strings else None | |
def findFunction(functionId): | |
fid = int(functionId, 16) | |
return functions[fid] if fid in functions else None | |
def findFunctions(elm): | |
functions = [] | |
for f in elm.findall('functions/function') or []: | |
function = findFunction(f.attrib['functionId']) | |
functions.append(function) | |
return functions | |
def decorateInputDataPoints(cid, dataPoints): | |
description = channelDescriptions[cid] | |
for index, dp in enumerate(description.findall('inputs/dataPoint')): | |
i = f"idp{index:04x}" | |
dataPoint = dataPoints.get(i, {}) | |
dataPoint['pairingId'] = int(dp.attrib['pairingId'], 16) | |
dataPoint['name'] = findName(dp.attrib.get('nameId', '0')) | |
dataPoints[i] = dataPoint | |
def decorateOutputDataPoints(cid, dataPoints): | |
description = channelDescriptions[cid] | |
for index, dp in enumerate(description.findall('outputs/dataPoint')): | |
i = f"odp{index:04x}" | |
dataPoint = dataPoints.get(i, {}) | |
dataPoint['pairingId'] = int(dp.attrib['pairingId'], 16) | |
dataPoint['name'] = findName(dp.attrib.get('nameId', '0')) | |
dataPoints[i] = dataPoint | |
### MAIN | |
for string in root.find('strings'): | |
sid = int(string.attrib['nameId'], 16) | |
strings[sid] = string.text | |
for function in root.find('definitions/functions'): | |
fid = int(function.attrib['functionId'], 16) | |
functions[fid] = {} | |
functions[fid]['functionId'] = fid | |
functions[fid]['description'] = findName(function.attrib['nameId']) | |
if ('name' in function.attrib): | |
functions[fid]['name'] = function.attrib['name'] | |
for elm in root.iterfind('descriptions/channel'): | |
cid = elm.attrib['cid'] | |
channelDescriptions[cid] = elm | |
for device in root.find('devices'): | |
serial = device.attrib['serialNumber'] | |
devices[serial] = {} | |
devices[serial]['serial'] = serial | |
devices[serial]['description'] = findName(device.attrib['nameId']) | |
devices[serial]['function'] = functions[int(device.attrib['functionId'], 16)] | |
devices[serial]['channels'] = {} | |
for channel in device.find('channels') or []: | |
def findFunctionId(elm): | |
for child in elm.findall('attribute'): | |
if 'name' in child.attrib and child.attrib['name'] == 'functionId': | |
return int(child.text, 16) | |
return None | |
def findFunctionForId(elm): | |
for child in elm.findall('attribute'): | |
if 'name' in child.attrib and child.attrib['name'] == 'functionId': | |
return findFunction(child.text) | |
return None | |
i = channel.attrib['i'] | |
cid = channel.attrib['cid'] | |
devices[serial]['channels'][i] = {} | |
devices[serial]['channels'][i]['cid'] = cid | |
devices[serial]['channels'][i]['function'] = findFunctionForId(channel) | |
devices[serial]['channels'][i]['input'] = {} | |
devices[serial]['channels'][i]['output'] = {} | |
for dataPoint in channel.findall('inputs/dataPoint'): | |
dp = {} | |
dpi = dataPoint.attrib['i'] | |
dp['value'] = dataPoint.find('value').text | |
devices[serial]['channels'][i]['input'][dpi] = dp | |
decorateInputDataPoints(cid, devices[serial]['channels'][i]['input']) | |
for dataPoint in channel.findall('outputs/dataPoint'): | |
dp = {} | |
dpi = dataPoint.attrib['i'] | |
dp['value'] = dataPoint.find('value').text | |
devices[serial]['channels'][i]['output'][dpi] = dp | |
decorateOutputDataPoints(cid, devices[serial]['channels'][i]['output']) | |
for device in devices: | |
print(json.dumps(devices[device], sort_keys=False, indent=4)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment