1pub struct DssClass {
13 pub name: &'static str,
14 pub props: &'static [&'static str],
15}
16
17macro_rules! class {
18 ($ident:ident, $name:literal, [$($p:literal),* $(,)?]) => {
19 pub static $ident: DssClass = DssClass { name: $name, props: &[$($p),*] };
20 };
21}
22
23class!(
24 LINE,
25 "line",
26 [
27 "bus1",
28 "bus2",
29 "linecode",
30 "length",
31 "phases",
32 "r1",
33 "x1",
34 "r0",
35 "x0",
36 "c1",
37 "c0",
38 "rmatrix",
39 "xmatrix",
40 "cmatrix",
41 "switch",
42 "rg",
43 "xg",
44 "rho",
45 "geometry",
46 "units",
47 "spacing",
48 "wires",
49 "earthmodel",
50 "cncables",
51 "tscables",
52 "b1",
53 "b0",
54 "seasons",
55 "ratings",
56 "linetype",
57 "normamps",
59 "emergamps",
60 "faultrate",
61 "pctperm",
62 "repair",
63 "basefreq",
64 "enabled",
65 "like",
66 ]
67);
68
69class!(
70 LINECODE,
71 "linecode",
72 [
73 "nphases",
74 "r1",
75 "x1",
76 "r0",
77 "x0",
78 "c1",
79 "c0",
80 "units",
81 "rmatrix",
82 "xmatrix",
83 "cmatrix",
84 "basefreq",
85 "normamps",
86 "emergamps",
87 "faultrate",
88 "pctperm",
89 "repair",
90 "kron",
91 "rg",
92 "xg",
93 "rho",
94 "neutral",
95 "b1",
96 "b0",
97 "seasons",
98 "ratings",
99 "linetype",
100 "like",
102 ]
103);
104
105class!(
109 LOADSHAPE,
110 "loadshape",
111 [
112 "npts",
113 "interval",
114 "mult",
115 "hour",
116 "mean",
117 "stddev",
118 "csvfile",
119 "sngfile",
120 "dblfile",
121 "action",
122 "qmult",
123 "useactual",
124 "pmax",
125 "qmax",
126 "sinterval",
127 "minterval",
128 "pbase",
129 "qbase",
130 "pmult",
131 "pqcsvfile",
132 "memorymapping",
133 "interpolation",
134 "like",
135 ]
136);
137
138class!(
139 LOAD,
140 "load",
141 [
142 "phases",
143 "bus1",
144 "kv",
145 "kw",
146 "pf",
147 "model",
148 "yearly",
149 "daily",
150 "duty",
151 "growth",
152 "conn",
153 "kvar",
154 "rneut",
155 "xneut",
156 "status",
157 "class",
158 "vminpu",
159 "vmaxpu",
160 "vminnorm",
161 "vminemerg",
162 "xfkva",
163 "allocationfactor",
164 "kva",
165 "%mean",
166 "%stddev",
167 "cvrwatts",
168 "cvrvars",
169 "kwh",
170 "kwhdays",
171 "cfactor",
172 "cvrcurve",
173 "numcust",
174 "zipv",
175 "%seriesrl",
176 "relweight",
177 "vlowpu",
178 "puxharm",
179 "xrharm",
180 "spectrum",
182 "basefreq",
183 "enabled",
184 "like",
185 ]
186);
187
188class!(
189 TRANSFORMER,
190 "transformer",
191 [
192 "phases",
193 "windings",
194 "wdg",
195 "bus",
196 "conn",
197 "kv",
198 "kva",
199 "tap",
200 "%r",
201 "rneut",
202 "xneut",
203 "buses",
204 "conns",
205 "kvs",
206 "kvas",
207 "taps",
208 "xhl",
209 "xht",
210 "xlt",
211 "xscarray",
212 "thermal",
213 "n",
214 "m",
215 "flrise",
216 "hsrise",
217 "%loadloss",
218 "%noloadloss",
219 "normhkva",
220 "emerghkva",
221 "sub",
222 "maxtap",
223 "mintap",
224 "numtaps",
225 "subname",
226 "%imag",
227 "ppm_antifloat",
228 "%rs",
229 "bank",
230 "xfmrcode",
231 "xrconst",
232 "x12",
233 "x13",
234 "x23",
235 "leadlag",
236 "wdgcurrents",
237 "core",
238 "rdcohms",
239 "seasons",
240 "ratings",
241 "normamps",
243 "emergamps",
244 "faultrate",
245 "pctperm",
246 "repair",
247 "basefreq",
248 "enabled",
249 "like",
250 ]
251);
252
253class!(
255 XFMR_CODE,
256 "xfmrcode",
257 [
258 "phases",
259 "windings",
260 "wdg",
261 "conn",
262 "kv",
263 "kva",
264 "tap",
265 "%r",
266 "rneut",
267 "xneut",
268 "conns",
269 "kvs",
270 "kvas",
271 "taps",
272 "xhl",
273 "xht",
274 "xlt",
275 "xscarray",
276 "thermal",
277 "n",
278 "m",
279 "flrise",
280 "hsrise",
281 "%loadloss",
282 "%noloadloss",
283 "normhkva",
284 "emerghkva",
285 "maxtap",
286 "mintap",
287 "numtaps",
288 "%imag",
289 "ppm_antifloat",
290 "%rs",
291 "x12",
292 "x13",
293 "x23",
294 "rdcohms",
295 "seasons",
296 "ratings",
297 "like",
298 ]
299);
300
301class!(
302 VSOURCE,
303 "vsource",
304 [
305 "bus1",
306 "basekv",
307 "pu",
308 "angle",
309 "frequency",
310 "phases",
311 "mvasc3",
312 "mvasc1",
313 "x1r1",
314 "x0r0",
315 "isc3",
316 "isc1",
317 "r1",
318 "x1",
319 "r0",
320 "x0",
321 "scantype",
322 "sequence",
323 "bus2",
324 "z1",
325 "z0",
326 "z2",
327 "puz1",
328 "puz0",
329 "puz2",
330 "basemva",
331 "yearly",
332 "daily",
333 "duty",
334 "model",
335 "puzideal",
336 "spectrum",
338 "basefreq",
339 "enabled",
340 "like",
341 ]
342);
343
344class!(
345 CAPACITOR,
346 "capacitor",
347 [
348 "bus1",
349 "bus2",
350 "phases",
351 "kvar",
352 "kv",
353 "conn",
354 "cmatrix",
355 "cuf",
356 "r",
357 "xl",
358 "harm",
359 "numsteps",
360 "states",
361 "normamps",
363 "emergamps",
364 "faultrate",
365 "pctperm",
366 "repair",
367 "basefreq",
368 "enabled",
369 "like",
370 ]
371);
372
373class!(
374 REACTOR,
375 "reactor",
376 [
377 "bus1",
378 "bus2",
379 "phases",
380 "kvar",
381 "kv",
382 "conn",
383 "rmatrix",
384 "xmatrix",
385 "parallel",
386 "r",
387 "x",
388 "rp",
389 "z1",
390 "z2",
391 "z0",
392 "z",
393 "rcurve",
394 "lcurve",
395 "lmh",
396 "normamps",
398 "emergamps",
399 "faultrate",
400 "pctperm",
401 "repair",
402 "basefreq",
403 "enabled",
404 "like",
405 ]
406);
407
408class!(
409 GENERATOR,
410 "generator",
411 [
412 "phases",
413 "bus1",
414 "kv",
415 "kw",
416 "pf",
417 "kvar",
418 "model",
419 "vminpu",
420 "vmaxpu",
421 "yearly",
422 "daily",
423 "duty",
424 "dispmode",
425 "dispvalue",
426 "conn",
427 "rneut",
428 "xneut",
429 "status",
430 "class",
431 "vpu",
432 "maxkvar",
433 "minkvar",
434 "pvfactor",
435 "forceon",
436 "kva",
437 "mva",
438 "xd",
439 "xdp",
440 "xdpp",
441 "h",
442 "d",
443 "usermodel",
444 "userdata",
445 "shaftmodel",
446 "shaftdata",
447 "dutystart",
448 "debugtrace",
449 "balanced",
450 "xrdp",
451 "usefuel",
452 "fuelkwh",
453 "%fuel",
454 "%reserve",
455 "refuel",
456 "dynamiceq",
457 "dynout",
458 "spectrum",
460 "basefreq",
461 "enabled",
462 "like",
463 ]
464);
465
466class!(
467 PVSYSTEM,
468 "pvsystem",
469 [
470 "phases",
471 "bus1",
472 "kv",
473 "irradiance",
474 "pmpp",
475 "%pmpp",
476 "temperature",
477 "pf",
478 "conn",
479 "kvar",
480 "kva",
481 "%cutin",
482 "%cutout",
483 "effcurve",
484 "ptcurve",
485 "daily",
486 "yearly",
487 "duty",
488 "tdaily",
489 "tyearly",
490 "tduty",
491 "class",
492 "user_model",
493 "user_data",
494 "debugtrace",
495 "varfollowinverter",
496 "duty_start",
497 "wattpriority",
498 "pfpriority",
499 "pctpmpp",
500 "pctcutin",
501 "pctcutout",
502 "kvarmax",
503 "kvarmaxabs",
504 "kvarlimit",
505 "kvarlimitneg",
506 "%pminnovars",
507 "%pminkvarmax",
508 "vminpu",
509 "vmaxpu",
510 "spectrum",
512 "basefreq",
513 "enabled",
514 "like",
515 ]
516);
517
518class!(
519 XYCURVE,
520 "xycurve",
521 [
522 "npts", "points", "yarray", "xarray", "csvfile", "sngfile", "dblfile", "x", "y",
523 "like",
525 ]
526);
527
528class!(
529 INVCONTROL,
530 "invcontrol",
531 [
532 "derlist",
533 "mode",
534 "combimode",
535 "vvc_curve1",
536 "hysteresis_offset",
537 "voltage_curvex_ref",
538 "avgwindowlen",
539 "volt_watt_curve",
540 "dbvmin",
541 "dbvmax",
542 "armingtime",
543 "deltaq_factor",
544 "voltagechange_tolerance",
545 "varchange_tolerance",
546 "voltwatt_curve",
547 "voltwattyaxis",
548 "rateofchange_mode",
549 "lpftau",
550 "riseFallLimit",
551 "deltaP_factor",
552 "eventlog",
553 "refreactivepower",
554 "activepchange_tolerance",
555 "monvoltagecalc",
556 "monbus",
557 "monbusesvbase",
558 "basefreq",
560 "enabled",
561 "like",
562 ]
563);
564
565class!(
566 SWTCONTROL,
567 "swtcontrol",
568 [
569 "switchedobj",
570 "switchedterm",
571 "action",
572 "lock",
573 "delay",
574 "normal",
575 "state",
576 "reset",
577 "basefreq",
579 "enabled",
580 "like",
581 ]
582);
583
584class!(
585 REGCONTROL,
586 "regcontrol",
587 [
588 "transformer",
589 "winding",
590 "vreg",
591 "band",
592 "ptratio",
593 "ctprim",
594 "r",
595 "x",
596 "bus",
597 "delay",
598 "reversible",
599 "revvreg",
600 "revband",
601 "revr",
602 "revx",
603 "tapdelay",
604 "debugtrace",
605 "maxtapchange",
606 "inversetime",
607 "tapwinding",
608 "vlimit",
609 "ptphase",
610 "revthreshold",
611 "revdelay",
612 "revneutral",
613 "eventlog",
614 "remoteptratio",
615 "tapnum",
616 "reset",
617 "ldc_z",
618 "rev_z",
619 "cogen",
620 "basefreq",
622 "enabled",
623 "like",
624 ]
625);
626
627class!(
629 WIRE_DATA,
630 "wiredata",
631 [
632 "rdc",
633 "rac",
634 "runits",
635 "gmrac",
636 "gmrunits",
637 "radius",
638 "radunits",
639 "normamps",
640 "emergamps",
641 "diam",
642 "seasons",
643 "ratings",
644 "capradius",
645 "like",
646 ]
647);
648
649class!(
651 CN_DATA,
652 "cndata",
653 [
654 "k",
655 "diastrand",
656 "gmrstrand",
657 "rstrand",
658 "epsr",
659 "inslayer",
660 "diains",
661 "diacable",
662 "rdc",
663 "rac",
664 "runits",
665 "gmrac",
666 "gmrunits",
667 "radius",
668 "radunits",
669 "normamps",
670 "emergamps",
671 "diam",
672 "seasons",
673 "ratings",
674 "capradius",
675 "like"
676 ]
677);
678
679class!(
680 LINE_GEOMETRY,
681 "linegeometry",
682 [
683 "nconds",
684 "nphases",
685 "cond",
686 "wire",
687 "x",
688 "h",
689 "units",
690 "normamps",
691 "emergamps",
692 "reduce",
693 "spacing",
694 "wires",
695 "cncable",
696 "tscable",
697 "cncables",
698 "tscables",
699 "seasons",
700 "ratings",
701 "linetype",
702 "like",
703 ]
704);
705
706class!(
707 LINE_SPACING,
708 "linespacing",
709 ["nconds", "nphases", "x", "h", "units", "like"]
710);
711
712static CLASSES: &[&DssClass] = &[
714 &LINE,
715 &LINECODE,
716 &WIRE_DATA,
717 &CN_DATA,
718 &LINE_GEOMETRY,
719 &LINE_SPACING,
720 &LOAD,
721 &LOADSHAPE,
722 &TRANSFORMER,
723 &XFMR_CODE,
724 &VSOURCE,
725 &CAPACITOR,
726 &REACTOR,
727 &GENERATOR,
728 &PVSYSTEM,
729 &XYCURVE,
730 &INVCONTROL,
731 &SWTCONTROL,
732 ®CONTROL,
733];
734
735pub fn class_by_name(name: &str) -> Option<&'static DssClass> {
738 CLASSES
739 .iter()
740 .find(|c| c.name.eq_ignore_ascii_case(name))
741 .copied()
742}
743
744impl DssClass {
745 pub fn prop_index(&self, query: &str) -> Option<usize> {
748 let q = query.to_ascii_lowercase();
749 self.props
750 .iter()
751 .position(|p| *p == q)
752 .or_else(|| self.props.iter().position(|p| p.starts_with(&q)))
753 }
754}
755
756#[cfg(test)]
757mod tests {
758 use super::*;
759
760 #[test]
761 fn exact_beats_prefix() {
762 assert_eq!(LINE.prop_index("r1"), Some(5));
764 assert_eq!(LINE.prop_index("R1"), Some(5));
765 }
766
767 #[test]
768 fn first_prefix_match_in_definition_order() {
769 assert_eq!(LINE.prop_index("r"), Some(5));
771 assert_eq!(LINE.prop_index("rm"), Some(11));
773 assert_eq!(LINE.prop_index("norm"), Some(30));
775 }
776
777 #[test]
778 fn percent_properties() {
779 assert_eq!(TRANSFORMER.prop_index("%R"), Some(8));
780 assert_eq!(TRANSFORMER.prop_index("%Rs"), Some(36));
781 assert_eq!(TRANSFORMER.prop_index("%loadloss"), Some(25));
782 }
783
784 #[test]
785 fn load_positions_match_the_engine() {
786 assert_eq!(LOAD.prop_index("relweight"), Some(34));
790 assert_eq!(LOAD.prop_index("vlowpu"), Some(35));
791 assert_eq!(LOAD.prop_index("puxharm"), Some(36));
792 assert_eq!(LOAD.prop_index("xrharm"), Some(37));
793 assert_eq!(LOAD.props.len(), 38 + 4); }
795
796 #[test]
797 fn class_lookup() {
798 assert!(class_by_name("Line").is_some());
799 assert!(class_by_name("LINECODE").is_some());
800 assert!(class_by_name("reactor").is_some());
801 assert_eq!(class_by_name("xfmrcode").unwrap().props[3], "conn");
802 }
803
804 #[test]
805 fn reactor_positions_match_the_engine() {
806 assert_eq!(REACTOR.prop_index("bus1"), Some(0));
810 assert_eq!(REACTOR.prop_index("kvar"), Some(3));
811 assert_eq!(REACTOR.prop_index("lmh"), Some(18));
812 assert_eq!(REACTOR.prop_index("normamps"), Some(19));
814 assert_eq!(REACTOR.props.len(), 19 + 8);
815 }
816
817 #[test]
818 fn unknown_property() {
819 assert_eq!(LINE.prop_index("zzz"), None);
820 }
821}