Skip to content

Commit cd25a54

Browse files
committed
wip: add demo
1 parent d076137 commit cd25a54

File tree

6 files changed

+244
-208
lines changed

6 files changed

+244
-208
lines changed

demo/index.html

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<!DOCTYPE html>
2+
<title>OpenSCD Core Demo</title>
3+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300&family=Roboto:wght@300;400;500&display=swap">
4+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons&display=block">
5+
<label for="scl1">SCL file 1</label>
6+
<input type="file" id="scl1" name="scl1" accept="application/xml" />
7+
8+
<hr>
9+
10+
<div id="result">
11+
</div>
12+
13+
<script type="module">
14+
import { newHasher } from '../dist/hash.js';
15+
16+
const scl1 = document.getElementById('scl1');
17+
const result = document.getElementById('result');
18+
19+
const { hash, db } = newHasher();
20+
21+
function display(description) {
22+
console.log('displaying', description);
23+
const elements = [];
24+
Object.entries(description).forEach(([key, value]) => {
25+
if (key.startsWith('@')) {
26+
const tag = key.substring(1);
27+
for (const hash of value) {
28+
const det = document.createElement('details');
29+
const sum = document.createElement('summary');
30+
det.append(sum);
31+
const d = db[tag][hash];
32+
sum.textContent = tag + ' ' + hash;
33+
det.addEventListener('toggle', () => {if (det.children.length < 2) det.append(...display(db[tag][hash]))})
34+
elements.push(det);
35+
}
36+
} else if ( key === 'eNS') {
37+
const det = document.createElement('details');
38+
const sum = document.createElement('summary');
39+
det.append(sum);
40+
sum.textContent = 'extension NS';
41+
Object.entries(value).forEach(([ns, attrs]) => {
42+
const de = document.createElement('details');
43+
const su = document.createElement('summary');
44+
de.append(su);
45+
su.textContent = ns;
46+
Object.entries(attrs).forEach(([a,v]) => {
47+
const attr = document.createElement('div');
48+
attr.setAttribute('class','column');
49+
attr.textContent = a
50+
de.append(attr);
51+
const val = document.createElement('div');
52+
val.setAttribute('class','column');
53+
val.textContent = v
54+
de.append(val);
55+
})
56+
})
57+
} else {
58+
const attr = document.createElement('div');
59+
attr.setAttribute('class','column');
60+
attr.textContent = key
61+
elements.push(attr);
62+
const val = document.createElement('div');
63+
val.setAttribute('class','column');
64+
val.textContent = value
65+
elements.push(val);
66+
}
67+
})
68+
return elements;
69+
}
70+
71+
scl1.addEventListener('change', e => {
72+
for (const file of scl1.files) {
73+
file.text().then(text => {
74+
console.log(hash(new DOMParser().parseFromString(text, 'application/xml').documentElement))
75+
Object.entries(db.SCL).forEach(([sclHash, description]) => {
76+
const details = document.createElement('details');
77+
const summary = document.createElement('summary');
78+
details.setAttribute('open', '')
79+
details.append(summary);
80+
summary.textContent = 'SCL ' + sclHash;
81+
Object.entries(description).forEach(([key, value]) => {
82+
if (key.startsWith('@')) {
83+
const tag = key.substring(1);
84+
for (const hash of value) {
85+
const det = document.createElement('details');
86+
const sum = document.createElement('summary');
87+
det.append(sum);
88+
sum.textContent = tag + ' ' + hash;
89+
det.addEventListener('toggle', () => {console.log('toggled!'); if (det.children.length < 2) det.append(...display(db[tag][hash]))})
90+
details.append(det);
91+
}
92+
} else if ( key === 'eNS') {
93+
const det = document.createElement('details');
94+
const sum = document.createElement('summary');
95+
det.append(sum);
96+
sum.textContent = 'extension NS';
97+
Object.entries(value).forEach(([ns, attrs]) => {
98+
const de = document.createElement('details');
99+
const su = document.createElement('summary');
100+
de.append(su);
101+
su.textContent = ns;
102+
Object.entries(attrs).forEach(([a,v]) => {
103+
const attr = document.createElement('div');
104+
attr.setAttribute('class','column');
105+
attr.textContent = a
106+
de.append(attr);
107+
const val = document.createElement('div');
108+
val.setAttribute('class','column');
109+
val.textContent = v
110+
de.append(val);
111+
})
112+
})
113+
} else {
114+
const attr = document.createElement('div');
115+
attr.setAttribute('class','column');
116+
attr.textContent = key
117+
details.append(attr);
118+
const val = document.createElement('div');
119+
val.setAttribute('class','column');
120+
val.textContent = value
121+
details.append(val);
122+
}
123+
})
124+
result.append(details);
125+
})
126+
})
127+
}
128+
});
129+
</script>
130+
131+
<style>
132+
body {
133+
background: #ccc;
134+
color: #222;
135+
font-family: Roboto;
136+
font-weight: 300;
137+
}
138+
.column {
139+
max-width: 49%;
140+
min-width: 34%;
141+
display: inline-block;
142+
padding: 4px;
143+
opacity: 0.8;
144+
vertical-align: middle;
145+
border: 1px #ccc solid;
146+
border-radius: 6px;
147+
}
148+
.column:nth-of-type(2n+1) {
149+
text-align: right;
150+
}
151+
.removed {
152+
background: lightcoral;
153+
}
154+
.changed {
155+
background: gold;
156+
}
157+
.added {
158+
background: lightgreen;
159+
}
160+
details {
161+
padding: 4px;
162+
}
163+
summary {
164+
font-weight: 400;
165+
}
166+
</style>

