@enervance/insight-cim-model 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/etl-neplan/etl-neplan-feederline.d.ts +1 -0
- package/dist/etl-neplan/etl-neplan-feederline.js +38 -30
- package/dist/etl-neplan/etl-neplan-feederline.js.map +1 -1
- package/dist/etl-neplan/neplan-contingency-analysis.js +17 -5
- package/dist/etl-neplan/neplan-contingency-analysis.js.map +1 -1
- package/package.json +1 -1
- package/src/etl-neplan/etl-neplan-feederline.ts +42 -34
- package/src/etl-neplan/neplan-contingency-analysis.ts +21 -39
- package/test/apache-jena-fuseki-interface/apache-jena-fuseki-neplan-1.tests.sp-ec.ts +2 -2
- package/test/apache-jena-fuseki-interface/apache-jena-fuseki-neplan-katarina-ruhrau.tests.spec.ts +223 -0
- package/test/apache-jena-fuseki-interface/data/xml/ruhrau-katharina/Ruhrau_Katharina_Rootnet_Area 1_EQ_V1.xml +24517 -24494
- package/test/apache-jena-fuseki-interface/data/xml/ruhrau-katharina/Ruhrau_Katharina_Rootnet_Area 1_SSH_V1.xml +4910 -4903
- package/test/apache-jena-fuseki-interface/data/xml/ruhrau-katharina/Ruhrau_Katharina_Rootnet_Area 1_SV_V1.xml +2497 -2492
- package/test/apache-jena-fuseki-interface/data/apache-jena-fuseki-3.12.0/run/system/tdb.lock +0 -1
- /package/test/apache-jena-fuseki-interface/{apache-jena-fuseki-neplan-2.tests.spec.ts → apache-jena-fuseki-neplan-2.tests.sp-ec.ts} +0 -0
package/test/apache-jena-fuseki-interface/apache-jena-fuseki-neplan-katarina-ruhrau.tests.spec.ts
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import * as fetch from 'node-fetch';
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
|
|
4
|
+
import * as childProcess from 'child_process';
|
|
5
|
+
import {
|
|
6
|
+
ACLineSegment,
|
|
7
|
+
addNeplanFacilities,
|
|
8
|
+
CIM_CLASS_NAMES,
|
|
9
|
+
EVTerminal,
|
|
10
|
+
EVTerminalAction,
|
|
11
|
+
FUSEKI_LOAD_CONFIG_NEPLAN, generateUUID, getActivityRecordEventByTypeName,
|
|
12
|
+
getClassDefinitionMap,
|
|
13
|
+
getEnergyConsumerByName,
|
|
14
|
+
getObjectByProperty,
|
|
15
|
+
IConnectivityNode,
|
|
16
|
+
Model, PROPERTY_HANDLER_WESTNETZNEPLAN_CONFIG,
|
|
17
|
+
SwitchActionKind,
|
|
18
|
+
SwitchingPlan,
|
|
19
|
+
transformEnergyConsumers,
|
|
20
|
+
WNConnectivityNode, WNFacility,
|
|
21
|
+
WNFaultConnectivityNode,
|
|
22
|
+
WNFeeder
|
|
23
|
+
} from "../../src";
|
|
24
|
+
import { loadFusekiData, parseFusekiData } from '../../src/etl-neplan/etl-neplan';
|
|
25
|
+
import { postNodeFetchData } from '../../src/util/utils';
|
|
26
|
+
import { createFeederLines } from '../../src/etl-neplan/etl-neplan-feederline';
|
|
27
|
+
import { performContingencyAnalysis } from '../../src/etl-neplan/etl-neplan-contingency-analysis';
|
|
28
|
+
import { WNOutage } from '../../src/model/extensions/neplan-westnetz/operations/WNOutage';
|
|
29
|
+
import { WNEnergyConsumer } from '../../src/model/extensions/neplan-westnetz/wires/WNEnergyConsumer';
|
|
30
|
+
import { determineSubstations } from '../../src/util/util-topology';
|
|
31
|
+
import { performContingencyAnalysisV2 } from '../../src/etl-neplan/neplan-contingency-analysis';
|
|
32
|
+
|
|
33
|
+
describe('Apache Jena Fuseki Interface Neplan Test', () => {
|
|
34
|
+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2147483633;
|
|
35
|
+
const FUSEKI_PORT = 3010;
|
|
36
|
+
const FUSEKI_TBD_NAME = 'test';
|
|
37
|
+
|
|
38
|
+
const fusekiURI = `http://127.0.0.1:${FUSEKI_PORT}/${FUSEKI_TBD_NAME}`;
|
|
39
|
+
const graphURL = 'http://test/data';
|
|
40
|
+
const graphURI = `<${graphURL}>`;
|
|
41
|
+
|
|
42
|
+
/** Endpunkt: Aktualisieren der Daten*/
|
|
43
|
+
const fusekiUpdateURI = `${fusekiURI}/update`;
|
|
44
|
+
|
|
45
|
+
/** Endpunkt: Abfrage der Daten*/
|
|
46
|
+
const fusekiQueryURI = `${fusekiURI}/query`;
|
|
47
|
+
|
|
48
|
+
/** Endpunkt: Datenimport */
|
|
49
|
+
const fusekiDataURI = `${fusekiURI}/data`;
|
|
50
|
+
|
|
51
|
+
/** Endpunkt: GraphURI-basierter Datenimport */
|
|
52
|
+
const fusekiGraphDataURI = `${fusekiURI}/data?graph=${graphURL}`;
|
|
53
|
+
|
|
54
|
+
let childRef;
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
const cimModel = new Model();
|
|
58
|
+
|
|
59
|
+
beforeAll((done) => {
|
|
60
|
+
|
|
61
|
+
childRef = childProcess.spawn('fuseki-server', [`--port=${FUSEKI_PORT}`, '--update'], {
|
|
62
|
+
cwd: process.cwd() + '\\test\\apache-jena-fuseki-interface\\data\\apache-jena-fuseki-3.12.0\\',
|
|
63
|
+
shell: true,
|
|
64
|
+
/*detached: true,*/
|
|
65
|
+
});
|
|
66
|
+
childRef.stdout.on('data', async (code) => {
|
|
67
|
+
/** auf die Ausgabe warten, wenn der Server gestartet ist */
|
|
68
|
+
const consolePrint = code.toString();
|
|
69
|
+
//console.log(consolePrint);
|
|
70
|
+
if (consolePrint.includes('Started') && consolePrint.includes('on port')) {
|
|
71
|
+
console.log('Fuseki started');
|
|
72
|
+
|
|
73
|
+
/** Mit RegEx Zahlen prüfen: nullen und Dezmaltrennzeichen abschneiden */
|
|
74
|
+
/** 0.081510 -> 0.08151, 0. -> 0, 10.00 -> 10*/
|
|
75
|
+
const regexDecimal = /(?:(\.\d*?[1-9]+)|\.)0*(?=<)/gm;
|
|
76
|
+
/** 0e+000 -> 0*/
|
|
77
|
+
const regexZeroScientific = /(>\d+(?=e[+-]0+))e[+-]0+/gm;
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
/** load testdata */
|
|
81
|
+
const eq = await fs.readFileSync('test/apache-jena-fuseki-interface/data/xml/ruhrau-katharina/Ruhrau_Katharina_Rootnet_Area 1_EQ_V1.xml', 'utf8');
|
|
82
|
+
const dataDecimalEq = eq.replace(regexDecimal, `$1`);
|
|
83
|
+
const dataAdjustedEq = dataDecimalEq.replace(regexZeroScientific, `$1`);
|
|
84
|
+
|
|
85
|
+
const ssh = await fs.readFileSync('test/apache-jena-fuseki-interface/data/xml/ruhrau-katharina/Ruhrau_Katharina_Rootnet_Area 1_SSH_V1.xml', 'utf8');
|
|
86
|
+
const dataDecimalSSH = ssh.replace(regexDecimal, `$1`);
|
|
87
|
+
const dataAdjustedSSH = dataDecimalSSH.replace(regexZeroScientific, `$1`);
|
|
88
|
+
/** feeder lines */
|
|
89
|
+
/** psrtypes */
|
|
90
|
+
const psrTypes = await fs.readFileSync('test/apache-jena-fuseki-interface/data/xml/PsrType.xml', 'utf8');
|
|
91
|
+
|
|
92
|
+
Promise.all([ postNodeFetchData(fusekiGraphDataURI, 'post', dataAdjustedEq, {'Content-type': 'application/rdf+xml;charset=utf-8'}),
|
|
93
|
+
postNodeFetchData(fusekiGraphDataURI, 'post', dataAdjustedSSH, {'Content-type': 'application/rdf+xml;charset=utf-8'}),
|
|
94
|
+
postNodeFetchData(fusekiGraphDataURI, 'post', psrTypes, {'Content-type': 'application/rdf+xml;charset=utf-8'})
|
|
95
|
+
]).then((values: any[]) => {
|
|
96
|
+
done();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('Apache Jena Fuseki Interface Neplan ETL add Feeder&SwitchActions', async (done) => {
|
|
103
|
+
cimModel.purgeData();
|
|
104
|
+
/** configure query data */
|
|
105
|
+
const neplanClassDefinitions = getClassDefinitionMap();
|
|
106
|
+
|
|
107
|
+
/** query data */
|
|
108
|
+
let cimFusekiDataRaw = await loadFusekiData(fusekiURI, graphURI, FUSEKI_LOAD_CONFIG_NEPLAN, neplanClassDefinitions);
|
|
109
|
+
/** parse queried data */
|
|
110
|
+
parseFusekiData(cimModel, cimFusekiDataRaw, FUSEKI_LOAD_CONFIG_NEPLAN, neplanClassDefinitions);
|
|
111
|
+
cimModel.resolveParsedAssociations();
|
|
112
|
+
|
|
113
|
+
const defaultSubstation = cimModel.getObjectByName('DefaultSubstation');
|
|
114
|
+
const baseIRI = defaultSubstation.baseIRI;
|
|
115
|
+
|
|
116
|
+
/** Objekte erzeugen */
|
|
117
|
+
const insertObjectSPARQL = createFeederLines(cimModel, baseIRI);
|
|
118
|
+
|
|
119
|
+
const queryCreateFeedersSwitch = `
|
|
120
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
121
|
+
PREFIX cim: <http://iec.ch/TC57/2013/CIM-schema-cim16#>
|
|
122
|
+
PREFIX entsoe: <http://entsoe.eu/CIM/SchemaExtension/3/1#>
|
|
123
|
+
PREFIX westnetzneplan: <http://westnetzneplan.de/CIM/Extensions#>
|
|
124
|
+
PREFIX enervance: <http://enervance.com/CIM/Extensions#>
|
|
125
|
+
INSERT DATA{
|
|
126
|
+
GRAPH ${graphURI} {
|
|
127
|
+
${insertObjectSPARQL.join(' ')}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
console.log('Feeders Vor');
|
|
133
|
+
for (const feeder of cimModel.feeders.values()) {
|
|
134
|
+
const wnFeeder = feeder as WNFeeder;
|
|
135
|
+
console.log('\t' + wnFeeder.name);
|
|
136
|
+
expect(wnFeeder.normalHeadTerminals.size).toBe(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
await postNodeFetchData(fusekiUpdateURI, 'post', queryCreateFeedersSwitch, {'Content-type': 'application/sparql-update'});
|
|
140
|
+
|
|
141
|
+
expect(defaultSubstation).toBeDefined();
|
|
142
|
+
expect(baseIRI).toBeDefined();
|
|
143
|
+
|
|
144
|
+
// SwitchActions
|
|
145
|
+
// const insertSPARQL = performContingencyAnalysis(cimModel);
|
|
146
|
+
const insertSPARQL = performContingencyAnalysisV2(cimModel);
|
|
147
|
+
const queryCreateSwitchActions = `
|
|
148
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
149
|
+
PREFIX cim: <http://iec.ch/TC57/2013/CIM-schema-cim16#>
|
|
150
|
+
PREFIX entsoe: <http://entsoe.eu/CIM/SchemaExtension/3/1#>
|
|
151
|
+
PREFIX westnetzneplan: <http://westnetzneplan.de/CIM/Extensions#>
|
|
152
|
+
PREFIX enervance: <http://enervance.com/CIM/Extensions#>
|
|
153
|
+
INSERT DATA{
|
|
154
|
+
GRAPH ${graphURI} {
|
|
155
|
+
${insertSPARQL.join(' ')}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
`;
|
|
159
|
+
await postNodeFetchData(fusekiUpdateURI, 'post', queryCreateSwitchActions, {'Content-type': 'application/sparql-update'});
|
|
160
|
+
cimModel.purgeData();
|
|
161
|
+
|
|
162
|
+
/** query data */
|
|
163
|
+
const cimFusekiDataRawNew = await loadFusekiData(fusekiURI, graphURI, FUSEKI_LOAD_CONFIG_NEPLAN, neplanClassDefinitions);
|
|
164
|
+
/** parse queried data */
|
|
165
|
+
parseFusekiData(cimModel, cimFusekiDataRawNew, FUSEKI_LOAD_CONFIG_NEPLAN, neplanClassDefinitions);
|
|
166
|
+
cimModel.resolveParsedAssociations();
|
|
167
|
+
|
|
168
|
+
console.log('Feeders');
|
|
169
|
+
for (const feeder of cimModel.feeders.values()) {
|
|
170
|
+
const wnFeeder = feeder as WNFeeder;
|
|
171
|
+
console.log('\t' + wnFeeder.name);
|
|
172
|
+
expect(wnFeeder.normalHeadTerminals.size).toBe(1);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
done();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
afterAll(async (done) => {
|
|
181
|
+
|
|
182
|
+
await fetch(fusekiURI, {
|
|
183
|
+
method: 'post',
|
|
184
|
+
body: `DROP GRAPH ${graphURI}`,
|
|
185
|
+
headers: {'Content-type': 'application/sparql-update'},
|
|
186
|
+
});
|
|
187
|
+
console.log(`Graph ${graphURI} dropped`);
|
|
188
|
+
console.log('Fuseki childRef PID ' + childRef.pid);
|
|
189
|
+
|
|
190
|
+
const childRefPort = childProcess.spawn(`echo off & (for /f \"tokens=5\" %a in (\'netstat -aon ^| findstr ${FUSEKI_PORT}\') do tasklist /NH /FO \"csv\" /FI \"PID eq %a\") & echo on`, {
|
|
191
|
+
shell: true,
|
|
192
|
+
});
|
|
193
|
+
childRefPort.stdout.on('data', (code) => {
|
|
194
|
+
try {
|
|
195
|
+
const arrayData = code.toString().split(',');
|
|
196
|
+
const appName = arrayData[0];
|
|
197
|
+
const pid = arrayData[1];
|
|
198
|
+
if (appName.includes('java')) {
|
|
199
|
+
const cildRefKill = childProcess.exec(`taskkill /PID ${pid} /F`, (error, stdout, stderr) => {
|
|
200
|
+
});
|
|
201
|
+
cildRefKill.stdout.on('data', (code) => {
|
|
202
|
+
console.log('Kill Fuseki Server');
|
|
203
|
+
console.log(code.toString());
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
} catch (e) {
|
|
207
|
+
} finally {
|
|
208
|
+
//TODO
|
|
209
|
+
}
|
|
210
|
+
done();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
/** Methode zum Schreiben der Daten in eine Datei */
|
|
217
|
+
export function writeFile(filePath: string, data: any) {
|
|
218
|
+
fs.writeFile(filePath, JSON.stringify(data), function (err) {
|
|
219
|
+
if (err) {
|
|
220
|
+
console.log(err);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|