forked from kikolobo/homebridge-lutron-homeworks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DbXParser.html
207 lines (172 loc) · 6.02 KB
/
DbXParser.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!DOCTYPE html>
<html>
<head>
<title>JSON Config Generator</title>
</head>
<body>
<h1>Homebridge-Homeworks Configuration Generator</h1>
You will need a HWQS XML File from your Lutron processor.<br>
More info:<a href="https://www.lutron.com/TechnicalDocumentLibrary/HWQS_XML_Extraction_FAQ.pdf">Extraction FAQ</a><br>
<hr><br>
Type the following information in the fields before you load the XML file.<br>
NOTE: No validation will be performed.
<br><br>
Host Address: <input type="text" id="host" value=""> <br>
Port: <input type="text" id="port" value=""> <br>
Username: <input type="text" id="username" value=""> <br>
Password: <input type="text" id="password" value=""> <br>
Device name should include Area? <input type="checkbox" id="includeAreaName" checked="true"><br><br>
Config name changes also changes HK? <input type="checkbox" id="updateHomeKitName" checked="true"><br><br>
Lutron DbXmInfo.xml File: <input type="file" name="inputfile"
id="inputfile" onclick="getFile()"> <br><br>
JSON Text will be created automatically below after loading the XML file.<br>Copy & Paste text to the JSON settings in HomeBridge. Replace the whole platform block that belongs to the Homeworks integration.
<hr>
<div id="errors"> </div>
<div id="output"> </div>
<script type="text/javascript">
console.log("Here....");
</script>
</body>
</html>
<script type='text/javascript' src='https://code.jquery.com/jquery-3.5.1.min.js'></script>
<script type='text/javascript' src="https://cdn.rawgit.com/abdmob/x2js/master/xml2json.js"></script>
<script type="text/javascript">
function getFile() {
document.getElementById('inputfile')
.addEventListener('change', function() {
var fr=new FileReader();
fr.onload=function(){
console.log("Readed....");
// document.getElementById('output').textContent=fr.result;
parseXML(fr.result);
}
fr.readAsText(this.files[0]);
});
}
function parseXML(text)
{
var xmlText = $.parseXML(text)
var x2js = new X2JS();
var data = x2js.xml2json(xmlText);
var parsed = walkDBJson( data );
var configObject = {
"host": document.getElementById("host").value,
"apiPort": document.getElementById("port").value,
"username": document.getElementById("username").value,
"password": document.getElementById("password").value,
"updateHomeKitName": document.getElementById("updateHomeKitName").value,
"devices": [],
"platform": "Homeworks",
};
configObject.devices = parsed;
document.getElementById("output").innerHTML = sanitizeHTML(JSON.stringify(configObject,undefined, 4));
}
function noteError(txt) {
document.getElementById("errors").innerHTML = "<p style='color:red'>" + txt + "</p>";
}
// Lutron's XML schema is not public so this is a best-guess. Also
// note that XML->JSON conversion is pretty wacko.
//
// The parsed XML is an object with field:
// HWProject object
//
// The Project object has (among others) field:
// Areas.Area Area or Area[]
//
// The Area object has (among others) fields:
// _Name string
// Rooms Array of Room[]
// Areas Area or Area[]
//
// The Output object has (among others) fields:
// _Name string
// _IntegrationID string
// _OutputType string
//
function walkDBJson(node) {
if (node.HWProject === undefined) {
console.log(node);
noteError("Unable to parse: missing 'HWProject' field");
return [];
}
return walkArea(node.HWProject.Area);
}
function walkArea(areas) {
// Areas is either a single area or an array
if (areas instanceof Array) {
var deviceList = [];
for(var rooms of areas) {
console.log(rooms);
deviceList = deviceList.concat(walkRooms(rooms.Room));
}
return deviceList;
} else {
console.log("NOPE");
}
return null;
}
function walkRooms(rooms) {
if (rooms instanceof Array) {
var deviceList = [];
for(var room of rooms) {
deviceList = deviceList.concat(walkRoom(room));
}
return deviceList;
}else {
console.log("NOPER");
}
return null;
}
function walkRoom(room) {
var deviceList = [];
console.log(room);
if (room.Outputs !== '') {
var x = walkOutputs(room.Outputs.Output, room.Name);
console.log(room.Name);
deviceList = deviceList.concat(x);
}
return deviceList;
}
function walkOutputs(outputs, name) {
if (outputs instanceof Array) {
var deviceList = [];
for (output of outputs) {
console.log(output);
deviceList.push( walkOutput( output, name));
}
return deviceList;
}
return walkOutput(outputs, name);
}
function walkOutput(output, name) {
var deviceName = output.Name;
if (document.getElementById("includeAreaName").checked) {
deviceName = name + " " + output.Name;
}
var fixtureType = "light";
if (output.FixtureType == "Wired QED") {
fixtureType = "shade";
}
var splitDeviceId = output.Address.split(":");
var reconstructedId = '';
for (segment of splitDeviceId) {
console.log(segment);
if (segment.length == 1) {
reconstructedId += `0${segment}:`;
} else {
reconstructedId += `${segment}:`;
}
}
const completeId = reconstructedId.slice(0,-1);
var device = { "name": deviceName,
"integrationID": completeId,
"Type": fixtureType,
"isDimmable": output.Type == "DIMMER"};
return device;
}
function sanitizeHTML(text) {
var element = document.createElement('div');
element.innerText = text;
return element.innerHTML;
}
</script>