Skip to content

Commit 121aa15

Browse files
committed
wip: hash DTT
1 parent 779af85 commit 121aa15

File tree

6 files changed

+475
-8
lines changed

6 files changed

+475
-8
lines changed

.eslintignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@ coverage
33
dist
44
doc
55

6-
**/*.spec.ts
7-
8-
**/*.html
6+
**/*.html

hash.spec.ts

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import { expect } from "chai";
2+
3+
import { newHasher } from "./hash.js";
4+
5+
const testScl = new DOMParser().parseFromString(
6+
`<SCL
7+
xmlns="http://www.iec.ch/61850/2003/SCL"
8+
xmlns:sxy="http://www.iec.ch/61850/2003/SCLcoordinates"
9+
xmlns:ens="http://somevalidURI"
10+
>
11+
<IED name="IED1">
12+
<AccessPoint name="AP1">
13+
<Server>
14+
<Authentication />
15+
<LDevice inst="ldInst1">
16+
<LN0 lnClass="LLN0" inst="" lnType="baseLLN0"/>
17+
<LN lnClass="XCBR" inst="1" lnType="baseXCBR"/>
18+
</LDevice>
19+
<LDevice inst="ldInst2">
20+
<LN0 lnClass="LLN0" inst="" lnType="equalLLN0"/>
21+
<LN lnClass="XCBR" inst="1" lnType="equalXCBR"/>
22+
</LDevice>
23+
<LDevice inst="ldInst3">
24+
<LN0 lnClass="LLN0" inst="" lnType="diffLLN0"/>
25+
<LN lnClass="XCBR" inst="1" lnType="diffXCBR"/>
26+
</LDevice>
27+
</Server>
28+
</AccessPoint>
29+
</IED>
30+
<IED name="IED2">
31+
<AccessPoint name="AP1">
32+
<Server>
33+
<Authentication />
34+
<LDevice inst="ldInst1">
35+
<LN0 lnClass="LLN0" inst="" lnType="baseLLN0"/>
36+
<LN lnClass="XCBR" inst="1" lnType="baseXCBR"/>
37+
</LDevice>
38+
<LDevice inst="ldInst2">
39+
<LN0 lnClass="LLN0" inst="" lnType="equalLLN0"/>
40+
<LN lnClass="XCBR" inst="1" lnType="equalXCBR"/>
41+
</LDevice>
42+
<LDevice inst="ldInst3">
43+
<LN0 lnClass="LLN0" inst="" lnType="diffLLN0"/>
44+
<LN lnClass="XCBR" inst="1" lnType="diffXCBR"/>
45+
</LDevice>
46+
</Server>
47+
</AccessPoint>
48+
</IED>
49+
<IED name="IED3">
50+
<AccessPoint name="AP1">
51+
<Server>
52+
<Authentication />
53+
<LDevice inst="ldInst1">
54+
<LN0 lnClass="LLN0" inst="" lnType="baseLLN0"/>
55+
<LN lnClass="XCBR" inst="1" lnType="baseXCBR"/>
56+
</LDevice>
57+
<LDevice inst="ldInst2">
58+
<LN0 lnClass="LLN0" inst="" lnType="equalLLN0"/>
59+
<LN lnClass="XCBR" inst="1" lnType="equalXCBR"/>
60+
</LDevice>
61+
</Server>
62+
</AccessPoint>
63+
</IED>
64+
<DataTypeTemplates>
65+
<LNodeType lnClass="LLN0" id="baseLLN0" >
66+
<DO name="Beh" type="someEqualDOType" />
67+
</LNodeType>
68+
<LNodeType lnClass="LLN0" id="equalLLN0" >
69+
<DO name="Beh" type="someEqualDOType" />
70+
</LNodeType>
71+
<LNodeType lnClass="LLN0" id="diffLLN0" >
72+
<DO name="Beh" type="someDiffDOType" />
73+
</LNodeType>
74+
<LNodeType lnClass="XCBR" id="equalXCBR" >
75+
<DO name="Beh" type="someEqualDOType" />
76+
</LNodeType>
77+
<LNodeType lnClass="XCBR" id="baseXCBR" >
78+
<DO name="Beh" type="someBaseDOType" />
79+
</LNodeType>
80+
<LNodeType lnClass="XCBR" id="diffXCBR" >
81+
<DO name="Beh" type="someDiffDOType" />
82+
</LNodeType>
83+
<DOType cdc="SPS" id="someBaseDOType">
84+
<DA name="stVal" bType="Struct" fc="ST" type="someBaseDAType" />
85+
</DOType>
86+
<DOType cdc="SPS" id="someEqualDOType">
87+
<DA name="stVal" bType="Struct" fc="ST" type="someEqualDAType" />
88+
</DOType>
89+
<DOType cdc="SPS" id="someDiffDOType">
90+
<DA name="stVal" bType="Enum" fc="ST" type="someID" />
91+
</DOType>
92+
<DAType id="someBaseDAType" desc="someDesc">
93+
<BDA name="mag" desc="someEqual" bType="Struct" sAddr="someSAddr" type="AnalogueValue"/>
94+
<BDA name="stVal" desc="someEnumBDA" bType="Enum" sAddr="someSAddr" type="someEnumType"/>
95+
<ProtNs type="8-MMS">IEC 61850-8-1:2007</ProtNs>
96+
</DAType>
97+
<DAType id="someEqualDAType" desc="someDesc">
98+
<BDA name="mag" desc="someEqual" bType="Struct" sAddr="someSAddr" type="AnalogueValue"/>
99+
<BDA name="stVal" desc="someEnumBDA" bType="Enum" sAddr="someSAddr" type="someEnumType"/>
100+
<ProtNs>IEC 61850-8-1:2007</ProtNs>
101+
</DAType>
102+
<DAType id="AnalogueValue" iedType="someIedType">
103+
<BDA desc="someDiff1" name="f" bType="FLOAT32" valKind="RO" valImport="true">
104+
<Val sGroup="1">45.00</Val>
105+
<Val sGroup="2">65.00</Val>
106+
</BDA>
107+
</DAType>
108+
<EnumType id="someEnumType" desc="someDesc">
109+
<EnumVal ord="-1" desc="someDesc">SomeContent</EnumVal>
110+
<EnumVal ord="13">SomeOtherContent</EnumVal>
111+
<EnumVal ord="-23"></EnumVal>
112+
</EnumType>
113+
<EnumType id="someID">
114+
<Private type="someType" desc="someDesc" sxy:x="10" ens:some="someOtherNameSpace">
115+
<![CDATA[some comment]]>
116+
<IED name="somePrivateIED"/>
117+
</Private>
118+
<Text>Some detailed description</Text>
119+
<ens:SomeNonSCLElement />
120+
<EnumVal ord="1">A</EnumVal>
121+
</EnumType>
122+
<EnumType id="someDiffID" >
123+
<Private type="someType" desc="someDesc" ens:some="someOtherNameSpace" sxy:x="10" >
124+
<![CDATA[some comment]]>
125+
<IED name="somePrivateIED"/>
126+
</Private>
127+
<Text>Some detailed description</Text>
128+
<ens:SomeNonSCLElement />
129+
<EnumVal ord="1"></EnumVal>
130+
</EnumType>
131+
<EnumType id="someOtherID">
132+
<Private type="someType" desc="someDesc" sxy:x="10" ens:some="someOtherNameSpace">
133+
<![CDATA[some comment]]>
134+
<IED name="somePrivateIED"/>
135+
</Private>
136+
<Text>Some detailed description</Text>
137+
<ens:SomeNonSCLElement />
138+
<EnumVal ord="1">A</EnumVal>
139+
</EnumType>
140+
</DataTypeTemplates>
141+
</SCL>`,
142+
"application/xml",
143+
);
144+
145+
// const sclElement = testScl.querySelector("SCL")!;
146+
const nonSCLElement = testScl.querySelector("SomeNonSCLElement")!;
147+
148+
const baseEnumType = testScl.querySelector("#someID")!;
149+
// const diffEnumType = testScl.querySelector("#someDiffID")!;
150+
// const equalEnumType = testScl.querySelector("#someOtherID")!;
151+
152+
const baseDAType = testScl.querySelector("#someBaseDAType")!;
153+
const baseDOType = testScl.querySelector("#someBaseDOType")!;
154+
155+
// const baseIED = testScl.querySelector(`IED[name="IED1"]`)!;
156+
// const equalIED = testScl.querySelector(`IED[name="IED2"]`)!;
157+
// const diffIED = testScl.querySelector(`IED[name="IED3"]`)!;
158+
159+
describe("hasher", () => {
160+
const { hash, db } = newHasher();
161+
// TODO(ca-d): test eNS attributes
162+
163+
it("hashes unknown elements by outerHTML", () => {
164+
const digest = hash(nonSCLElement);
165+
const description =
166+
db[nonSCLElement.localName + "@" + nonSCLElement.namespaceURI][digest];
167+
expect(description).property("xml").to.equal(nonSCLElement.outerHTML);
168+
});
169+
170+
it("hashes EnumTypes by EnumVals, Privates and Texts", () => {
171+
const digest = hash(baseEnumType);
172+
const description = db.EnumType[digest] as Record<string, string[]>;
173+
expect(description).property("@EnumVal").to.have.lengthOf(1);
174+
const val = db.EnumVal[description["@EnumVal"][0]];
175+
expect(val).to.exist.and.to.have.property("ord", 1);
176+
expect(val).to.have.property("val", "A");
177+
expect(description).property("@Private").to.have.lengthOf(1);
178+
const priv = db.Private[description["@Private"][0]];
179+
expect(priv).to.exist.and.to.have.property(
180+
"xml",
181+
baseEnumType.querySelector("Private")?.outerHTML,
182+
);
183+
expect(description).property("@Text").to.have.lengthOf(1);
184+
const text = db.Text[description["@Text"][0]];
185+
expect(text).to.exist.and.to.have.property(
186+
"xml",
187+
baseEnumType.querySelector("Text")?.outerHTML,
188+
);
189+
});
190+
191+
it("hashes DATypes by BDAs and ProtNs", () => {
192+
const digest = hash(baseDAType);
193+
const description = db.DAType[digest] as Record<string, string[]>;
194+
expect(description).to.deep.equal({
195+
// FIXME(ca-d): define correct behaviour
196+
desc: "someDesc",
197+
"@BDA": ["b134bb4b87b783fa", "fcd3828e35e87aa4"],
198+
"@ProtNs": ["4fd2d8f99b2f756a"],
199+
});
200+
// TODO(ca-d): test siblingCount
201+
});
202+
203+
it("hashes DOTypes by DAs and SDOs", () => {
204+
const digest = hash(baseDOType);
205+
const description = db.DOType[digest] as Record<string, string[]>;
206+
expect(description).to.deep.equal({
207+
// FIXME(ca-d): define correct behaviour
208+
"@DA": ["4af99b41c4a5737c"],
209+
});
210+
});
211+
212+
after(() => {
213+
Object.keys(db).forEach((key) => {
214+
console.log(key, db[key]);
215+
});
216+
});
217+
});

0 commit comments

Comments
 (0)