describe/DAType.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe("Description for SCL schema element DAType", () => {
4444
});
4545

4646
it("returns property bdas recording BDA child elements", () =>
47-
expect(DAType(baseDAType).bdas["mag"]).to.satisfy(
47+
expect(DAType(baseDAType).bdas.mag).to.satisfy(
4848
isAbstractDataAttributeDescription,
4949
));
5050

hash.spec.ts

Lines changed: 7 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ const baseEnumType = testScl.querySelector("#someID")!;
149149
// const diffEnumType = testScl.querySelector("#someDiffID")!;
150150
// const equalEnumType = testScl.querySelector("#someOtherID")!;
151151

152-
const baseDAType = testScl.querySelector("#someBaseDAType")!;
153-
const baseDOType = testScl.querySelector("#someBaseDOType")!;
154-
const baseLNodeType = testScl.querySelector("#baseLLN0")!;
152+
// const baseDAType = testScl.querySelector("#someBaseDAType")!;
153+
// const baseDOType = testScl.querySelector("#someBaseDOType")!;
154+
// const baseLNodeType = testScl.querySelector("#baseLLN0")!;
155155

156156
// const baseIED = testScl.querySelector(`IED[name="IED1"]`)!;
157157
// const equalIED = testScl.querySelector(`IED[name="IED2"]`)!;
@@ -189,203 +189,14 @@ describe("hasher", () => {
189189
);
190190
});
191191

