@enervance/insight-cim-model 0.0.277 → 0.0.279

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.
Files changed (76) hide show
  1. package/dist/analysis/powerflow/powerflow.util.d.ts +213 -0
  2. package/dist/analysis/powerflow/powerflow.util.js +1466 -0
  3. package/dist/analysis/powerflow/powerflow.util.js.map +1 -0
  4. package/dist/constants/cim-class-names.d.ts +4 -0
  5. package/dist/constants/cim-class-names.js +4 -0
  6. package/dist/constants/cim-class-names.js.map +1 -1
  7. package/dist/converter/integral7/converter.integral7.d.ts +3 -3
  8. package/dist/converter/integral7/converter.integral7.js +114 -61
  9. package/dist/converter/integral7/converter.integral7.js.map +1 -1
  10. package/dist/converter/integral7/dl-convert/executor.js +22 -55
  11. package/dist/converter/integral7/dl-convert/executor.js.map +1 -1
  12. package/dist/converter/integral7/interface-i7/export-frame-i7.js +6 -1
  13. package/dist/converter/integral7/interface-i7/export-frame-i7.js.map +1 -1
  14. package/dist/converter/integral7/model/interfaces.d.ts +7 -1
  15. package/dist/converter/integral7/model/interfaces.js.map +1 -1
  16. package/dist/converter/integral7/sql/integral.sql.d.ts +3 -0
  17. package/dist/converter/integral7/sql/integral.sql.js +8 -2
  18. package/dist/converter/integral7/sql/integral.sql.js.map +1 -1
  19. package/dist/interfaces/model/core/IIdentifiedObject.d.ts +1 -0
  20. package/dist/interfaces/model/core/ITerminal.d.ts +0 -1
  21. package/dist/model/core/ConnectivityNode.js +2 -0
  22. package/dist/model/core/ConnectivityNode.js.map +1 -1
  23. package/dist/model/core/Equipment.js +1 -0
  24. package/dist/model/core/Equipment.js.map +1 -1
  25. package/dist/model/core/IdentifiedObject.d.ts +3 -0
  26. package/dist/model/core/IdentifiedObject.js +7 -0
  27. package/dist/model/core/IdentifiedObject.js.map +1 -1
  28. package/dist/model/core/Terminal.d.ts +1 -0
  29. package/dist/model/core/Terminal.js +11 -8
  30. package/dist/model/core/Terminal.js.map +1 -1
  31. package/dist/model/dc/CsConverter.js.map +1 -1
  32. package/dist/model/extensions/amprion/common/AMPRIONWireOperatingTypeKind.d.ts +3 -0
  33. package/dist/model/extensions/amprion/common/AMPRIONWireOperatingTypeKind.js +4 -1
  34. package/dist/model/extensions/amprion/common/AMPRIONWireOperatingTypeKind.js.map +1 -1
  35. package/dist/model/extensions/amprion/core/AMPRIONConnectivityNode.d.ts +1 -0
  36. package/dist/model/extensions/amprion/core/AMPRIONConnectivityNode.js +2 -1
  37. package/dist/model/extensions/amprion/core/AMPRIONConnectivityNode.js.map +1 -1
  38. package/dist/model/extensions/amprion/core/AMPRIONLine.d.ts +1 -0
  39. package/dist/model/extensions/amprion/core/AMPRIONLine.js +2 -0
  40. package/dist/model/extensions/amprion/core/AMPRIONLine.js.map +1 -1
  41. package/dist/model/extensions/amprion/wires/AMPRIONACLineSegment.d.ts +1 -0
  42. package/dist/model/extensions/amprion/wires/AMPRIONACLineSegment.js.map +1 -1
  43. package/dist/model/extensions/amprion/wires/AMPRIONLinearShuntCompensator.d.ts +14 -0
  44. package/dist/model/extensions/amprion/wires/AMPRIONLinearShuntCompensator.js +50 -0
  45. package/dist/model/extensions/amprion/wires/AMPRIONLinearShuntCompensator.js.map +1 -0
  46. package/dist/model/extensions/integral/common/INTEGRALMultiplierFactor.d.ts +1 -0
  47. package/dist/model/extensions/integral/common/INTEGRALMultiplierFactor.js +4 -2
  48. package/dist/model/extensions/integral/common/INTEGRALMultiplierFactor.js.map +1 -1
  49. package/dist/model/extensions/integral/dc/DCConverterUnit.d.ts +1 -0
  50. package/dist/model/extensions/integral/dc/DCConverterUnit.js +2 -0
  51. package/dist/model/extensions/integral/dc/DCConverterUnit.js.map +1 -1
  52. package/dist/model/extensions/integral/wires/INTEGRALEnergySource.d.ts +28 -0
  53. package/dist/model/extensions/integral/wires/INTEGRALEnergySource.js +177 -0
  54. package/dist/model/extensions/integral/wires/INTEGRALEnergySource.js.map +1 -0
  55. package/dist/model/extensions/integral/wires/INTEGRALSynchronousMachine.d.ts +5 -0
  56. package/dist/model/extensions/integral/wires/INTEGRALSynchronousMachine.js +88 -0
  57. package/dist/model/extensions/integral/wires/INTEGRALSynchronousMachine.js.map +1 -1
  58. package/dist/model/generation/GeneratingUnit.js.map +1 -1
  59. package/dist/model/generation/HydroGeneratingUnit.d.ts +6 -0
  60. package/dist/model/generation/HydroGeneratingUnit.js +62 -0
  61. package/dist/model/generation/HydroGeneratingUnit.js.map +1 -1
  62. package/dist/model/wires/EnergySource.js +14 -13
  63. package/dist/model/wires/EnergySource.js.map +1 -1
  64. package/dist/model/wires/LinearShuntCompensator.d.ts +5 -0
  65. package/dist/model/wires/LinearShuntCompensator.js +45 -25
  66. package/dist/model/wires/LinearShuntCompensator.js.map +1 -1
  67. package/dist/model/wires/SeriesCompensator.js +1 -2
  68. package/dist/model/wires/SeriesCompensator.js.map +1 -1
  69. package/dist/model/wires/ShuntCompensator.d.ts +1 -0
  70. package/dist/model/wires/ShuntCompensator.js +7 -0
  71. package/dist/model/wires/ShuntCompensator.js.map +1 -1
  72. package/dist/model/wires/SynchronousMachine.js +4 -4
  73. package/dist/utils2/cim.model.utils.js +8 -0
  74. package/dist/utils2/cim.model.utils.js.map +1 -1
  75. package/dist/utils2/parser.utils.js.map +1 -1
  76. package/package.json +1 -1
@@ -0,0 +1,1466 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getKrInfo = exports.PowerflowUtil = void 0;
4
+ const ExternalNetworkInjection_1 = require("../../model/wires/ExternalNetworkInjection.js");
5
+ const SynchronousMachine_1 = require("../../model/wires/SynchronousMachine.js");
6
+ const PowerTransformer_1 = require("../../model/wires/PowerTransformer.js");
7
+ const ACLineSegment_1 = require("../../model/wires/ACLineSegment.js");
8
+ const EnergySource_1 = require("../../model/wires/EnergySource.js");
9
+ const EnergyConsumer_1 = require("../../model/wires/EnergyConsumer.js");
10
+ const ConnectivityNode_1 = require("../../model/core/ConnectivityNode.js");
11
+ const TopologicalNode_1 = require("../../model/topology/TopologicalNode.js");
12
+ const cim_model_assetinfo_util_1 = require("../../utils2/cim.model.assetinfo.util.js");
13
+ const common_utils_1 = require("../../utils2/common.utils.js");
14
+ const cim_constants_1 = require("../../constants/cim-constants.js");
15
+ const Switch_1 = require("../../model/wires/Switch.js");
16
+ const EquivalentBranch_1 = require("../../model/equivalents/EquivalentBranch.js");
17
+ const LinearShuntCompensator_1 = require("../../model/wires/LinearShuntCompensator.js");
18
+ class PowerflowUtil {
19
+ /**
20
+ * Ermittelt alle elektrischverbundene Elemente eines Netzes
21
+ * @param modelContainer das Netz als CIM Modell
22
+ * */
23
+ static getInterconnectedGrids(modelContainer, withSwitchSates = false) {
24
+ const results = new Array();
25
+ const visitedUUIDs = new Map();
26
+ let nextCn = PowerflowUtil.getNextNode(modelContainer.connectivityNodes, visitedUUIDs);
27
+ while (nextCn) {
28
+ const objectsFound = PowerflowUtil.breadthFirstSearch(nextCn, withSwitchSates);
29
+ const interconnectedGridElements = [...objectsFound.values()];
30
+ results.push({
31
+ interconnectedGridElements,
32
+ computabe: PowerflowUtil.isGridComputable(interconnectedGridElements),
33
+ interconnectedGridCounter: results.length + 1
34
+ });
35
+ for (const object of objectsFound.values()) {
36
+ visitedUUIDs.set(object.getUUID(), object);
37
+ }
38
+ nextCn = PowerflowUtil.getNextNode(modelContainer.connectivityNodes, visitedUUIDs);
39
+ }
40
+ return results;
41
+ }
42
+ static breadthFirstSearch(startCN, withSwitchSates = false) {
43
+ // const objectsFound = new Array<IConnectivityNode | IConductingEquipment>();
44
+ const objectsFound = new Map();
45
+ let nodesOnCurrentLevel = new Array();
46
+ let nodesOnNextLevel = new Array(startCN);
47
+ let terminalVisited = new Map();
48
+ let counter = 0;
49
+ while (nodesOnNextLevel.length) {
50
+ nodesOnCurrentLevel.length = 0;
51
+ nodesOnCurrentLevel = [...nodesOnNextLevel];
52
+ /** next level nodes leeren */
53
+ nodesOnNextLevel.length = 0;
54
+ for (const currentNode of nodesOnCurrentLevel) {
55
+ objectsFound.set(currentNode.getUUID(), currentNode);
56
+ // nodesVisited.push(currentNode.getUUID());
57
+ for (const terminal of currentNode.terminals.values()) {
58
+ if (!terminal)
59
+ continue;
60
+ if (withSwitchSates && !terminal.isClosed())
61
+ continue;
62
+ /** Terminal traversierbar und nicht besucht */
63
+ if (terminalVisited.has(terminal.getUUID()))
64
+ continue;
65
+ terminalVisited.set(terminal.getUUID(), terminal);
66
+ const terminalConductingEquipment = terminal.conductingEquipment;
67
+ if (!terminalConductingEquipment)
68
+ continue;
69
+ if (withSwitchSates && !terminal.isClosed())
70
+ continue;
71
+ if (!objectsFound.has(terminalConductingEquipment === null || terminalConductingEquipment === void 0 ? void 0 : terminalConductingEquipment.getUUID())) {
72
+ nodesOnNextLevel.push(terminalConductingEquipment);
73
+ }
74
+ const terminalConnectivityNode = terminal.connectivityNode;
75
+ if (!terminalConnectivityNode)
76
+ continue;
77
+ if (!objectsFound.has(terminalConnectivityNode.getUUID())) {
78
+ nodesOnNextLevel.push(terminalConnectivityNode);
79
+ }
80
+ }
81
+ }
82
+ }
83
+ return objectsFound;
84
+ }
85
+ /**
86
+ * bestimmt den nächsten unbesuchten Knoten für die Breitensuche.
87
+ * @param connectivityNodes alle ConnectivityNodes eines Netzmodells
88
+ * @param visitedUUIDs UUIDs aller abgearbeiteten Elemente
89
+ * */
90
+ static getNextNode(connectivityNodes, visitedUUIDs) {
91
+ return [...connectivityNodes.values()].find(it => !visitedUUIDs.has(it.getUUID()));
92
+ }
93
+ /** Prüft, ob das Netz rechenfähig ist. */
94
+ static isGridComputable(network) {
95
+ if (PowerflowUtil.isGeneratorsExists(network)) {
96
+ if (PowerflowUtil.isEnergySourcesConsumersExists(network)) {
97
+ if (PowerflowUtil.isBranchExists(network)) {
98
+ return true;
99
+ }
100
+ }
101
+ }
102
+ return false;
103
+ }
104
+ /** Prüft, ob im Teilnetz eine Slacks/Generators vorhanden sind */
105
+ static isGeneratorsExists(network) {
106
+ const t = network.find(it => (it instanceof ExternalNetworkInjection_1.ExternalNetworkInjection || it instanceof SynchronousMachine_1.SynchronousMachine));
107
+ return t ? true : false;
108
+ }
109
+ /** Prüft, ob im Teilnetz eine Slacks/Generators vorhanden sind */
110
+ static isBranchExists(network) {
111
+ const t = network.find(it => (it instanceof ACLineSegment_1.ACLineSegment || it instanceof PowerTransformer_1.PowerTransformer));
112
+ return t ? true : false;
113
+ //return network.find(it => (it instanceof ACLineSegment || it instanceof PowerTransformer)) ? true : false;
114
+ }
115
+ //Prüft, ob im Teilnetz NetzLasten/-einspeisungen vorhanden sind
116
+ static isEnergySourcesConsumersExists(network) {
117
+ const t = network.find(it => (it instanceof EnergySource_1.EnergySource || it instanceof EnergyConsumer_1.EnergyConsumer));
118
+ return t ? true : false;
119
+ // return network.find(it => (it instanceof EnergySource || it instanceof EnergyConsumer)) ? true : false;
120
+ }
121
+ static convertCIM2PandaPowerNetwork(network, nodeType, pandaDataFrame, defaultsConfig) {
122
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
123
+ const uuidToIndex = new Map();
124
+ const snMVA = pandaDataFrame._object.sn_mva;
125
+ /** key uuid -> (Typ EnergyConsumer/EnergySource => Objekte)*/
126
+ const tpLoadsNfeeders = new Map();
127
+ /** Buselemente anlegen */
128
+ const cimNodes = network.filter(it => it.constructor.name.includes(nodeType));
129
+ const busData = pandaDataFrame._object.bus._object;
130
+ for (const cimNode of cimNodes) {
131
+ const ppNodeType = 'b'; // per default Station
132
+ const baseV = PowerflowUtil.getBaseVoltageAsNumber(cimNode);
133
+ const baseVoltage = baseV <= 0 ? defaultsConfig.data.line.default_u : baseV;
134
+ /** name, vn_kv, type, zone, in_service, description, substat,f older_id,sernum,for_name,chr_name,pf_converged,pf_name,geo */
135
+ const bus = [
136
+ cimNode.mrid,
137
+ baseVoltage,
138
+ ppNodeType,
139
+ 1,
140
+ true,
141
+ '',
142
+ '',
143
+ '',
144
+ '',
145
+ '',
146
+ '',
147
+ false,
148
+ cimNode.mrid,
149
+ null
150
+ ];
151
+ busData.data.push(bus);
152
+ if (cimNode.getUUID() === '5fa34a72-d1f0-4abc-b3ad-5e5a4b2e7fc7') {
153
+ console.log();
154
+ }
155
+ const idx = busData.data.length - 1;
156
+ busData.index.push(idx);
157
+ uuidToIndex.set(cimNode.mrid, idx);
158
+ // TODO refactoring/überarbeiten
159
+ const loadsNfeeders = new Map();
160
+ if (nodeType === 'ConnectivityNode') {
161
+ cimNode.determineLoadNFeeder(loadsNfeeders);
162
+ }
163
+ else {
164
+ cimNode.determineLoadNFeeder(loadsNfeeders);
165
+ }
166
+ tpLoadsNfeeders.set(cimNode.mrid, loadsNfeeders);
167
+ }
168
+ /** Lasten anlegen */
169
+ const loadData = pandaDataFrame._object.load._object;
170
+ for (const entry of tpLoadsNfeeders.entries()) {
171
+ const loadsNfeeders = entry[1];
172
+ for (const entry of loadsNfeeders.entries()) {
173
+ const key = entry[0];
174
+ if (key.includes('EnergyConsumer')) {
175
+ const valuesArr = entry[1];
176
+ for (let i = 0; i < valuesArr.length; i++) {
177
+ const energyConsumer = valuesArr[i];
178
+ for (const terminalValue of energyConsumer.terminals.values()) {
179
+ const connectedNode = terminalValue.getConnectedNode();
180
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
181
+ if (!busID)
182
+ continue;
183
+ const p = energyConsumer.getP();
184
+ const q = energyConsumer.getQ();
185
+ const costPhi = energyConsumer.getCosPhi();
186
+ /** name, bus, p_mw, q_mvar, const_z_percent, const_i_percent, sn_mva, scaling, in_service,type, init_p_mw, init_q_mvar, cos_phi */
187
+ const load = [
188
+ energyConsumer.mrid,
189
+ busID,
190
+ p,
191
+ q,
192
+ 0,
193
+ 0,
194
+ snMVA,
195
+ PowerflowUtil.scalingFactor,
196
+ true,
197
+ null,
198
+ p,
199
+ q,
200
+ costPhi // cos_phi
201
+ ];
202
+ loadData.data.push(load);
203
+ loadData.index.push(loadData.data.length - 1);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ /** Ersatzleistungszahl */
210
+ const krInfo = getKrInfo(tpLoadsNfeeders);
211
+ const sgenData = pandaDataFrame._object.sgen._object;
212
+ /** Generatoren anlegen */
213
+ const genData = pandaDataFrame._object.gen._object;
214
+ /** Einspeisungen anlegen */
215
+ for (const loadsNfeeders of tpLoadsNfeeders.values()) {
216
+ for (const entry of loadsNfeeders.entries()) {
217
+ const key = entry[0];
218
+ const valuesArr = entry[1];
219
+ if (key.includes('EnergySource')) {
220
+ for (let i = 0; i < valuesArr.length; i++) {
221
+ const energySource = valuesArr[i];
222
+ if (PowerflowUtil.synchronousMachineUUIDs.includes(energySource.getUUID()))
223
+ continue;
224
+ for (const terminalValue of energySource.terminals.values()) {
225
+ const connectedNode = terminalValue.getConnectedNode();
226
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
227
+ if (busID !== undefined) {
228
+ // "name","bus","p_mw","q_mvar",
229
+ // "name","bus","p_mw","q_mvar","sn_mva","scaling","in_service","type","current_source", in_service_date
230
+ // [1, 0.0, 0.0,false,true,null,21.7,12.7,1.0,null,null];
231
+ // const sgen: any[] = [energySource.mrid, busID, p, q, 0, 1, true, (energySource.psrType?.name ?? ''), false, inServiceDate];
232
+ let p = isNaN(energySource.activePower) ? 0 : energySource.activePower;
233
+ let q = isNaN(energySource.reactivePower) ? 0 : energySource.reactivePower;
234
+ const inServiceDate = (_a = energySource.getAsset()) === null || _a === void 0 ? void 0 : _a.getInServiceDate();
235
+ const isGenerator = energySource.kr > 0;
236
+ if (isGenerator) {
237
+ const baseVoltage = PowerflowUtil.getBaseVoltageAsNumber(connectedNode);
238
+ const slackWeight = energySource.kr / (krInfo === null || krInfo === void 0 ? void 0 : krInfo.krSum);
239
+ /** name, bus, vm_pu, va_degree, slack_weight, in_service, s_sc_max_mva,s_sc_min_mva,rx_min,rx_max,r0x0_max,x0x_max,r0x0_min,x0x_min,description */
240
+ const gen = [
241
+ energySource.getUUID(),
242
+ busID,
243
+ //p < 0 ? p * -1 : p, // p_mw
244
+ 0,
245
+ 1,
246
+ snMVA,
247
+ 0,
248
+ 0,
249
+ 1,
250
+ //genWithHighestPrio?.getUUID() === synchronousMachine.getUUID() ? true : false, // slack
251
+ false,
252
+ true,
253
+ slackWeight ? slackWeight : 0,
254
+ 'sync',
255
+ energySource.key
256
+ ]; // min_p_mw
257
+ genData.data.push(gen);
258
+ genData.index.push(genData.data.length - 1);
259
+ }
260
+ /** "name, bus, p_mw, q_mvar,sn_mva,scaling,in_service,type,current_source, in_service_date */
261
+ const sgen = [
262
+ energySource.mrid,
263
+ busID,
264
+ p, q,
265
+ snMVA,
266
+ PowerflowUtil.scalingFactorRn,
267
+ true,
268
+ ((_c = (_b = energySource.psrType) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : ''),
269
+ false,
270
+ inServiceDate
271
+ ];
272
+ sgenData.data.push(sgen);
273
+ sgenData.index.push(sgenData.data.length - 1);
274
+ }
275
+ }
276
+ }
277
+ }
278
+ }
279
+ }
280
+ /** Slacks */
281
+ const extNetData = pandaDataFrame._object.ext_grid._object;
282
+ const generators = network.filter(it => it instanceof SynchronousMachine_1.SynchronousMachine);
283
+ const generatorsWithoutControl = generators.filter(it => { var _a; return !((_a = it.regulatingControl) === null || _a === void 0 ? void 0 : _a.targetValue) && !it.generatingUnit; });
284
+ const genWithHighestPrio = generators.reduce((highest, current) => highest.referencePriority > current.referencePriority ? highest : current);
285
+ for (const synchronousMachine of krInfo.gensWithKrOnly) {
286
+ const str = `${synchronousMachine.mrid} ${synchronousMachine.key}`;
287
+ // TODO
288
+ console.log('GensWithKrOnly ist nicht implementiert', str);
289
+ }
290
+ for (const synchronousMachine of krInfo.gensWithTargetVoltageKr) {
291
+ const str = `${synchronousMachine.mrid}${synchronousMachine.key}`;
292
+ if (PowerflowUtil.synchronousMachineUUIDs.includes(synchronousMachine.getUUID()))
293
+ continue;
294
+ for (const terminalValue of synchronousMachine.terminals.values()) {
295
+ const connectedNode = terminalValue.getConnectedNode();
296
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
297
+ if (!busID) {
298
+ console.log(`${str} keine BusID`);
299
+ continue;
300
+ }
301
+ const baseVoltage = PowerflowUtil.getBaseVoltageAsNumber(connectedNode);
302
+ const targetValue = synchronousMachine.regulatingControl.targetValue;
303
+ const targetVoltage = targetValue / baseVoltage;
304
+ const p = synchronousMachine.p || 0;
305
+ if (synchronousMachine.controlEnabled === false) {
306
+ console.log(`${str} kein controlEnabled`);
307
+ continue;
308
+ }
309
+ const isSlack = (genWithHighestPrio === null || genWithHighestPrio === void 0 ? void 0 : genWithHighestPrio.getUUID()) === synchronousMachine.getUUID();
310
+ const generatingUnit = synchronousMachine.generatingUnit;
311
+ /** KR-Zahl => (governorSCD * nominalP ) / (100 * 50hz) */
312
+ const kr = generatingUnit ? ((generatingUnit.governorSCD * generatingUnit.nominalP) / (100 * 50)) : 0;
313
+ const slackWeight = kr / (krInfo === null || krInfo === void 0 ? void 0 : krInfo.krSum);
314
+ if (isSlack) {
315
+ if (p !== 0) {
316
+ /** "name, bus, p_mw, q_mvar, sn_mva, scaling, in_service, type, current_source, in_service_date */
317
+ const sgen = [
318
+ common_utils_1.CommonUtils.generateUUID(),
319
+ busID,
320
+ p,
321
+ 0,
322
+ snMVA,
323
+ 1,
324
+ true,
325
+ '',
326
+ false,
327
+ null // in_service_date
328
+ ];
329
+ sgenData.data.push(sgen);
330
+ sgenData.index.push(sgenData.data.length - 1);
331
+ }
332
+ /** name, bus, vm_pu, va_degree, slack_weight, in_service, s_sc_max_mva,s_sc_min_mva,rx_min,rx_max,r0x0_max,x0x_max,r0x0_min,x0x_min,description */
333
+ const slack = [
334
+ synchronousMachine.getUUID(),
335
+ busID,
336
+ targetVoltage,
337
+ 0,
338
+ slackWeight ? slackWeight : 0,
339
+ true,
340
+ 0,
341
+ 0,
342
+ 0,
343
+ 0,
344
+ 0,
345
+ 0,
346
+ 0,
347
+ 0,
348
+ '',
349
+ synchronousMachine.key
350
+ ]; // key
351
+ extNetData.data.push(slack);
352
+ extNetData.index.push(extNetData.data.length - 1);
353
+ }
354
+ else {
355
+ /** name,bus,p_mw,vm_pu,sn_mva,min_q_mvar,max_q_mvar,scaling,slack,in_service,slack_weight,type*/
356
+ const gen = [
357
+ synchronousMachine.getUUID(),
358
+ busID,
359
+ //p < 0 ? p * -1 : p, // p_mw
360
+ p,
361
+ targetVoltage,
362
+ snMVA,
363
+ synchronousMachine.minQ,
364
+ synchronousMachine.maxQ,
365
+ 1,
366
+ //genWithHighestPrio?.getUUID() === synchronousMachine.getUUID() ? true : false, // slack
367
+ true,
368
+ true,
369
+ slackWeight ? slackWeight : 0,
370
+ 'sync',
371
+ synchronousMachine.key
372
+ ]; // min_p_mw
373
+ genData.data.push(gen);
374
+ genData.index.push(genData.data.length - 1);
375
+ }
376
+ }
377
+ }
378
+ for (const synchronousMachine of generatorsWithoutControl) {
379
+ if (PowerflowUtil.synchronousMachineUUIDs.includes(synchronousMachine.getUUID()))
380
+ continue;
381
+ for (const terminalValue of synchronousMachine.terminals.values()) {
382
+ const connectedNode = terminalValue.getConnectedNode();
383
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
384
+ if (busID !== undefined) {
385
+ // "name","bus","p_mw","q_mvar",
386
+ // "name","bus","p_mw","q_mvar","sn_mva","scaling","in_service","type","current_source", in_service_date
387
+ // [1, 0.0, 0.0,false,true,null,21.7,12.7,1.0,null,null];
388
+ // const sgen: any[] = [energySource.mrid, busID, p, q, 0, 1, true, (energySource.psrType?.name ?? ''), false, inServiceDate];
389
+ let p = isNaN(synchronousMachine.p) ? 0 : synchronousMachine.p;
390
+ let q = isNaN(synchronousMachine.q) ? 0 : synchronousMachine.q;
391
+ /** "name, bus, p_mw, q_mvar,sn_mva,scaling,in_service,type,current_source, in_service_date */
392
+ const sgen = [
393
+ synchronousMachine.mrid,
394
+ busID,
395
+ p, q,
396
+ snMVA,
397
+ 1,
398
+ true,
399
+ '',
400
+ false,
401
+ null
402
+ ];
403
+ sgenData.data.push(sgen);
404
+ sgenData.index.push(sgenData.data.length - 1);
405
+ }
406
+ }
407
+ }
408
+ /*for (const loadsNfeeders of tpLoadsNfeeders.values()) {
409
+ for (const entry of loadsNfeeders.entries()) {
410
+ const key = entry[0];
411
+ if (key.includes('SynchronousMachine')) {
412
+ const valuesArr = entry[1];
413
+ for (let i = 0; i < valuesArr.length; i++) {
414
+
415
+ const synchronousMachine = valuesArr[i] as SynchronousMachine;
416
+
417
+ const str = `${synchronousMachine.mrid}${synchronousMachine.key}`;
418
+
419
+ for (const terminalValue of synchronousMachine.terminals.values()) {
420
+ const connectedNode = terminalValue.getConnectedNode();
421
+
422
+ const busID = uuidToIndex.get(connectedNode?.mrid);
423
+ if (!busID) {
424
+ console.log(`${str} keine BusID`);
425
+ continue;
426
+ }
427
+ const baseV = PowerflowUtil.getBaseVoltageAsNumber(connectedNode);
428
+
429
+
430
+ let targetValue = baseV;
431
+ if (synchronousMachine.regulatingControl && synchronousMachine.regulatingControl.targetValue > 0) {
432
+ targetValue = synchronousMachine.regulatingControl.targetValue;
433
+ }
434
+
435
+ if (!synchronousMachine.regulatingControl?.targetValue) {
436
+ console.log(`${str} kein targetValue`);
437
+ continue;
438
+ }
439
+
440
+ targetValue = !isNaN(targetValue) ? targetValue : baseV;
441
+
442
+ const baseVoltage = baseV <= 0 ? defaultsConfig.data.line.default_u : baseV;
443
+ const targetVoltage = targetValue / baseVoltage;
444
+
445
+ const p = synchronousMachine.p || 0;
446
+ const q = synchronousMachine.q || 0;
447
+
448
+ if (synchronousMachine.controlEnabled === false) {
449
+ console.log(`${str} kein controlEnabled`);
450
+ continue;
451
+ }
452
+
453
+ const generatingUnit = synchronousMachine.generatingUnit;
454
+ /!** KR-Zahl => (governorSCD * nominalP ) / (100 * 50hz) *!/
455
+ const kr = generatingUnit ? ((generatingUnit.governorSCD * generatingUnit.nominalP) / (100 * 50)) : 0;
456
+ const slackWeight = kr / krInfo?.krSum;
457
+ /!** name,bus,p_mw,vm_pu,sn_mva,min_q_mvar,max_q_mvar,scaling,slack,in_service,slack_weight,type*!/
458
+ const gen: any[] = [
459
+ synchronousMachine.getUUID(), // name
460
+ busID, // bus
461
+ p * -1, // p_mw
462
+ targetVoltage, // vm_pu
463
+ synchronousMachine.ratedS, // sn_mva
464
+ synchronousMachine.minQ, // min_q_mvar
465
+ synchronousMachine.maxQ, // max_q_mvar
466
+ 1, // scaling
467
+ genWithHighestPrio?.getUUID() === synchronousMachine.getUUID() ? true : false, // slack
468
+ true, // in_service
469
+ slackWeight ? slackWeight : 0, // slack_weight
470
+ 'sync', // type,
471
+ synchronousMachine.key
472
+ ]; // min_p_mw
473
+ genData.data.push(gen);
474
+ genData.index.push(genData.data.length - 1);
475
+ }
476
+
477
+ console.log(`counter Ende ${counter++}`);
478
+ }
479
+ }
480
+ }
481
+ }*/
482
+ /** Stromkreisabschnitte anlegen */
483
+ const lineData = pandaDataFrame._object.line._object;
484
+ const lines = network.filter(it => it.constructor.name.includes('ACLineSegment'));
485
+ for (const l of lines) {
486
+ const acLineSegment = l;
487
+ const isConnected = acLineSegment.isConnected();
488
+ const connections = acLineSegment.getBusConnections();
489
+ if (connections.length !== 2)
490
+ continue;
491
+ const start = connections[0];
492
+ const ziel = connections[1];
493
+ if (!uuidToIndex.has(start.mrid) || !uuidToIndex.has(ziel.mrid))
494
+ continue;
495
+ const busFromID = uuidToIndex.get(start.mrid);
496
+ const busToID = uuidToIndex.get(ziel.mrid);
497
+ /** bei Fehlen der der Anschluesse wird der Stromkreisabschnitt ignoriert */
498
+ if (!(busFromID > -1 && busToID > -1)) {
499
+ console.log(`ACLineSegment uuid ${acLineSegment.mrid} name ${acLineSegment.name} is not connected`);
500
+ continue;
501
+ }
502
+ const infoImpedances = cim_model_assetinfo_util_1.CimModelAssetinfoUtil.getElectricPropertiesACLineSegmentFromInfo(acLineSegment);
503
+ const infoImpedance = (infoImpedances === null || infoImpedances === void 0 ? void 0 : infoImpedances.length) ? infoImpedances[0] : undefined;
504
+ const initCurrentLimit = acLineSegment.getCurrentLimit() ? acLineSegment.getCurrentLimit() : infoImpedance === null || infoImpedance === void 0 ? void 0 : infoImpedance.ratedCurrent;
505
+ const initX = +acLineSegment.x ? +acLineSegment.x : infoImpedance === null || infoImpedance === void 0 ? void 0 : infoImpedance.x;
506
+ const initR = +acLineSegment.r ? +acLineSegment.r : infoImpedance === null || infoImpedance === void 0 ? void 0 : infoImpedance.r;
507
+ /** Länge */
508
+ const initLength = +acLineSegment.length ? +acLineSegment.length : infoImpedance === null || infoImpedance === void 0 ? void 0 : infoImpedance.length;
509
+ const length = +initLength < 1 ? defaultsConfig['line'].default_length : +initLength;
510
+ /** Reactance / Reaktanz / Blindwiderstand */
511
+ const x = +initX === 0 ? defaultsConfig['line'].default_x : +initX / length;
512
+ /** Resistance / Wirkwiderstand */
513
+ const r = +initR === 0 ? defaultsConfig['line'].default_r : +initR / length;
514
+ const c = (Math.abs(acLineSegment.bch) / (2 * 50 * Math.PI * length) * Math.pow(1000, 3));
515
+ const g = 0;
516
+ /** CurrentLimt / Strombelastbarkeit */
517
+ const ir = (initCurrentLimit <= 0 ? defaultsConfig['line'].default_ir : initCurrentLimit) / 1000;
518
+ /** Typ des Stromkreisabschnittes. Default Freileitung
519
+ * cs - Kabel
520
+ * ol - Freileitung */
521
+ const type = ((_d = acLineSegment.psrType) === null || _d === void 0 ? void 0 : _d.name) === cim_constants_1.CimAssetAliasNames.Cable ? 'cs' : 'ol';
522
+ const baseVoltage = (_f = (_e = acLineSegment.baseVoltage) === null || _e === void 0 ? void 0 : _e.nominalVoltage) === null || _f === void 0 ? void 0 : _f.value;
523
+ const stdType = this.createPandaPowerTypeFromValues(pandaDataFrame, type, baseVoltage, ir, x, r, c);
524
+ /** PandaPower-Line-Objekt erstellen */
525
+ const line = [
526
+ acLineSegment.mrid,
527
+ null,
528
+ uuidToIndex.get(start.mrid),
529
+ uuidToIndex.get(ziel.mrid),
530
+ length,
531
+ r < 0.001 ? 0.001 : r,
532
+ x < 0.001 ? 0.001 : x,
533
+ c, g,
534
+ ir,
535
+ 1,
536
+ 1,
537
+ 'cs',
538
+ isConnected,
539
+ 0,
540
+ 100,
541
+ '',
542
+ 0,
543
+ 0,
544
+ 0,
545
+ 0,
546
+ 0,
547
+ 0,
548
+ '',
549
+ null // geo
550
+ ];
551
+ lineData.data.push(line);
552
+ lineData.index.push(lineData.data.length - 1);
553
+ }
554
+ const xwardData = pandaDataFrame._object.xward._object;
555
+ /** ElementWithTargetVoltageKr -> XWard */
556
+ for (const equivalentInjection of krInfo.wardsWithTargetVoltageKr) {
557
+ //console.log(`${equivalentInjection.mrid};${equivalentInjection.key};${equivalentInjection.regulationStatus};${equivalentInjection.regulationTarget};${(equivalentInjection as INTEGRALEquivalentInjection)?.kr};${equivalentInjection.p};${equivalentInjection.q}`);
558
+ for (const terminalValue of equivalentInjection.terminals.values()) {
559
+ const connectedNode = terminalValue.getConnectedNode();
560
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
561
+ if (busID !== undefined) {
562
+ const baseV = PowerflowUtil.getBaseVoltageAsNumber(connectedNode);
563
+ let targetValue = equivalentInjection.regulationTarget;
564
+ targetValue = !isNaN(targetValue) ? targetValue : baseV;
565
+ const baseVoltage = baseV <= 0 ? defaultsConfig.data.line.default_u : baseV;
566
+ const targetVoltage = targetValue / baseVoltage;
567
+ const p = equivalentInjection.p || 0;
568
+ const q = equivalentInjection.q || 0;
569
+ const kr = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.kr;
570
+ const slackWeight = kr / (krInfo === null || krInfo === void 0 ? void 0 : krInfo.krSum);
571
+ const ps_mw = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.p_bel;
572
+ const qs_mvar = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.q_bel;
573
+ const pz_mw = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.p_ki;
574
+ const qz_mvar = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.q_ki;
575
+ // const r_ohm = (equivalentInjection as INTEGRALEquivalentInjection)?.rExt;
576
+ // const x_ohm = (equivalentInjection as INTEGRALEquivalentInjection)?.xExt;
577
+ const r_ohm = equivalentInjection.r;
578
+ const x_ohm = equivalentInjection.x;
579
+ const xward = [
580
+ equivalentInjection.getUUID(),
581
+ busID,
582
+ ps_mw,
583
+ qs_mvar,
584
+ qz_mvar,
585
+ pz_mw,
586
+ r_ohm,
587
+ x_ohm,
588
+ targetVoltage,
589
+ slackWeight,
590
+ true,
591
+ equivalentInjection.key // key
592
+ ];
593
+ xwardData.data.push(xward);
594
+ xwardData.index.push(xwardData.data.length - 1);
595
+ }
596
+ }
597
+ }
598
+ for (const equivalentInjection of krInfo.wardsWithTargetVoltageOnly) {
599
+ //console.log(`${equivalentInjection.mrid};${equivalentInjection.key};${equivalentInjection.regulationStatus};${equivalentInjection.regulationTarget};${(equivalentInjection as INTEGRALEquivalentInjection)?.kr};${equivalentInjection.p};${equivalentInjection.q}`);
600
+ for (const terminalValue of equivalentInjection.terminals.values()) {
601
+ const connectedNode = terminalValue.getConnectedNode();
602
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
603
+ if (busID !== undefined) {
604
+ const baseV = PowerflowUtil.getBaseVoltageAsNumber(connectedNode);
605
+ let targetValue = equivalentInjection.regulationTarget;
606
+ targetValue = !isNaN(targetValue) ? targetValue : baseV;
607
+ const baseVoltage = baseV <= 0 ? defaultsConfig.data.line.default_u : baseV;
608
+ const targetVoltage = targetValue / baseVoltage;
609
+ const slackWeight = 0;
610
+ const ps_mw = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.p_bel;
611
+ const qs_mvar = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.q_bel;
612
+ const pz_mw = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.p_ki;
613
+ const qz_mvar = equivalentInjection === null || equivalentInjection === void 0 ? void 0 : equivalentInjection.q_ki;
614
+ const r_ohm = equivalentInjection.r;
615
+ const x_ohm = equivalentInjection.x;
616
+ /** name,bus,ps_mw,qs_mvar,qz_mvar,pz_mw,r_ohm,x_ohm,vm_pu,slack_weight,in_service */
617
+ const xward = [
618
+ equivalentInjection.getUUID(),
619
+ busID,
620
+ ps_mw,
621
+ qs_mvar,
622
+ qz_mvar,
623
+ pz_mw,
624
+ r_ohm,
625
+ x_ohm,
626
+ targetVoltage,
627
+ slackWeight,
628
+ true,
629
+ equivalentInjection.key // key
630
+ ];
631
+ xwardData.data.push(xward);
632
+ xwardData.index.push(xwardData.data.length - 1);
633
+ }
634
+ }
635
+ }
636
+ /** elementWithKrOnly -> Gen */
637
+ for (const equivalentInjection of krInfo.wardsWithKrOnly) {
638
+ const str = `${equivalentInjection.mrid} ${equivalentInjection.key}`;
639
+ // TODO
640
+ console.log('WardsWithKrOnly ist nicht implementiert', str);
641
+ }
642
+ /** EquivalentBranch/Ersatzlängszweige anlegen */
643
+ const impedanceData = pandaDataFrame._object.impedance._object;
644
+ const equivalentBranches = network.filter(it => it instanceof EquivalentBranch_1.EquivalentBranch);
645
+ for (const equivalentBranch of equivalentBranches) {
646
+ //Prüfen, ob die Terminals geschlossen sind.
647
+ const isConnected = equivalentBranch.isConnected();
648
+ const connections = equivalentBranch.getBusConnections();
649
+ if (connections.length !== 2)
650
+ continue;
651
+ const start = connections[0];
652
+ const ziel = connections[1];
653
+ if (!uuidToIndex.has(start.mrid) || !uuidToIndex.has(ziel.mrid))
654
+ continue;
655
+ const r21 = equivalentBranch.r21 ? equivalentBranch.r21 : equivalentBranch.r;
656
+ const x21 = equivalentBranch.x21 ? equivalentBranch.x21 : equivalentBranch.x;
657
+ const zeroR12 = equivalentBranch.zeroR12;
658
+ const zeroX12 = equivalentBranch.zeroX12;
659
+ const zeroR21 = equivalentBranch.r21 ? equivalentBranch.r21 : zeroR12;
660
+ const zeroX21 = equivalentBranch.x21 ? equivalentBranch.x21 : zeroX12;
661
+ const snMVA = pandaDataFrame._object.sn_mva;
662
+ const z_base = Math.pow((_h = (_g = equivalentBranch.baseVoltage) === null || _g === void 0 ? void 0 : _g.nominalVoltage) === null || _h === void 0 ? void 0 : _h.value, 2) / snMVA;
663
+ const rft_pu = equivalentBranch.r / z_base;
664
+ const xft_pu = equivalentBranch.x / z_base;
665
+ const rtf_pu = r21 / z_base;
666
+ const xtf_pu = x21 / z_base;
667
+ const rft0_pu = zeroR12 / z_base;
668
+ const xft0_pu = zeroX12 / z_base;
669
+ const rtf0_pu = zeroR21 / z_base;
670
+ const xtf0_pu = zeroX21 / z_base;
671
+ const busFromID = uuidToIndex.get(start.mrid);
672
+ const busToID = uuidToIndex.get(ziel.mrid);
673
+ /** [name, from_bus, to_bus, rft_pu, xft_pu, rtf_pu, xtf_pu, sn_mva, in_service] */
674
+ /** name, from_bus, to_bus, rft_pu, xft_pu, rtf_pu, xtf_pu, sn_mva, in_service*/
675
+ if (isNaN(rft_pu) || rft_pu === 0) {
676
+ console.log(`rft_pu ${rft_pu}`);
677
+ }
678
+ if (isNaN(xft_pu) || xft_pu === 0) {
679
+ console.log(`xft_pu ${xft_pu}`);
680
+ }
681
+ if (isNaN(rtf_pu) || rtf_pu === 0) {
682
+ console.log(`rtf_pu ${rtf_pu}`);
683
+ }
684
+ if (isNaN(xtf_pu) || xtf_pu === 0) {
685
+ console.log(`xtf_pu ${xtf_pu}`);
686
+ }
687
+ const data = [equivalentBranch.getUUID(), busFromID, busToID, rft_pu, xft_pu, rtf_pu, xtf_pu, snMVA, true, equivalentBranch.key];
688
+ impedanceData.data.push(data);
689
+ impedanceData.index.push(impedanceData.data.length - 1);
690
+ }
691
+ /** Transformatoren 2W anlegen */
692
+ const trafoData = pandaDataFrame._object.trafo._object;
693
+ const powerTransformers = network.filter(it => it.constructor.name.includes('PowerTransformer'));
694
+ for (const powerTransformer of powerTransformers) {
695
+ const trafoW2 = powerTransformer;
696
+ const connections = trafoW2.getBusConnections();
697
+ if (connections.length > 2)
698
+ continue; // Trafo 3W
699
+ const start = connections[0];
700
+ const ziel = connections[1];
701
+ if (!uuidToIndex.has(start.mrid) || !uuidToIndex.has(ziel.mrid))
702
+ continue;
703
+ const busFromID = uuidToIndex.get(start.mrid);
704
+ const busToID = uuidToIndex.get(ziel.mrid);
705
+ const powerTransformerEnd1 = trafoW2.powerTransformerEnd[0];
706
+ const powerTransformerEnd2 = trafoW2.powerTransformerEnd[1];
707
+ const w1_un = trafoW2.powerTransformerEnd[0].baseVoltage.nominalVoltage.value;
708
+ const w2_un = trafoW2.powerTransformerEnd[1].baseVoltage.nominalVoltage.value;
709
+ const s = trafoW2.powerTransformerEnd[0].ratedS;
710
+ const shiftDegree = isNaN(powerTransformerEnd1.phaseAngleClock) ? powerTransformerEnd2.phaseAngleClock : powerTransformerEnd1.phaseAngleClock;
711
+ if (powerTransformerEnd1.x === 0) {
712
+ console.log(`PowerTransformer ${trafoW2.getUUID()} x is not defined!`);
713
+ continue;
714
+ }
715
+ const trafoTypes = pandaDataFrame._object.std_types.trafo;
716
+ let stdType = PowerflowUtil.createStdTypeTrafo2WFromValues(pandaDataFrame._object.std_types.trafo, w1_un, w2_un, s);
717
+ if (!stdType) {
718
+ // console.log(`kein Trafo2W Assettype gefunden UUID ${trafoW2.mrid} S ${s} Ur1 ${w1_un} Ur2 ${w2_un}`);
719
+ /** Lege den fehlenden Trafotyp automatisch an. */
720
+ /** iron losses in kW */
721
+ let pfeKw = (powerTransformerEnd1.g * Math.pow(powerTransformerEnd1.ratedU, 2) +
722
+ powerTransformerEnd2.g * Math.pow(powerTransformerEnd2.ratedU, 2)) * 1000;
723
+ // pfeKw = 0;
724
+ /** real component of short circuit voltage [%] */
725
+ const vkrPercent = Math.abs(powerTransformerEnd1.r) * powerTransformerEnd1.ratedS * 100 / Math.pow(powerTransformerEnd1.ratedU, 2) +
726
+ Math.abs(powerTransformerEnd2.r) * powerTransformerEnd1.ratedS * 100 / Math.pow(powerTransformerEnd2.ratedU, 2);
727
+ /** short circuit voltage [%] */
728
+ const transformerEnd1SignX = Math.sign(powerTransformerEnd1.x) === 0 ? 1 : Math.sign(powerTransformerEnd1.x);
729
+ const transformerEnd2SignX = Math.sign(powerTransformerEnd2.x) === 0 ? 1 : Math.sign(powerTransformerEnd2.x);
730
+ let vkPercent = Math.pow(Math.pow(powerTransformerEnd1.r, 2) + Math.pow(powerTransformerEnd1.x, 2), 0.5) *
731
+ (powerTransformerEnd1.ratedS * 1000) / (10 * Math.pow(powerTransformerEnd1.ratedU, 2)) +
732
+ Math.pow(Math.pow(powerTransformerEnd2.r, 2) + Math.pow(powerTransformerEnd2.x, 2), 0.5) *
733
+ (powerTransformerEnd1.ratedS * 1000 / (10 * Math.pow(powerTransformerEnd2.ratedU, 2)));
734
+ vkPercent = vkPercent * transformerEnd1SignX;
735
+ vkPercent = vkPercent * transformerEnd2SignX;
736
+ /** open loop losses in [%] */
737
+ let i0Percent = Math.pow(Math.pow(Math.pow(powerTransformerEnd1.b * Math.pow(powerTransformerEnd1.ratedU, 2), 2) +
738
+ Math.pow(powerTransformerEnd1.g * Math.pow(powerTransformerEnd1.ratedU, 2), 2), 0.5) +
739
+ Math.pow(powerTransformerEnd2.b * Math.pow(powerTransformerEnd2.ratedU, 2), 2) +
740
+ Math.pow(powerTransformerEnd2.g * Math.pow(powerTransformerEnd2.ratedU, 2), 2), 0.5) * 100 / powerTransformerEnd1.ratedS;
741
+ //i0Percent = 0;
742
+ const shiftDegree = isNaN(powerTransformerEnd1.phaseAngleClock) ? powerTransformerEnd2.phaseAngleClock : powerTransformerEnd1.phaseAngleClock;
743
+ const vectorGroup = (powerTransformerEnd1.connectionKind + '') + (powerTransformerEnd2.connectionKind + '');
744
+ stdType = {
745
+ key: `${trafoW2.mrid}`,
746
+ value: {
747
+ shift_degree: shiftDegree,
748
+ vector_group: vectorGroup,
749
+ vn_hv_kv: powerTransformerEnd1.ratedU,
750
+ pfe_kw: pfeKw,
751
+ i0_percent: i0Percent,
752
+ vn_lv_kv: powerTransformerEnd2.ratedU,
753
+ sn_mva: powerTransformerEnd1.ratedS,
754
+ tap_step_degree: 0,
755
+ tap_neutral: 0,
756
+ tap_min: 0,
757
+ vkr_percent: vkrPercent,
758
+ tap_step_percent: 0.0,
759
+ tap_side: 'hv',
760
+ tap_phase_shifter: false,
761
+ tap_max: 0,
762
+ vk_percent: vkPercent
763
+ }
764
+ };
765
+ // @ts-ignore
766
+ trafoTypes[`${trafoW2.mrid}`] = stdType.value;
767
+ }
768
+ if (busFromID > -1 && busToID > -1) {
769
+ /** name,std_type,hv_bus,lv_bus,sn_mva,vn_hv_kv,vn_lv_kv,vk_percent,vkr_percent,pfe_kw,i0_percent,
770
+ * shift_degree,tap_side,tap_neutral,tap_min,tap_max,tap_step_percent,tap_step_degree,tap_pos,
771
+ * tap_phase_shifter,parallel,df,in_service,tap_set_vm_pu,description,equipment,vector_group,
772
+ * vk0_percent,vkr0_percent,mag0_percent,mag0_rx,si0_hv_partial*/
773
+ const trafo = [
774
+ trafoW2.getUUID(),
775
+ stdType.key,
776
+ busFromID,
777
+ busToID,
778
+ stdType.value['sn_mva'],
779
+ w1_un,
780
+ w2_un,
781
+ stdType.value['vk_percent'],
782
+ stdType.value['vkr_percent'],
783
+ stdType.value['pfe_kw'],
784
+ stdType.value['i0_percent'],
785
+ stdType.value['shift_degree'],
786
+ 'hv',
787
+ stdType.value['tap_neutral'],
788
+ stdType.value['tap_min'],
789
+ stdType.value['tap_max'],
790
+ 1.3,
791
+ stdType.value['tap_step_degree'],
792
+ 0,
793
+ stdType.value['tap_phase_shifter'],
794
+ 1,
795
+ 1,
796
+ true,
797
+ 1,
798
+ '',
799
+ '',
800
+ '',
801
+ '',
802
+ 0,
803
+ 0,
804
+ 0,
805
+ 1,
806
+ start.mrid,
807
+ ziel.mrid // lv_bus_uuid
808
+ ];
809
+ trafoData.data.push(trafo);
810
+ trafoData.index.push(trafoData.data.length - 1);
811
+ }
812
+ }
813
+ /** Transformatoren 3W anlegen */
814
+ const trafoData3W = pandaDataFrame._object.trafo3w._object;
815
+ for (const powerTransformer of powerTransformers) {
816
+ const trafoW3 = powerTransformer;
817
+ const connections = trafoW3.getBusConnections();
818
+ if (connections.length !== 3)
819
+ continue;
820
+ const busW1 = connections[0];
821
+ const busW2 = connections[1];
822
+ const busW3 = connections[2];
823
+ if (!(uuidToIndex.has(busW1.mrid) && uuidToIndex.has(busW2.mrid) && uuidToIndex.has(busW3.mrid)))
824
+ continue;
825
+ const powerTransformerEnd1 = trafoW3.powerTransformerEnd[0];
826
+ const powerTransformerEnd2 = trafoW3.powerTransformerEnd[1];
827
+ const powerTransformerEnd3 = trafoW3.powerTransformerEnd[2];
828
+ const busW1ID = uuidToIndex.get(busW1.mrid);
829
+ const busW2ID = uuidToIndex.get(busW2.mrid);
830
+ const busW3ID = uuidToIndex.get(busW3.mrid);
831
+ const w1Ur = (_l = (_k = (_j = trafoW3.powerTransformerEnd[0]) === null || _j === void 0 ? void 0 : _j.baseVoltage) === null || _k === void 0 ? void 0 : _k.nominalVoltage) === null || _l === void 0 ? void 0 : _l.value;
832
+ const w2Ur = (_p = (_o = (_m = trafoW3.powerTransformerEnd[1]) === null || _m === void 0 ? void 0 : _m.baseVoltage) === null || _o === void 0 ? void 0 : _o.nominalVoltage) === null || _p === void 0 ? void 0 : _p.value;
833
+ const w3Ur = (_s = (_r = (_q = trafoW3.powerTransformerEnd[2]) === null || _q === void 0 ? void 0 : _q.baseVoltage) === null || _r === void 0 ? void 0 : _r.nominalVoltage) === null || _s === void 0 ? void 0 : _s.value;
834
+ const w1Sr = (_t = trafoW3 === null || trafoW3 === void 0 ? void 0 : trafoW3.powerTransformerEnd[0]) === null || _t === void 0 ? void 0 : _t.ratedS;
835
+ const w2Sr = (_u = trafoW3 === null || trafoW3 === void 0 ? void 0 : trafoW3.powerTransformerEnd[1]) === null || _u === void 0 ? void 0 : _u.ratedS;
836
+ const w3Sr = (_v = trafoW3 === null || trafoW3 === void 0 ? void 0 : trafoW3.powerTransformerEnd[2]) === null || _v === void 0 ? void 0 : _v.ratedS;
837
+ const minSHvMv = Math.min(w1Sr, w2Sr);
838
+ const minSMvLv = Math.min(w2Sr, w3Sr);
839
+ const minSLvHv = Math.min(w1Sr, w3Sr);
840
+ const pfeKw = (powerTransformerEnd1.g * Math.pow(powerTransformerEnd1.ratedU, 2) +
841
+ powerTransformerEnd2.g * Math.pow(powerTransformerEnd2.ratedU, 2) +
842
+ powerTransformerEnd3.g * Math.pow(powerTransformerEnd3.ratedU, 2)) * 1000;
843
+ const vkrHvPercent = (powerTransformerEnd1.r + powerTransformerEnd2.r * Math.pow(powerTransformerEnd1.ratedU / powerTransformerEnd2.ratedU, 2)) *
844
+ minSHvMv * 100 / Math.pow(powerTransformerEnd1.ratedU, 2);
845
+ let vkrMvPercent = (powerTransformerEnd2.r + powerTransformerEnd3.r * Math.pow(powerTransformerEnd2.ratedU / powerTransformerEnd3.ratedU, 2)) *
846
+ minSMvLv * 100 / Math.pow(powerTransformerEnd2.ratedU, 2);
847
+ if (vkrMvPercent < 0) {
848
+ vkrMvPercent = 0;
849
+ }
850
+ const vkrLvPercent = (powerTransformerEnd3.r + powerTransformerEnd1.r * Math.pow(powerTransformerEnd3.ratedU / powerTransformerEnd1.ratedU, 2)) *
851
+ minSLvHv * 100 / Math.pow(powerTransformerEnd3.ratedU, 2);
852
+ const vkHvPercent = Math.pow(powerTransformerEnd1.r + powerTransformerEnd2.r * Math.pow(Math.pow((powerTransformerEnd1.ratedU / powerTransformerEnd2.ratedU), 2), 2) +
853
+ Math.pow(powerTransformerEnd1.x + powerTransformerEnd2.x * Math.pow(powerTransformerEnd1.ratedU / powerTransformerEnd2.ratedU, 2), 2), 0.5) *
854
+ minSHvMv * 100 / Math.pow(powerTransformerEnd1.ratedU, 2);
855
+ const vkMvPercent = Math.pow(powerTransformerEnd2.r + powerTransformerEnd3.r * Math.pow(Math.pow((powerTransformerEnd2.ratedU / powerTransformerEnd3.ratedU), 2), 2) +
856
+ Math.pow(powerTransformerEnd2.x + powerTransformerEnd3.x * Math.pow(powerTransformerEnd2.ratedU / powerTransformerEnd3.ratedU, 2), 2), 0.5) *
857
+ minSMvLv * 100 / Math.pow(powerTransformerEnd2.ratedU, 2);
858
+ const vkLvPercent = Math.pow(powerTransformerEnd3.r + powerTransformerEnd1.r * Math.pow(Math.pow((powerTransformerEnd3.ratedU / powerTransformerEnd1.ratedU), 2), 2) +
859
+ Math.pow(powerTransformerEnd3.x + powerTransformerEnd1.x * Math.pow(powerTransformerEnd3.ratedU / powerTransformerEnd1.ratedU, 2), 2), 0.5) *
860
+ minSLvHv * 100 / Math.pow(powerTransformerEnd3.ratedU, 2);
861
+ const i0Percent = (Math.pow(Math.pow(powerTransformerEnd1.b * Math.pow(powerTransformerEnd1.ratedU, 2), 2) +
862
+ Math.pow(powerTransformerEnd1.g * Math.pow(powerTransformerEnd1.ratedU, 2), 2), 0.5) +
863
+ Math.pow(Math.pow(powerTransformerEnd2.b * Math.pow(powerTransformerEnd2.ratedU, 2), 2) +
864
+ Math.pow(powerTransformerEnd2.g * Math.pow(powerTransformerEnd2.ratedU, 2), 2), 0.5) +
865
+ Math.pow(Math.pow(powerTransformerEnd3.b * Math.pow(powerTransformerEnd3.ratedU, 2), 2) +
866
+ Math.pow(powerTransformerEnd3.g * Math.pow(powerTransformerEnd3.ratedU, 2), 2), 0.5)) * 100 / powerTransformerEnd1.ratedS;
867
+ const shiftMvDegree = powerTransformerEnd2.phaseAngleClock * 30;
868
+ const shiftLvDegree = powerTransformerEnd3.phaseAngleClock * 30;
869
+ const vectorGroup = powerTransformerEnd1.connectionKind + '' + powerTransformerEnd2.connectionKind + '' + powerTransformerEnd3.connectionKind + '';
870
+ const stdType = {
871
+ key: `${trafoW3.mrid}`,
872
+ value: {
873
+ 'vector_group': vectorGroup,
874
+ 'vn_mv_kv': powerTransformerEnd2.ratedU,
875
+ 'vn_lv_kv': powerTransformerEnd3.ratedU,
876
+ 'shift_lv_degree': shiftLvDegree,
877
+ 'shift_mv_degree': shiftMvDegree,
878
+ 'pfe_kw': pfeKw,
879
+ 'vn_hv_kv': powerTransformerEnd1.ratedU,
880
+ 'i0_percent': i0Percent,
881
+ 'sn_lv_mva': powerTransformerEnd3.ratedS,
882
+ 'sn_hv_mva': powerTransformerEnd1.ratedS,
883
+ 'sn_mv_mva': powerTransformerEnd2.ratedS,
884
+ 'vkr_lv_percent': vkrLvPercent,
885
+ 'tap_neutral': 0,
886
+ 'tap_min': 0,
887
+ 'vk_mv_percent': vkMvPercent,
888
+ 'vkr_hv_percent': vkrHvPercent,
889
+ 'vk_lv_percent': vkLvPercent,
890
+ 'tap_max': 0,
891
+ 'vkr_mv_percent': vkrMvPercent,
892
+ 'tap_step_percent': 0,
893
+ 'tap_side': 'hv',
894
+ 'vk_hv_percent': vkHvPercent
895
+ }
896
+ };
897
+ if (!(busW1ID > -1 && busW2ID > -1 && busW3ID > -1))
898
+ continue;
899
+ /**
900
+ name,std_type,hv_bus,mv_bus,lv_bus,sn_hv_mva,sn_mv_mva,sn_lv_mva,vn_hv_kv,vn_mv_kv,vn_lv_kv,vk_hv_percent,
901
+ vk_mv_percent,vk_lv_percent,vkr_hv_percent,vkr_mv_percent,vkr_lv_percent,
902
+ pfe_kw,i0_percent,shift_mv_degree,
903
+ shift_lv_degree,tap_side,tap_neutral,
904
+ tap_min,tap_max,tap_step_percent,tap_step_degree,tap_pos,tap_at_star_point,
905
+ in_service
906
+ /** */
907
+ const trafo = [
908
+ trafoW3.mrid,
909
+ null,
910
+ busW1ID,
911
+ busW2ID,
912
+ busW3ID,
913
+ stdType.value['sn_hv_mva'],
914
+ stdType.value['sn_mv_mva'],
915
+ stdType.value['sn_lv_mva'],
916
+ stdType.value['vn_hv_kv'],
917
+ stdType.value['vn_mv_kv'],
918
+ stdType.value['vn_lv_kv'],
919
+ stdType.value['vk_hv_percent'],
920
+ stdType.value['vk_mv_percent'],
921
+ stdType.value['vk_lv_percent'],
922
+ stdType.value['vkr_hv_percent'],
923
+ stdType.value['vkr_mv_percent'],
924
+ stdType.value['vkr_lv_percent'],
925
+ stdType.value['pfe_kw'],
926
+ stdType.value['i0_percent'],
927
+ stdType.value['shift_mv_degree'],
928
+ stdType.value['shift_lv_degree'],
929
+ 'hv',
930
+ stdType.value['tap_neutral'],
931
+ stdType.value['tap_min'],
932
+ stdType.value['tap_max'],
933
+ stdType.value['tap_step_percent'],
934
+ stdType.value['tap_step_degree'],
935
+ 0,
936
+ false,
937
+ true,
938
+ busW1.mrid,
939
+ busW2.mrid,
940
+ busW3.mrid // lv_bus_uuid
941
+ ];
942
+ trafoData3W.data.push(trafo);
943
+ trafoData3W.index.push(trafoData3W.data.length - 1);
944
+ }
945
+ /** Laengsdrossel anlegen */
946
+ const seriesCompensators = network.filter(it => it.constructor.name.includes('SeriesCompensator'));
947
+ for (const sc of seriesCompensators) {
948
+ const seriesCompensator = sc;
949
+ const isConnected = seriesCompensator.isConnected();
950
+ const connections = seriesCompensator.getBusConnections();
951
+ if (connections.length !== 2)
952
+ continue;
953
+ const start = connections[0];
954
+ const ziel = connections[1];
955
+ if (!uuidToIndex.has(start.mrid) || !uuidToIndex.has(ziel.mrid))
956
+ continue;
957
+ const busFromID = uuidToIndex.get(start.mrid);
958
+ const busToID = uuidToIndex.get(ziel.mrid);
959
+ const z_base = Math.pow((_x = (_w = seriesCompensator.baseVoltage) === null || _w === void 0 ? void 0 : _w.nominalVoltage) === null || _x === void 0 ? void 0 : _x.value, 2) / snMVA;
960
+ const rft_pu = seriesCompensator.r / z_base;
961
+ const xft_pu = seriesCompensator.x / z_base;
962
+ const rtf_pu = seriesCompensator.r / z_base;
963
+ const xtf_pu = seriesCompensator.x / z_base;
964
+ const rft0_pu = seriesCompensator.r0 / z_base;
965
+ const xft0_pu = seriesCompensator.x0 / z_base;
966
+ const rtf0_pu = seriesCompensator.r0 / z_base;
967
+ const xtf0_pu = seriesCompensator.x0 / z_base;
968
+ /** name, from_bus, to_bus, rft_pu, xft_pu, rtf_pu, xtf_pu, sn_mva, in_service */
969
+ /** name, from_bus, to_bus, rft_pu, xft_pu, rtf_pu, xtf_pu, sn_mva, in_service */
970
+ if (isNaN(rft_pu) || rft_pu === 0) {
971
+ console.log(`rft_pu ${rft_pu}`);
972
+ }
973
+ if (isNaN(xft_pu) || xft_pu === 0) {
974
+ console.log(`xft_pu ${xft_pu}`);
975
+ }
976
+ if (isNaN(rtf_pu) || rtf_pu === 0) {
977
+ console.log(`rtf_pu ${rtf_pu}`);
978
+ }
979
+ if (isNaN(xtf_pu) || xtf_pu === 0) {
980
+ console.log(`xtf_pu ${xtf_pu}`);
981
+ }
982
+ const data = [seriesCompensator.getUUID(), busFromID, busToID, rft_pu, xft_pu, rtf_pu, xtf_pu, snMVA, true, seriesCompensator.key];
983
+ impedanceData.data.push(data);
984
+ impedanceData.index.push(impedanceData.data.length - 1);
985
+ }
986
+ /** Kompensationsanlagen anlegen */
987
+ const shuntData = pandaDataFrame._object.shunt._object;
988
+ const linearShuntCompensators = network.filter(it => it instanceof LinearShuntCompensator_1.LinearShuntCompensator);
989
+ for (const linearShuntCompensator of linearShuntCompensators) {
990
+ /** regelbare Kompensationsanlagen */
991
+ if (!((_y = linearShuntCompensator.regulatingControl) === null || _y === void 0 ? void 0 : _y.targetValue)) {
992
+ // console.log(`LinearShuntCompensator ${linearShuntCompensator.getUUID()} kein targetValue`);
993
+ //continue;
994
+ }
995
+ const targetValue = (_z = linearShuntCompensator.regulatingControl) === null || _z === void 0 ? void 0 : _z.targetValue;
996
+ /** bus, name, q_mvar, p_mw, vn_kv, step, max_step, in_service */
997
+ for (const terminalValue of linearShuntCompensator.terminals.values()) {
998
+ const connectedNode = terminalValue.getConnectedNode();
999
+ const baseV = PowerflowUtil.getBaseVoltageAsNumber(connectedNode);
1000
+ const baseVoltage = baseV <= 0 ? defaultsConfig.data.line.default_u : baseV;
1001
+ //const targetVoltage = targetValue / baseVoltage;
1002
+ const baseVoltageNominal = linearShuntCompensator.nomU;
1003
+ const baseVoltageNominalPowTwo = Math.pow(baseVoltageNominal, 2);
1004
+ const busID = uuidToIndex.get(connectedNode === null || connectedNode === void 0 ? void 0 : connectedNode.mrid);
1005
+ const p_real = linearShuntCompensator.gPerSection;
1006
+ const p_imag = (linearShuntCompensator.bPerSection * baseVoltageNominalPowTwo) * -1;
1007
+ const voltage_real = baseVoltageNominalPowTwo;
1008
+ const voltage_imag = 0;
1009
+ /* eqssh_shunts = eqssh_shunts.rename(columns={
1010
+ 'rdfId': sc['o_id'], 'rdfId_Terminal': sc['t'], 'connected': 'in_service', 'index_bus': 'bus',
1011
+ 'nomU': 'vn_kv',
1012
+ 'sections': 'step',
1013
+ 'maximumSections': 'max_step'})
1014
+ y = eqssh_shunts['gPerSection'] + eqssh_shunts['bPerSection'] * 1j
1015
+ s = eqssh_shunts['vn_kv'] ** 2 * np.conj(y)
1016
+ eqssh_shunts['p_mw'] = s.values.real
1017
+ eqssh_shunts['q_mvar'] = s.values.imag*/
1018
+ const p = p_real * voltage_imag + p_imag * voltage_real;
1019
+ const q = p_real * voltage_real - p_imag * voltage_imag;
1020
+ if (isNaN(linearShuntCompensator.sections)) {
1021
+ console.log();
1022
+ }
1023
+ /** [\"bus\",\"name\",\"q_mvar\",\"p_mw\",\"vn_kv\",\"step\",\"max_step\",\"in_service\"] */
1024
+ const shunt = [
1025
+ busID,
1026
+ linearShuntCompensator.getUUID(),
1027
+ q,
1028
+ p,
1029
+ linearShuntCompensator.nomU,
1030
+ isNaN(linearShuntCompensator.sections) ? linearShuntCompensator.normalSections : linearShuntCompensator.sections,
1031
+ linearShuntCompensator.maximumSections,
1032
+ linearShuntCompensator.sections > 0 ? true : false // in_service
1033
+ ];
1034
+ /* shuntData.data.push(shunt);
1035
+ shuntData.index.push(shuntData.data.length - 1);*/
1036
+ }
1037
+ }
1038
+ /** Schaltelemente */
1039
+ /** Speichert die berücksichtgten Schaltelemente
1040
+ * Später wird diese Map verwendet, um spannungslose Switches zu bestimmen und ins Netzmodell aufzunehmen */
1041
+ const consideredSwitches = new Map();
1042
+ const switchData = pandaDataFrame._object.switch._object;
1043
+ const switches = network.filter(it => it instanceof Switch_1.Switch);
1044
+ for (const swtch of switches) {
1045
+ consideredSwitches.set(swtch.mrid, swtch);
1046
+ PowerflowUtil.addSwitch(swtch, uuidToIndex, switchData);
1047
+ }
1048
+ /** Junctions / Starre Schaltfelder */
1049
+ for (const networkElement of network) {
1050
+ if (networkElement.constructor.name.includes('Junction')) {
1051
+ consideredSwitches.set(networkElement.mrid, networkElement);
1052
+ PowerflowUtil.addJunctionSwitch(networkElement, uuidToIndex, switchData);
1053
+ }
1054
+ }
1055
+ return PowerflowUtil.toJsonPandaDataFrame(pandaDataFrame);
1056
+ }
1057
+ static fromJsonPandaDataFrame(pandaDataFrameJSON) {
1058
+ const pandaDataFrame = JSON.parse(pandaDataFrameJSON);
1059
+ //Bus
1060
+ pandaDataFrame._object.bus._object = JSON.parse(pandaDataFrame._object.bus._object);
1061
+ pandaDataFrame._object.bus._object['data'] = [];
1062
+ pandaDataFrame._object.bus._object['index'] = [];
1063
+ //Load
1064
+ pandaDataFrame._object.load._object = JSON.parse(pandaDataFrame._object.load._object);
1065
+ pandaDataFrame._object.load._object['data'] = [];
1066
+ pandaDataFrame._object.load._object['index'] = [];
1067
+ // sgen
1068
+ pandaDataFrame._object.sgen._object = JSON.parse(pandaDataFrame._object.sgen._object);
1069
+ pandaDataFrame._object.sgen._object['data'] = [];
1070
+ pandaDataFrame._object.sgen._object['index'] = [];
1071
+ // Motor
1072
+ pandaDataFrame._object.motor._object = JSON.parse(pandaDataFrame._object.motor._object);
1073
+ pandaDataFrame._object.motor._object['data'] = [];
1074
+ pandaDataFrame._object.motor._object['index'] = [];
1075
+ // asymmetric_load
1076
+ pandaDataFrame._object.asymmetric_load._object = JSON.parse(pandaDataFrame._object.asymmetric_load._object);
1077
+ pandaDataFrame._object.asymmetric_load._object['data'] = [];
1078
+ pandaDataFrame._object.asymmetric_load._object['index'] = [];
1079
+ // asymmetric_sgen
1080
+ pandaDataFrame._object.asymmetric_sgen._object = JSON.parse(pandaDataFrame._object.asymmetric_sgen._object);
1081
+ pandaDataFrame._object.asymmetric_sgen._object['data'] = [];
1082
+ pandaDataFrame._object.asymmetric_sgen._object['index'] = [];
1083
+ // storage
1084
+ pandaDataFrame._object.storage._object = JSON.parse(pandaDataFrame._object.storage._object);
1085
+ pandaDataFrame._object.storage._object['data'] = [];
1086
+ pandaDataFrame._object.storage._object['index'] = [];
1087
+ // gen
1088
+ pandaDataFrame._object.gen._object = JSON.parse(pandaDataFrame._object.gen._object);
1089
+ pandaDataFrame._object.gen._object['data'] = [];
1090
+ pandaDataFrame._object.gen._object['index'] = [];
1091
+ // Switch
1092
+ pandaDataFrame._object.switch._object = JSON.parse(pandaDataFrame._object.switch._object);
1093
+ pandaDataFrame._object.switch._object['data'] = [];
1094
+ pandaDataFrame._object.switch._object['index'] = [];
1095
+ // shunt
1096
+ pandaDataFrame._object.shunt._object = JSON.parse(pandaDataFrame._object.shunt._object);
1097
+ pandaDataFrame._object.shunt._object['data'] = [];
1098
+ pandaDataFrame._object.shunt._object['index'] = [];
1099
+ // ext_grid
1100
+ pandaDataFrame._object.ext_grid._object = JSON.parse(pandaDataFrame._object.ext_grid._object);
1101
+ pandaDataFrame._object.ext_grid._object['data'] = [];
1102
+ pandaDataFrame._object.ext_grid._object['index'] = [];
1103
+ //Line
1104
+ pandaDataFrame._object.line._object = JSON.parse(pandaDataFrame._object.line._object);
1105
+ pandaDataFrame._object.line._object['data'] = [];
1106
+ pandaDataFrame._object.line._object['index'] = [];
1107
+ // trafo
1108
+ pandaDataFrame._object.trafo._object = JSON.parse(pandaDataFrame._object.trafo._object);
1109
+ pandaDataFrame._object.trafo._object['data'] = [];
1110
+ pandaDataFrame._object.trafo._object['index'] = [];
1111
+ // trafo3w
1112
+ pandaDataFrame._object.trafo3w._object = JSON.parse(pandaDataFrame._object.trafo3w._object);
1113
+ pandaDataFrame._object.trafo3w._object['data'] = [];
1114
+ pandaDataFrame._object.trafo3w._object['index'] = [];
1115
+ // impedance
1116
+ pandaDataFrame._object.impedance._object = JSON.parse(pandaDataFrame._object.impedance._object);
1117
+ pandaDataFrame._object.impedance._object['data'] = [];
1118
+ pandaDataFrame._object.impedance._object['index'] = [];
1119
+ // dcline
1120
+ pandaDataFrame._object.dcline._object = JSON.parse(pandaDataFrame._object.dcline._object);
1121
+ pandaDataFrame._object.dcline._object['data'] = [];
1122
+ pandaDataFrame._object.dcline._object['index'] = [];
1123
+ // ward
1124
+ pandaDataFrame._object.ward._object = JSON.parse(pandaDataFrame._object.ward._object);
1125
+ pandaDataFrame._object.ward._object['data'] = [];
1126
+ pandaDataFrame._object.ward._object['index'] = [];
1127
+ // xward
1128
+ pandaDataFrame._object.xward._object = JSON.parse(pandaDataFrame._object.xward._object);
1129
+ pandaDataFrame._object.xward._object['data'] = [];
1130
+ pandaDataFrame._object.xward._object['index'] = [];
1131
+ // measurement
1132
+ pandaDataFrame._object.measurement._object = JSON.parse(pandaDataFrame._object.measurement._object);
1133
+ pandaDataFrame._object.measurement._object['data'] = [];
1134
+ pandaDataFrame._object.measurement._object['index'] = [];
1135
+ // pwl_cost
1136
+ pandaDataFrame._object.pwl_cost._object = JSON.parse(pandaDataFrame._object.pwl_cost._object);
1137
+ pandaDataFrame._object.pwl_cost._object['data'] = [];
1138
+ pandaDataFrame._object.pwl_cost._object['index'] = [];
1139
+ // poly_cost
1140
+ pandaDataFrame._object.poly_cost._object = JSON.parse(pandaDataFrame._object.poly_cost._object);
1141
+ pandaDataFrame._object.poly_cost._object['data'] = [];
1142
+ pandaDataFrame._object.poly_cost._object['index'] = [];
1143
+ // characteristic
1144
+ pandaDataFrame._object.characteristic._object = JSON.parse(pandaDataFrame._object.characteristic._object);
1145
+ pandaDataFrame._object.characteristic._object['data'] = [];
1146
+ pandaDataFrame._object.characteristic._object['index'] = [];
1147
+ // controller
1148
+ pandaDataFrame._object.controller._object = JSON.parse(pandaDataFrame._object.controller._object);
1149
+ pandaDataFrame._object.controller._object['data'] = [];
1150
+ pandaDataFrame._object.controller._object['index'] = [];
1151
+ // std_types
1152
+ pandaDataFrame._object.std_types.line = {};
1153
+ pandaDataFrame._object.std_types.trafo = {};
1154
+ pandaDataFrame._object.std_types.trafo3w = {};
1155
+ return pandaDataFrame;
1156
+ }
1157
+ /** Serialize PandaDataFrame to JSON */
1158
+ static toJsonPandaDataFrame(pandasDataFrame) {
1159
+ // Bus
1160
+ pandasDataFrame._object.bus._object = String(JSON.stringify(pandasDataFrame._object.bus._object));
1161
+ // Load
1162
+ pandasDataFrame._object.load._object = String(JSON.stringify(pandasDataFrame._object.load._object));
1163
+ // sgen
1164
+ pandasDataFrame._object.sgen._object = String(JSON.stringify(pandasDataFrame._object.sgen._object));
1165
+ // Motor
1166
+ pandasDataFrame._object.motor._object = String(JSON.stringify(pandasDataFrame._object.motor._object));
1167
+ // asymmetric_load
1168
+ pandasDataFrame._object.asymmetric_load._object = String(JSON.stringify(pandasDataFrame._object.asymmetric_load._object));
1169
+ // asymmetric_sgen
1170
+ pandasDataFrame._object.asymmetric_sgen._object = String(JSON.stringify(pandasDataFrame._object.asymmetric_sgen._object));
1171
+ // storage
1172
+ pandasDataFrame._object.storage._object = String(JSON.stringify(pandasDataFrame._object.storage._object));
1173
+ // gen
1174
+ pandasDataFrame._object.gen._object = String(JSON.stringify(pandasDataFrame._object.gen._object));
1175
+ // Switch
1176
+ pandasDataFrame._object.switch._object = String(JSON.stringify(pandasDataFrame._object.switch._object));
1177
+ // shunt
1178
+ pandasDataFrame._object.shunt._object = String(JSON.stringify(pandasDataFrame._object.shunt._object));
1179
+ // ext_grid Slack
1180
+ pandasDataFrame._object.ext_grid._object = String(JSON.stringify(pandasDataFrame._object.ext_grid._object));
1181
+ // Line
1182
+ pandasDataFrame._object.line._object = String(JSON.stringify(pandasDataFrame._object.line._object));
1183
+ // trafo
1184
+ pandasDataFrame._object.trafo._object = String(JSON.stringify(pandasDataFrame._object.trafo._object));
1185
+ // trafo3w
1186
+ pandasDataFrame._object.trafo3w._object = String(JSON.stringify(pandasDataFrame._object.trafo3w._object));
1187
+ // impedance
1188
+ pandasDataFrame._object.impedance._object = String(JSON.stringify(pandasDataFrame._object.impedance._object));
1189
+ // dcline
1190
+ pandasDataFrame._object.dcline._object = String(JSON.stringify(pandasDataFrame._object.dcline._object));
1191
+ // ward
1192
+ pandasDataFrame._object.ward._object = String(JSON.stringify(pandasDataFrame._object.ward._object));
1193
+ // xward
1194
+ pandasDataFrame._object.xward._object = String(JSON.stringify(pandasDataFrame._object.xward._object));
1195
+ // measurement
1196
+ pandasDataFrame._object.measurement._object = String(JSON.stringify(pandasDataFrame._object.measurement._object));
1197
+ // pwl_cost
1198
+ pandasDataFrame._object.pwl_cost._object = String(JSON.stringify(pandasDataFrame._object.pwl_cost._object));
1199
+ // poly_cost
1200
+ pandasDataFrame._object.poly_cost._object = String(JSON.stringify(pandasDataFrame._object.poly_cost._object));
1201
+ // characteristic
1202
+ pandasDataFrame._object.characteristic._object = String(JSON.stringify(pandasDataFrame._object.characteristic._object));
1203
+ // controller
1204
+ pandasDataFrame._object.controller._object = String(JSON.stringify(pandasDataFrame._object.controller._object));
1205
+ }
1206
+ static getBaseVoltageAsNumber(node) {
1207
+ var _a;
1208
+ let baseKV = 0;
1209
+ if (node instanceof ConnectivityNode_1.ConnectivityNode) {
1210
+ const cn = node;
1211
+ if (cn.connectivityNodeContainer) {
1212
+ baseKV = cn.getBaseVoltageAsNumber();
1213
+ }
1214
+ }
1215
+ else if (node instanceof TopologicalNode_1.TopologicalNode) {
1216
+ const tp = node;
1217
+ if (tp.baseVoltage) {
1218
+ baseKV = (_a = tp.baseVoltage.nominalVoltage) === null || _a === void 0 ? void 0 : _a.value;
1219
+ }
1220
+ }
1221
+ return baseKV;
1222
+ }
1223
+ static createPandaPowerTypeFromValues(pandasDataFrame, type, un, ir, x, r, c) {
1224
+ const stdTypeLines = pandasDataFrame._object.std_types.line;
1225
+ /** Pro Stromkreiabschnitt einen Typ anlegen,
1226
+ * um nach jedem e.action Durchlauf ursprünglichen Zustand gerstellen zu können.
1227
+ * Typen aus dem Betriebsmittelkatalog haben u.U. unterschiedliche Impedanzen. */
1228
+ const uuid = common_utils_1.CommonUtils.generateUUID();
1229
+ stdTypeLines[uuid] = {
1230
+ type,
1231
+ r_ohm_per_km: r,
1232
+ q_mm2: '',
1233
+ x_ohm_per_km: x,
1234
+ c_nf_per_km: c,
1235
+ max_i_ka: ir,
1236
+ vn_kv: un,
1237
+ name: uuid,
1238
+ uuid,
1239
+ artificial: true
1240
+ };
1241
+ return uuid;
1242
+ }
1243
+ static createStdTypeTrafo2WFromValues(types, w1Ur, w2Ur, s) {
1244
+ const un1 = PowerflowUtil.getNominalVoltage(w1Ur);
1245
+ const un2 = PowerflowUtil.getNominalVoltage(w2Ur);
1246
+ for (const [key, value] of Object.entries(types)) {
1247
+ const typData = types[key];
1248
+ if (typData && typData['vn_hv_kv'] === un1 && typData['vn_lv_kv'] === un2 && typData['sn_mva'] === s) {
1249
+ return { key, value };
1250
+ }
1251
+ }
1252
+ return undefined;
1253
+ }
1254
+ static createStdTypeTrafo3WFromValues(types, w1Ur, w2Ur, w3Ur, w1Sr, w2Sr, w3Sr) {
1255
+ const un1 = PowerflowUtil.getNominalVoltage(w1Ur);
1256
+ const un2 = PowerflowUtil.getNominalVoltage(w2Ur);
1257
+ const un3 = PowerflowUtil.getNominalVoltage(w3Ur);
1258
+ for (const [key, value] of Object.entries(types)) {
1259
+ // key -> Typname
1260
+ const typData = types[key];
1261
+ if (typData && typData['vn_hv_kv'] === un1 && typData['vn_mv_kv'] === un2 && typData['vn_lv_kv'] === un3) {
1262
+ if (typData && typData['sn_hv_mva'] === w1Sr && typData['sn_mv_mva'] === w2Sr && typData['sn_lv_mva'] === w3Sr) {
1263
+ return { key, value };
1264
+ }
1265
+ }
1266
+ }
1267
+ return undefined;
1268
+ }
1269
+ /** Normiert Bemessungsspannung (Ur) zu Nennspannung (Un)
1270
+ * +/- 7%
1271
+ * z.B. Ur=115 => Un=110 */
1272
+ static getNominalVoltage(ur) {
1273
+ /** Un 380 +/- 7% kV*/
1274
+ if (ur > 354 && ur < 407) {
1275
+ return 380;
1276
+ }
1277
+ /** Un 220 +/- 7% kV*/
1278
+ else if (ur > 204 && ur < 235) {
1279
+ return 220;
1280
+ }
1281
+ /** Un 110 +/- 10% kV*/
1282
+ else if (ur > 100 && ur < 121) {
1283
+ return 110;
1284
+ }
1285
+ /** Un 30 +/- 10% kV*/
1286
+ else if (ur > 26 && ur < 34) {
1287
+ return 30;
1288
+ }
1289
+ /** Un 20 +/- 10% kV*/
1290
+ else if (ur > 17 && ur < 23) {
1291
+ return 20;
1292
+ }
1293
+ /** Un 10 +/- 10% kV*/
1294
+ else if (ur > 8 && ur < 12) {
1295
+ return 10;
1296
+ }
1297
+ /** Un 0.4 +/- 10% kV*/
1298
+ else if (ur > 0.36 && ur < 0.44) {
1299
+ return 0.4;
1300
+ }
1301
+ else {
1302
+ /** Un 110 */
1303
+ return 110;
1304
+ }
1305
+ }
1306
+ static addSwitch(switchElement, uuidToIndex, ppSwitchData) {
1307
+ const isClosed = switchElement.isClosed();
1308
+ const isConnected = switchElement.isConnected();
1309
+ const connections = switchElement.getBusConnections();
1310
+ if (connections.length == 2) {
1311
+ const start = connections[0];
1312
+ const ziel = connections[1];
1313
+ if (uuidToIndex.has(start === null || start === void 0 ? void 0 : start.mrid) && uuidToIndex.has(ziel === null || ziel === void 0 ? void 0 : ziel.mrid)) {
1314
+ const busID1 = uuidToIndex.get(start.mrid);
1315
+ const busID2 = uuidToIndex.get(ziel.mrid);
1316
+ // "bus","element","et","type","closed","name","z_ohm", in_ka
1317
+ // bus,element,et,type,closed,name,z_ohm,in_ka
1318
+ // [1, 0.0, 0.0,false,true,null,21.7,12.7,1.0,null,null]
1319
+ const switchEl = [busID1, busID2, 'b', 'LBS', (isClosed && isConnected), switchElement.mrid, 0, 1000];
1320
+ ppSwitchData.data.push(switchEl);
1321
+ ppSwitchData.index.push(ppSwitchData.data.length - 1);
1322
+ }
1323
+ }
1324
+ }
1325
+ /** Junctions werden als Bus-Bus Switch abgebildet
1326
+ * et="b", type="CB" */
1327
+ static addJunctionSwitch(junction, uuidToIndex, ppSwitchData) {
1328
+ const isConnected = junction.isConnected();
1329
+ const connections = junction.getBusConnections();
1330
+ if (connections.length == 2) {
1331
+ const start = connections[0];
1332
+ const ziel = connections[1];
1333
+ if (uuidToIndex.has(start === null || start === void 0 ? void 0 : start.mrid) && uuidToIndex.has(ziel === null || ziel === void 0 ? void 0 : ziel.mrid)) {
1334
+ const busID1 = uuidToIndex.get(start.mrid);
1335
+ const busID2 = uuidToIndex.get(ziel.mrid);
1336
+ // "bus","element","et","type","closed","name","z_ohm"
1337
+ // [1, 0.0, 0.0,false,true,null,21.7,12.7,1.0,null,null]
1338
+ const switchEl = [busID1, busID2, 'b', 'CB', isConnected, junction.mrid, 0];
1339
+ ppSwitchData.data.push(switchEl);
1340
+ ppSwitchData.index.push(ppSwitchData.data.length - 1);
1341
+ }
1342
+ }
1343
+ }
1344
+ }
1345
+ exports.PowerflowUtil = PowerflowUtil;
1346
+ PowerflowUtil.scalingFactor = 0.2;
1347
+ PowerflowUtil.scalingFactorRn = 0.2;
1348
+ PowerflowUtil.synchronousMachineUUIDs = ["eafca6d1-4299-48bc-bf20-fe531c25871a", "720354d3-de47-4a0b-b40d-65a996668b88", "bcba52b6-8d94-4393-a6e4-cfbb5714ec78", "46b9e4e5-8a9d-4b82-8c84-428514bd397a", "b317798e-eca3-4a6d-bf26-a7e53cb09297"];
1349
+ function getKrInfo(tpLoadsNfeeders) {
1350
+ var _a;
1351
+ /** Ersatzleistungszahl */
1352
+ let krSum = 0;
1353
+ let elementWithHighestKr;
1354
+ const wardsWithKrOnly = new Array();
1355
+ const wardsWithTargetVoltageOnly = new Array();
1356
+ const wardsWithTargetVoltageKr = new Array();
1357
+ const gensWithKrOnly = new Array();
1358
+ const gensWithTargetVoltageOnly = new Array();
1359
+ const gensWithTargetVoltageKr = new Array();
1360
+ const sgensWithKrOnly = new Array();
1361
+ const sgensWithTargetVoltageOnly = new Array();
1362
+ const sgensWithTargetVoltageKr = new Array();
1363
+ for (const loadsNfeeders of tpLoadsNfeeders.values()) {
1364
+ for (const entry of loadsNfeeders.entries()) {
1365
+ const key = entry[0];
1366
+ if (key.includes('INTEGRALEquivalentInjection')) {
1367
+ const valuesArr = entry[1];
1368
+ for (let i = 0; i < valuesArr.length; i++) {
1369
+ const equivalentInjection = valuesArr[i];
1370
+ if (PowerflowUtil.synchronousMachineUUIDs.includes(equivalentInjection.getUUID()))
1371
+ continue;
1372
+ const hasKr = !isNaN(equivalentInjection.kr);
1373
+ const hasTargetVoltage = !isNaN(equivalentInjection.regulationTarget);
1374
+ // Fall 1
1375
+ if (hasKr && hasTargetVoltage) {
1376
+ wardsWithTargetVoltageKr.push(equivalentInjection);
1377
+ }
1378
+ else if (hasTargetVoltage) {
1379
+ wardsWithTargetVoltageOnly.push(equivalentInjection);
1380
+ }
1381
+ else if (hasKr) {
1382
+ wardsWithKrOnly.push(equivalentInjection);
1383
+ }
1384
+ if (!hasKr)
1385
+ continue;
1386
+ krSum += equivalentInjection.kr;
1387
+ if (!elementWithHighestKr) {
1388
+ elementWithHighestKr = equivalentInjection;
1389
+ }
1390
+ else if (elementWithHighestKr.kr < equivalentInjection.kr) {
1391
+ elementWithHighestKr = equivalentInjection;
1392
+ }
1393
+ }
1394
+ }
1395
+ else if (key.includes('SynchronousMachine')) {
1396
+ const valuesArr = entry[1];
1397
+ for (let i = 0; i < valuesArr.length; i++) {
1398
+ const synchronousMachine = valuesArr[i];
1399
+ if (PowerflowUtil.synchronousMachineUUIDs.includes(synchronousMachine.getUUID()))
1400
+ continue;
1401
+ if (synchronousMachine.normallyInService !== true)
1402
+ continue;
1403
+ const generatingUnit = synchronousMachine.generatingUnit;
1404
+ /** KR-Zahl => (governorSCD * nominalP ) / (100 * 50hz) */
1405
+ // const kr = generatingUnit ? ((generatingUnit.governorSCD * generatingUnit.nominalP) / (100 * 50)) : 0;
1406
+ const hasKr = !isNaN(synchronousMachine.kr);
1407
+ const hasTargetVoltage = !isNaN((_a = synchronousMachine.regulatingControl) === null || _a === void 0 ? void 0 : _a.targetValue);
1408
+ // Fall 1
1409
+ if (hasKr && hasTargetVoltage) {
1410
+ gensWithTargetVoltageKr.push(synchronousMachine);
1411
+ }
1412
+ else if (hasTargetVoltage) {
1413
+ gensWithTargetVoltageOnly.push(synchronousMachine);
1414
+ }
1415
+ else if (hasKr) {
1416
+ gensWithKrOnly.push(synchronousMachine);
1417
+ }
1418
+ if (!hasKr)
1419
+ continue;
1420
+ krSum += synchronousMachine.kr;
1421
+ if (!elementWithHighestKr) {
1422
+ elementWithHighestKr = synchronousMachine;
1423
+ }
1424
+ else if (elementWithHighestKr.kr < synchronousMachine.kr) {
1425
+ elementWithHighestKr = synchronousMachine;
1426
+ }
1427
+ }
1428
+ }
1429
+ else if (key.includes('EnergySource')) {
1430
+ const valuesArr = entry[1];
1431
+ for (let i = 0; i < valuesArr.length; i++) {
1432
+ const energySource = valuesArr[i];
1433
+ if (PowerflowUtil.synchronousMachineUUIDs.includes(energySource.getUUID()))
1434
+ continue;
1435
+ if (energySource.normallyInService !== true)
1436
+ continue;
1437
+ /** KR-Zahl => (governorSCD * nominalP ) / (100 * 50hz) */
1438
+ const hasKr = !isNaN(energySource.kr);
1439
+ if (!hasKr)
1440
+ continue;
1441
+ sgensWithKrOnly.push(energySource);
1442
+ krSum += energySource.kr;
1443
+ if (!elementWithHighestKr) {
1444
+ elementWithHighestKr = energySource;
1445
+ }
1446
+ else if (elementWithHighestKr.kr < energySource.kr) {
1447
+ elementWithHighestKr = energySource;
1448
+ }
1449
+ }
1450
+ }
1451
+ }
1452
+ }
1453
+ return {
1454
+ krSum,
1455
+ elementWithHighestKr,
1456
+ wardsWithKrOnly,
1457
+ wardsWithTargetVoltageOnly,
1458
+ wardsWithTargetVoltageKr,
1459
+ gensWithKrOnly,
1460
+ gensWithTargetVoltageOnly,
1461
+ gensWithTargetVoltageKr,
1462
+ sgensWithKrOnly
1463
+ };
1464
+ }
1465
+ exports.getKrInfo = getKrInfo;
1466
+ //# sourceMappingURL=powerflow.util.js.map