192-
it("hashes DATypes by BDAs and ProtNs", () => {
193-
hash(baseDAType);
194-
/*
195-
const digest = hash(baseDAType);
196-
const description = db.DAType[digest] as Record<string, string[]>;
197-
expect(description).to.deep.equal({
198-
// FIXME(ca-d): define correct behaviour
199-
"@BDA": ["18d6c93b2cc1cc55", "dd9f5c7e69b1708c"],
200-
"@ProtNs": ["4fd2d8f99b2f756a"],
201-
});
202-
*/
203-
// TODO(ca-d): test siblingCount
204-
});
205-
206-
it("hashes DOTypes by DAs and SDOs", () => {
207-
hash(baseDOType);
208-
/*
209-
const digest = hash(baseDOType);
210-
const description = db.DOType[digest] as Record<string, string[]>;
211-
expect(description).to.deep.equal({
212-
// FIXME(ca-d): define correct behaviour
213-
"@DA": ["74871b9108bd5768"],
214-
cdc: "SPS",
215-
});
216-
*/
217-
});
218-
219-
it("hashes LNodeTypes by DOs", () => {
220-
hash(baseLNodeType);
221-
/*
222-
const digest = hash(baseLNodeType);
223-
const description = db.LNodeType[digest] as Record<string, string[]>;
224-
expect(description).to.deep.equal({
225-
// FIXME(ca-d): define correct behaviour
226-
"@DO": ["4c6e42c7c8b0797f"],
227-
lnClass: "LLN0",
228-
});
229-
*/
230-
});
231-
232-
it("hashes LNodeTypes by DOs", () => {
233-
hash(testScl.querySelector("DataTypeTemplates")!);
234-
});
235-
236192
after(() => {
237-
/* // primivite snapshot test - uncomment to update
193+
/*
194+
console.log(
195+
Array.from(testScl.querySelectorAll("IED")).map((ied) => hash(ied)),
196+
);
238197
Object.keys(db).forEach((key) => {
239198
console.log('expect(db["' + key + '"]).to.deep.equal(', db[key], ")");
240199
});
241200
*/
242-
expect(db["SomeNonSCLElement@http://somevalidURI"]).to.deep.equal({
243-
b6712fb57eb0e24b: {
244-
xml: '<ens:SomeNonSCLElement xmlns:ens="http://somevalidURI"/>',
245-
},
246-
});
247-
expect(db.Private).to.deep.equal({
248-
"082c018bb12fb5e5": {
249-
xml:
250-
'<Private xmlns="http://www.iec.ch/61850/2003/SCL" type="someType" desc="someDesc" xmlns:sxy="http://www.iec.ch/61850/2003/SCLcoordinates" sxy:x="10" xmlns:ens="http://somevalidURI" ens:some="someOtherNameSpace">\n' +
251-
" <![CDATA[some comment]]>\n" +
252-
' <IED name="somePrivateIED"/>\n' +
253-
" </Private>",
254-
},
255-
"878b5b8db7dc9340": {
256-
xml:
257-
'<Private xmlns="http://www.iec.ch/61850/2003/SCL" type="someType" desc="someDesc" xmlns:ens="http://somevalidURI" ens:some="someOtherNameSpace" xmlns:sxy="http://www.iec.ch/61850/2003/SCLcoordinates" sxy:x="10">\n' +
258-
" <![CDATA[some comment]]>\n" +
259-
' <IED name="somePrivateIED"/>\n' +
260-
" </Private>",
261-
},
262-
});
263-
expect(db.Text).to.deep.equal({
264-
"6e995d62cc5f8f1a": {
265-
xml: '<Text xmlns="http://www.iec.ch/61850/2003/SCL">Some detailed description</Text>',
266-
},
267-
});
268-
expect(db.EnumVal).to.deep.equal({
269-
"8f561e2a03513559": { ord: 1, val: "A" },
270-
"25599d957ef37857": { ord: -1, val: "SomeContent" },
271-
ef0565086e00a6e5: { ord: 13, val: "SomeOtherContent" },
272-
"7332c15a44952cce": { ord: -23, val: "" },
273-
"728b4a0f4332e9c5": { ord: 1, val: "" },
274-
});
275-
expect(db.EnumType).to.deep.equal({
276-
c2541301f8126d77: {
277-
"@Private": ["082c018bb12fb5e5"],
278-
"@Text": ["6e995d62cc5f8f1a"],
279-
"@ens:SomeNonSCLElement": ["b6712fb57eb0e24b"],
280-
"@EnumVal": ["8f561e2a03513559"],
281-
},
282-
"52e71c8529bf548f": {
283-
"@EnumVal": [
284-
"25599d957ef37857",
285-
"7332c15a44952cce",
286-
"ef0565086e00a6e5",
287-
],
288-
},
289-
"01bfdeb82adbbab3": {
290-
"@Private": ["878b5b8db7dc9340"],
291-
"@Text": ["6e995d62cc5f8f1a"],
292-
"@ens:SomeNonSCLElement": ["b6712fb57eb0e24b"],
293-
"@EnumVal": ["728b4a0f4332e9c5"],
294-
},
295-
});
296-
expect(db.Val).to.deep.equal({
297-
"4841a3d87b04aa9b": { val: "45.00", sGroup: 1 },
298-
"0fc915000247dd52": { val: "65.00", sGroup: 2 },
299-
});
300-
expect(db.BDA).to.deep.equal({
301-
a99636321898296f: {
302-
"@Val": ["0fc915000247dd52", "4841a3d87b04aa9b"],
303-
bType: "FLOAT32",
304-
valImport: true,
305-
valKind: "RO",
306-
count: 0,
307-
},
308-
"017e02f18557b8a3": {
309-
bType: "Struct",
310-
sAddr: "someSAddr",
311-
valKind: "Set",
312-
valImport: false,
313-
count: 0,
314-
"@DAType": ["c579130da5263aca"],
315-
},
316-
"0ad0aa080b280458": {
317-
bType: "Enum",
318-
sAddr: "someSAddr",
319-
valKind: "Set",
320-
valImport: false,
321-
count: 0,
322-
"@EnumType": ["52e71c8529bf548f"],
323-
},
324-
});
325-
expect(db.DAType).to.deep.equal({
326-
c579130da5263aca: {
327-
"@BDA": ["a99636321898296f"],
328-
iedType: "someIedType",
329-
},
330-
d322e88e06132d1b: {
331-
"@BDA": ["017e02f18557b8a3", "0ad0aa080b280458"],
332-
"@ProtNs": ["4fd2d8f99b2f756a"],
333-
},
334-
});
335-
expect(db.ProtNs).to.deep.equal({
336-
"4fd2d8f99b2f756a": { type: "8-MMS", val: "IEC 61850-8-1:2007" },
337-
});
338-
expect(db.DA).to.deep.equal({
339-
d567af79f866336f: {
340-
bType: "Struct",
341-
fc: "ST",
342-
valKind: "Set",
343-
valImport: false,
344-
count: 0,
345-
"@DAType": ["d322e88e06132d1b"],
346-
},
347-
"745036cf3aa59119": {
348-
bType: "Enum",
349-
fc: "ST",
350-
valKind: "Set",
351-
valImport: false,
352-
count: 0,
353-
"@EnumType": ["c2541301f8126d77"],
354-
},
355-
});
356-
expect(db.DOType).to.deep.equal({
357-
"8eaab6c78d2cf143": { cdc: "SPS", "@DA": ["d567af79f866336f"] },
358-
d359de8b7fddee2c: { cdc: "SPS", "@DA": ["745036cf3aa59119"] },
359-
});
360-
expect(db.DO).to.deep.equal({
361-
"2b5d2e745d7551b4": { "@DOType": ["8eaab6c78d2cf143"] },
362-
"80c83ba21492936c": { "@DOType": ["d359de8b7fddee2c"] },
363-
});
364-
expect(db.LNodeType).to.deep.equal({
365-
"4e0619031232ec6e": { "@DO": ["2b5d2e745d7551b4"], lnClass: "LLN0" },
366-
ef46e239e70ddbc9: { "@DO": ["80c83ba21492936c"], lnClass: "LLN0" },
367-
aeb05f6e8affc23a: { "@DO": ["2b5d2e745d7551b4"], lnClass: "XCBR" },
368-
"99a26557bf1bb276": { "@DO": ["80c83ba21492936c"], lnClass: "XCBR" },
369-
});
370-
expect(db.DataTypeTemplates).to.deep.equal({
371-
bc00e9afa5b7022e: {
372-
"@LNodeType": [
373-
"4e0619031232ec6e",
374-
"4e0619031232ec6e",
375-
"99a26557bf1bb276",
376-
"aeb05f6e8affc23a",
377-
"aeb05f6e8affc23a",
378-
"ef46e239e70ddbc9",
379-
],
380-
"@DOType": ["8eaab6c78d2cf143", "8eaab6c78d2cf143", "d359de8b7fddee2c"],
381-
"@DAType": ["c579130da5263aca", "d322e88e06132d1b", "d322e88e06132d1b"],
382-
"@EnumType": [
383-
"01bfdeb82adbbab3",
384-
"52e71c8529bf548f",
385-
"c2541301f8126d77",
386-
"c2541301f8126d77",
387-
],
388-
},
389-
});
390201
});
391202
});

0 commit comments

Comments
 (0)