-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStorageController.py
1664 lines (1201 loc) · 76.6 KB
/
StorageController.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Copyright (c) 2021-2024 Paulo Meira
# Copyright (c) 2021-2024 DSS-Extensions contributors
from __future__ import annotations
from typing import Union, List, AnyStr, Optional, Iterator, TYPE_CHECKING
from typing_extensions import TypedDict, Unpack
from .types import Float64Array, Int32Array
from . import enums
from .DSSObj import IDSSObj, DSSObj
from .Batch import DSSBatch
from .ArrayProxy import BatchFloat64ArrayProxy, BatchInt32ArrayProxy
from .common import LIST_LIKE
from .CircuitElement import CircuitElementBatchMixin, CircuitElementMixin
from .LoadShape import LoadShape
class StorageController(DSSObj, CircuitElementMixin):
__slots__ = DSSObj._extra_slots + CircuitElementMixin._extra_slots
_cls_name = 'StorageController'
_cls_idx = 30
_cls_int_idx = {
2,
3,
12,
13,
27,
28,
35,
39,
}
_cls_float_idx = {
4,
5,
6,
7,
8,
9,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
29,
30,
31,
32,
33,
34,
38,
}
_cls_prop_idx = {
'element': 1,
'terminal': 2,
'monphase': 3,
'kwtarget': 4,
'kwtargetlow': 5,
'pctkwband': 6,
'%kwband': 6,
'kwband': 7,
'pctkwbandlow': 8,
'%kwbandlow': 8,
'kwbandlow': 9,
'elementlist': 10,
'weights': 11,
'modedischarge': 12,
'modecharge': 13,
'timedischargetrigger': 14,
'timechargetrigger': 15,
'pctratekw': 16,
'%ratekw': 16,
'pctratecharge': 17,
'%ratecharge': 17,
'pctreserve': 18,
'%reserve': 18,
'kwhtotal': 19,
'kwtotal': 20,
'kwhactual': 21,
'kwactual': 22,
'kwneed': 23,
'yearly': 24,
'daily': 25,
'duty': 26,
'eventlog': 27,
'inhibittime': 28,
'tup': 29,
'tflat': 30,
'tdn': 31,
'kwthreshold': 32,
'dispfactor': 33,
'resetlevel': 34,
'seasons': 35,
'seasontargets': 36,
'seasontargetslow': 37,
'basefreq': 38,
'enabled': 39,
'like': 40,
}
def __init__(self, api_util, ptr):
DSSObj.__init__(self, api_util, ptr)
CircuitElementMixin.__init__(self)
def edit(self, **kwargs: Unpack[StorageControllerProperties]) -> StorageController:
"""
Edit this StorageController.
This method will try to open a new edit context (if not already open),
edit the properties, and finalize the edit context.
It can be seen as a shortcut to manually setting each property, or a Pythonic
analogous (but extended) to the DSS `Edit` command.
:param **kwargs: Pass keyword arguments equivalent to the DSS properties of the object.
:return: Returns itself to allow call chaining.
"""
self._edit(props=kwargs)
return self
def _get_Element_str(self) -> str:
return self._get_prop_string(1)
def _set_Element_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_string_o(1, value, flags)
Element_str = property(_get_Element_str, _set_Element_str) # type: str
"""
Full object name of the circuit element, typically a line or transformer, which the control is monitoring. There is no default; Must be specified.In "Local" control mode, is the name of the load that will be managed by the storage device, which should be installed at the same bus.
DSS property name: `Element`, DSS property index: 1.
"""
def _get_Element(self) -> DSSObj:
return self._get_obj(1, None)
def _set_Element(self, value: Union[AnyStr, DSSObj], flags: enums.SetterFlags = 0):
if isinstance(value, DSSObj) or value is None:
self._set_obj(1, value, flags)
return
self._set_string_o(1, value, flags)
Element = property(_get_Element, _set_Element) # type: DSSObj
"""
Full object name of the circuit element, typically a line or transformer, which the control is monitoring. There is no default; Must be specified.In "Local" control mode, is the name of the load that will be managed by the storage device, which should be installed at the same bus.
DSS property name: `Element`, DSS property index: 1.
"""
def _get_Terminal(self) -> int:
return self._lib.Obj_GetInt32(self._ptr, 2)
def _set_Terminal(self, value: int, flags: enums.SetterFlags = 0):
self._lib.Obj_SetInt32(self._ptr, 2, value, flags)
Terminal = property(_get_Terminal, _set_Terminal) # type: int
"""
Number of the terminal of the circuit element to which the StorageController control is connected. 1 or 2, typically. Default is 1. Make sure to select the proper direction on the power for the respective dispatch mode.
DSS property name: `Terminal`, DSS property index: 2.
"""
def _get_MonPhase(self) -> Union[enums.MonitoredPhase, int]:
value = self._lib.Obj_GetInt32(self._ptr, 3)
if value > 0:
return value
return enums.MonitoredPhase(value)
def _set_MonPhase(self, value: Union[AnyStr, int, enums.MonitoredPhase], flags: enums.SetterFlags = 0):
if not isinstance(value, int):
self._set_string_o(3, value, flags)
return
self._lib.Obj_SetInt32(self._ptr, 3, value, flags)
MonPhase = property(_get_MonPhase, _set_MonPhase) # type: enums.MonitoredPhase
"""
Number of the phase being monitored or one of {AVG | MAX | MIN} for all phases. Default=MAX. Must be less than the number of phases. Used in PeakShave, Follow, Support and I-PeakShave discharging modes and in PeakShaveLow, I-PeakShaveLow charging modes. For modes based on active power measurements, the value used by the control is the monitored one multiplied by the number of phases of the monitored element.
DSS property name: `MonPhase`, DSS property index: 3.
"""
def _get_MonPhase_str(self) -> str:
return self._get_prop_string(3)
def _set_MonPhase_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_MonPhase(value, flags)
MonPhase_str = property(_get_MonPhase_str, _set_MonPhase_str) # type: str
"""
Number of the phase being monitored or one of {AVG | MAX | MIN} for all phases. Default=MAX. Must be less than the number of phases. Used in PeakShave, Follow, Support and I-PeakShave discharging modes and in PeakShaveLow, I-PeakShaveLow charging modes. For modes based on active power measurements, the value used by the control is the monitored one multiplied by the number of phases of the monitored element.
DSS property name: `MonPhase`, DSS property index: 3.
"""
def _get_kWTarget(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 4)
def _set_kWTarget(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 4, value, flags)
kWTarget = property(_get_kWTarget, _set_kWTarget) # type: float
"""
kW/kamps target for Discharging. The Storage element fleet is dispatched to try to hold the power/current in band at least until the Storage is depleted. The selection of power or current depends on the Discharge mode (PeakShave->kW, I-PeakShave->kamps).
DSS property name: `kWTarget`, DSS property index: 4.
"""
def _get_kWTargetLow(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 5)
def _set_kWTargetLow(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 5, value, flags)
kWTargetLow = property(_get_kWTargetLow, _set_kWTargetLow) # type: float
"""
kW/kamps target for Charging. The Storage element fleet is dispatched to try to hold the power/current in band at least until the Storage is fully charged. The selection of power or current depends on the charge mode (PeakShavelow->kW, I-PeakShavelow->kamps).
DSS property name: `kWTargetLow`, DSS property index: 5.
"""
def _get_pctkWBand(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 6)
def _set_pctkWBand(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 6, value, flags)
pctkWBand = property(_get_pctkWBand, _set_pctkWBand) # type: float
"""
Bandwidth (% of Target kW/kamps) of the dead band around the kW/kamps target value. Default is 2% (+/-1%).No dispatch changes are attempted if the power in the monitored terminal stays within this band.
DSS property name: `%kWBand`, DSS property index: 6.
"""
def _get_kWBand(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 7)
def _set_kWBand(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 7, value, flags)
kWBand = property(_get_kWBand, _set_kWBand) # type: float
"""
Alternative way of specifying the bandwidth. (kW/kamps) of the dead band around the kW/kamps target value. Default is 2% of kWTarget (+/-1%).No dispatch changes are attempted if the power in the monitored terminal stays within this band.
DSS property name: `kWBand`, DSS property index: 7.
"""
def _get_pctkWBandLow(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 8)
def _set_pctkWBandLow(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 8, value, flags)
pctkWBandLow = property(_get_pctkWBandLow, _set_pctkWBandLow) # type: float
"""
Bandwidth (% of kWTargetLow) of the dead band around the kW/kamps low target value. Default is 2% (+/-1%).No charging is attempted if the power in the monitored terminal stays within this band.
DSS property name: `%kWBandLow`, DSS property index: 8.
"""
def _get_kWBandLow(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 9)
def _set_kWBandLow(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 9, value, flags)
kWBandLow = property(_get_kWBandLow, _set_kWBandLow) # type: float
"""
Alternative way of specifying the bandwidth. (kW/kamps) of the dead band around the kW/kamps low target value. Default is 2% of kWTargetLow (+/-1%).No charging is attempted if the power in the monitored terminal stays within this band.
DSS property name: `kWBandLow`, DSS property index: 9.
"""
def _get_ElementList(self) -> List[str]:
return self._get_string_array(self._lib.Obj_GetStringArray, self._ptr, 10)
def _set_ElementList(self, value: List[AnyStr], flags: enums.SetterFlags = 0):
value, value_ptr, value_count = self._prepare_string_array(value)
self._lib.Obj_SetStringArray(self._ptr, 10, value_ptr, value_count, flags)
self._check_for_error()
ElementList = property(_get_ElementList, _set_ElementList) # type: List[str]
"""
Array list of Storage elements to be controlled. If not specified, all Storage elements in the circuit not presently dispatched by another controller are assumed dispatched by this controller.
DSS property name: `ElementList`, DSS property index: 10.
"""
def _get_Weights(self) -> Float64Array:
return self._get_float64_array(self._lib.Obj_GetFloat64Array, self._ptr, 11)
def _set_Weights(self, value: Float64Array, flags: enums.SetterFlags = 0):
self._set_float64_array_o(11, value, flags)
Weights = property(_get_Weights, _set_Weights) # type: Float64Array
"""
Array of proportional weights corresponding to each Storage element in the ElementList. The needed kW or kvar to get back to center band is dispatched to each Storage element according to these weights. Default is to set all weights to 1.0.
DSS property name: `Weights`, DSS property index: 11.
"""
def _get_ModeDischarge(self) -> enums.StorageControllerDischargeMode:
return enums.StorageControllerDischargeMode(self._lib.Obj_GetInt32(self._ptr, 12))
def _set_ModeDischarge(self, value: Union[AnyStr, int, enums.StorageControllerDischargeMode], flags: enums.SetterFlags = 0):
if not isinstance(value, int):
self._set_string_o(12, value, flags)
return
self._lib.Obj_SetInt32(self._ptr, 12, value, flags)
ModeDischarge = property(_get_ModeDischarge, _set_ModeDischarge) # type: enums.StorageControllerDischargeMode
"""
{PeakShave* | Follow | Support | Loadshape | Time | Schedule | I-PeakShave} Mode of operation for the DISCHARGE FUNCTION of this controller.
In PeakShave mode (Default), the control attempts to discharge Storage to keep power in the monitored element below the kWTarget.
In Follow mode, the control is triggered by time and resets the kWTarget value to the present monitored element power. It then attempts to discharge Storage to keep power in the monitored element below the new kWTarget. See TimeDischargeTrigger.
In Support mode, the control operates oppositely of PeakShave mode: Storage is discharged to keep kW power output up near the target.
In Loadshape mode, both charging and discharging precisely follows the per unit loadshape. Storage is discharged when the loadshape value is positive.
In Time mode, the Storage discharge is turned on at the specified %RatekW at the specified discharge trigger time in fractional hours.
In Schedule mode, the Tup, TFlat, and Tdn properties specify the up ramp duration, flat duration, and down ramp duration for the schedule. The schedule start time is set by TimeDischargeTrigger and the rate of discharge for the flat part is determined by %RatekW.
In I-PeakShave mode, the control attempts to discharge Storage to keep current in the monitored element below the target given in k-amps (thousands of amps), when this control mode is active, the property kWTarget will be expressed in k-amps.
DSS property name: `ModeDischarge`, DSS property index: 12.
"""
def _get_ModeDischarge_str(self) -> str:
return self._get_prop_string(12)
def _set_ModeDischarge_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_ModeDischarge(value, flags)
ModeDischarge_str = property(_get_ModeDischarge_str, _set_ModeDischarge_str) # type: str
"""
{PeakShave* | Follow | Support | Loadshape | Time | Schedule | I-PeakShave} Mode of operation for the DISCHARGE FUNCTION of this controller.
In PeakShave mode (Default), the control attempts to discharge Storage to keep power in the monitored element below the kWTarget.
In Follow mode, the control is triggered by time and resets the kWTarget value to the present monitored element power. It then attempts to discharge Storage to keep power in the monitored element below the new kWTarget. See TimeDischargeTrigger.
In Support mode, the control operates oppositely of PeakShave mode: Storage is discharged to keep kW power output up near the target.
In Loadshape mode, both charging and discharging precisely follows the per unit loadshape. Storage is discharged when the loadshape value is positive.
In Time mode, the Storage discharge is turned on at the specified %RatekW at the specified discharge trigger time in fractional hours.
In Schedule mode, the Tup, TFlat, and Tdn properties specify the up ramp duration, flat duration, and down ramp duration for the schedule. The schedule start time is set by TimeDischargeTrigger and the rate of discharge for the flat part is determined by %RatekW.
In I-PeakShave mode, the control attempts to discharge Storage to keep current in the monitored element below the target given in k-amps (thousands of amps), when this control mode is active, the property kWTarget will be expressed in k-amps.
DSS property name: `ModeDischarge`, DSS property index: 12.
"""
def _get_ModeCharge(self) -> enums.StorageControllerChargeMode:
return enums.StorageControllerChargeMode(self._lib.Obj_GetInt32(self._ptr, 13))
def _set_ModeCharge(self, value: Union[AnyStr, int, enums.StorageControllerChargeMode], flags: enums.SetterFlags = 0):
if not isinstance(value, int):
self._set_string_o(13, value, flags)
return
self._lib.Obj_SetInt32(self._ptr, 13, value, flags)
ModeCharge = property(_get_ModeCharge, _set_ModeCharge) # type: enums.StorageControllerChargeMode
"""
{Loadshape | Time* | PeakShaveLow | I-PeakShaveLow} Mode of operation for the CHARGE FUNCTION of this controller.
In Loadshape mode, both charging and discharging precisely follows the per unit loadshape. Storage is charged when the loadshape value is negative.
In Time mode, the Storage charging FUNCTION is triggered at the specified %RateCharge at the specified charge trigger time in fractional hours.
In PeakShaveLow mode, the charging operation will charge the Storage fleet when the power at a monitored element is below a specified KW target (kWTarget_low). The Storage will charge as much power as necessary to keep the power within the deadband around kWTarget_low.
In I-PeakShaveLow mode, the charging operation will charge the Storage fleet when the current (Amps) at a monitored element is below a specified amps target (kWTarget_low). The Storage will charge as much power as necessary to keep the amps within the deadband around kWTarget_low. When this control mode is active, the property kWTarget_low will be expressed in k-amps and all the other parameters will be adjusted to match the amps (current) control criteria.
DSS property name: `ModeCharge`, DSS property index: 13.
"""
def _get_ModeCharge_str(self) -> str:
return self._get_prop_string(13)
def _set_ModeCharge_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_ModeCharge(value, flags)
ModeCharge_str = property(_get_ModeCharge_str, _set_ModeCharge_str) # type: str
"""
{Loadshape | Time* | PeakShaveLow | I-PeakShaveLow} Mode of operation for the CHARGE FUNCTION of this controller.
In Loadshape mode, both charging and discharging precisely follows the per unit loadshape. Storage is charged when the loadshape value is negative.
In Time mode, the Storage charging FUNCTION is triggered at the specified %RateCharge at the specified charge trigger time in fractional hours.
In PeakShaveLow mode, the charging operation will charge the Storage fleet when the power at a monitored element is below a specified KW target (kWTarget_low). The Storage will charge as much power as necessary to keep the power within the deadband around kWTarget_low.
In I-PeakShaveLow mode, the charging operation will charge the Storage fleet when the current (Amps) at a monitored element is below a specified amps target (kWTarget_low). The Storage will charge as much power as necessary to keep the amps within the deadband around kWTarget_low. When this control mode is active, the property kWTarget_low will be expressed in k-amps and all the other parameters will be adjusted to match the amps (current) control criteria.
DSS property name: `ModeCharge`, DSS property index: 13.
"""
def _get_TimeDischargeTrigger(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 14)
def _set_TimeDischargeTrigger(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 14, value, flags)
TimeDischargeTrigger = property(_get_TimeDischargeTrigger, _set_TimeDischargeTrigger) # type: float
"""
Default time of day (hr) for initiating Discharging of the fleet. During Follow or Time mode discharging is triggered at a fixed time each day at this hour. If Follow mode, Storage will be discharged to attempt to hold the load at or below the power level at the time of triggering. In Time mode, the discharge is based on the %RatekW property value. Set this to a negative value to ignore. Default is 12.0 for Follow mode; otherwise it is -1 (ignored).
DSS property name: `TimeDischargeTrigger`, DSS property index: 14.
"""
def _get_TimeChargeTrigger(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 15)
def _set_TimeChargeTrigger(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 15, value, flags)
TimeChargeTrigger = property(_get_TimeChargeTrigger, _set_TimeChargeTrigger) # type: float
"""
Default time of day (hr) for initiating charging in Time control mode. Set this to a negative value to ignore. Default is 2.0. (0200).When this value is >0 the Storage fleet is set to charging at this time regardless of other control criteria to make sure Storage is topped off for the next discharge cycle.
DSS property name: `TimeChargeTrigger`, DSS property index: 15.
"""
def _get_pctRatekW(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 16)
def _set_pctRatekW(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 16, value, flags)
pctRatekW = property(_get_pctRatekW, _set_pctRatekW) # type: float
"""
Sets the kW discharge rate in % of rated capacity for each element of the fleet. Applies to TIME control mode, SCHEDULE mode, or anytime discharging is triggered by time.
DSS property name: `%RatekW`, DSS property index: 16.
"""
def _get_pctRateCharge(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 17)
def _set_pctRateCharge(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 17, value, flags)
pctRateCharge = property(_get_pctRateCharge, _set_pctRateCharge) # type: float
"""
Sets the kW charging rate in % of rated capacity for each element of the fleet. Applies to TIME control mode and anytime charging mode is entered due to a time trigger.
DSS property name: `%RateCharge`, DSS property index: 17.
"""
def _get_pctReserve(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 18)
def _set_pctReserve(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 18, value, flags)
pctReserve = property(_get_pctReserve, _set_pctReserve) # type: float
"""
Use this property to change the % reserve for each Storage element under control of this controller. This might be used, for example, to allow deeper discharges of Storage or in case of emergency operation to use the remainder of the Storage element.
DSS property name: `%Reserve`, DSS property index: 18.
"""
def _get_kWhTotal(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 19)
def _set_kWhTotal(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 19, value, flags)
kWhTotal = property(_get_kWhTotal, _set_kWhTotal) # type: float
"""
(Read only). Total rated kWh energy Storage capacity of Storage elements controlled by this controller.
DSS property name: `kWhTotal`, DSS property index: 19.
"""
def _get_kWTotal(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 20)
def _set_kWTotal(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 20, value, flags)
kWTotal = property(_get_kWTotal, _set_kWTotal) # type: float
"""
(Read only). Total rated kW power capacity of Storage elements controlled by this controller.
DSS property name: `kWTotal`, DSS property index: 20.
"""
def _get_kWhActual(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 21)
def _set_kWhActual(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 21, value, flags)
kWhActual = property(_get_kWhActual, _set_kWhActual) # type: float
"""
(Read only). Actual kWh stored of all controlled Storage elements.
DSS property name: `kWhActual`, DSS property index: 21.
"""
def _get_kWActual(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 22)
def _set_kWActual(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 22, value, flags)
kWActual = property(_get_kWActual, _set_kWActual) # type: float
"""
(Read only). Actual kW output of all controlled Storage elements.
DSS property name: `kWActual`, DSS property index: 22.
"""
def _get_kWNeed(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 23)
def _set_kWNeed(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 23, value, flags)
kWNeed = property(_get_kWNeed, _set_kWNeed) # type: float
"""
(Read only). KW needed to meet target.
DSS property name: `kWNeed`, DSS property index: 23.
"""
def _get_Yearly_str(self) -> str:
return self._get_prop_string(24)
def _set_Yearly_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_string_o(24, value, flags)
Yearly_str = property(_get_Yearly_str, _set_Yearly_str) # type: str
"""
Dispatch loadshape object, If any, for Yearly solution Mode.
DSS property name: `Yearly`, DSS property index: 24.
"""
def _get_Yearly(self) -> LoadShape:
return self._get_obj(24, LoadShape)
def _set_Yearly(self, value: Union[AnyStr, LoadShape], flags: enums.SetterFlags = 0):
if isinstance(value, DSSObj) or value is None:
self._set_obj(24, value, flags)
return
self._set_string_o(24, value, flags)
Yearly = property(_get_Yearly, _set_Yearly) # type: LoadShape
"""
Dispatch loadshape object, If any, for Yearly solution Mode.
DSS property name: `Yearly`, DSS property index: 24.
"""
def _get_Daily_str(self) -> str:
return self._get_prop_string(25)
def _set_Daily_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_string_o(25, value, flags)
Daily_str = property(_get_Daily_str, _set_Daily_str) # type: str
"""
Dispatch loadshape object, If any, for Daily solution mode.
DSS property name: `Daily`, DSS property index: 25.
"""
def _get_Daily(self) -> LoadShape:
return self._get_obj(25, LoadShape)
def _set_Daily(self, value: Union[AnyStr, LoadShape], flags: enums.SetterFlags = 0):
if isinstance(value, DSSObj) or value is None:
self._set_obj(25, value, flags)
return
self._set_string_o(25, value, flags)
Daily = property(_get_Daily, _set_Daily) # type: LoadShape
"""
Dispatch loadshape object, If any, for Daily solution mode.
DSS property name: `Daily`, DSS property index: 25.
"""
def _get_Duty_str(self) -> str:
return self._get_prop_string(26)
def _set_Duty_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_string_o(26, value, flags)
Duty_str = property(_get_Duty_str, _set_Duty_str) # type: str
"""
Dispatch loadshape object, If any, for Dutycycle solution mode.
DSS property name: `Duty`, DSS property index: 26.
"""
def _get_Duty(self) -> LoadShape:
return self._get_obj(26, LoadShape)
def _set_Duty(self, value: Union[AnyStr, LoadShape], flags: enums.SetterFlags = 0):
if isinstance(value, DSSObj) or value is None:
self._set_obj(26, value, flags)
return
self._set_string_o(26, value, flags)
Duty = property(_get_Duty, _set_Duty) # type: LoadShape
"""
Dispatch loadshape object, If any, for Dutycycle solution mode.
DSS property name: `Duty`, DSS property index: 26.
"""
def _get_EventLog(self) -> bool:
return self._lib.Obj_GetInt32(self._ptr, 27) != 0
def _set_EventLog(self, value: bool, flags: enums.SetterFlags = 0):
self._lib.Obj_SetInt32(self._ptr, 27, value, flags)
EventLog = property(_get_EventLog, _set_EventLog) # type: bool
"""
{Yes/True | No/False} Default is No. Log control actions to Eventlog.
DSS property name: `EventLog`, DSS property index: 27.
"""
def _get_InhibitTime(self) -> int:
return self._lib.Obj_GetInt32(self._ptr, 28)
def _set_InhibitTime(self, value: int, flags: enums.SetterFlags = 0):
self._lib.Obj_SetInt32(self._ptr, 28, value, flags)
InhibitTime = property(_get_InhibitTime, _set_InhibitTime) # type: int
"""
Hours (integer) to inhibit Discharging after going into Charge mode. Default is 5.
DSS property name: `InhibitTime`, DSS property index: 28.
"""
def _get_TUp(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 29)
def _set_TUp(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 29, value, flags)
TUp = property(_get_TUp, _set_TUp) # type: float
"""
Duration, hrs, of upramp part for SCHEDULE mode. Default is 0.25.
DSS property name: `TUp`, DSS property index: 29.
"""
def _get_TFlat(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 30)
def _set_TFlat(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 30, value, flags)
TFlat = property(_get_TFlat, _set_TFlat) # type: float
"""
Duration, hrs, of flat part for SCHEDULE mode. Default is 2.0.
DSS property name: `TFlat`, DSS property index: 30.
"""
def _get_TDn(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 31)
def _set_TDn(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 31, value, flags)
TDn = property(_get_TDn, _set_TDn) # type: float
"""
Duration, hrs, of downramp part for SCHEDULE mode. Default is 0.25.
DSS property name: `TDn`, DSS property index: 31.
"""
def _get_kWThreshold(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 32)
def _set_kWThreshold(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 32, value, flags)
kWThreshold = property(_get_kWThreshold, _set_kWThreshold) # type: float
"""
Threshold, kW, for Follow mode. kW has to be above this value for the Storage element to be dispatched on. Defaults to 75% of the kWTarget value. Must reset this property after setting kWTarget if you want a different value.
DSS property name: `kWThreshold`, DSS property index: 32.
"""
def _get_DispFactor(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 33)
def _set_DispFactor(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 33, value, flags)
DispFactor = property(_get_DispFactor, _set_DispFactor) # type: float
"""
Defaults to 1 (disabled). Set to any value between 0 and 1 to enable this parameter.
Use this parameter to reduce the amount of power requested by the controller in each control iteration. It can be useful when maximum control iterations are exceeded due to numerical instability such as fleet being set to charging and idling in subsequent control iterations (check the Eventlog).
DSS property name: `DispFactor`, DSS property index: 33.
"""
def _get_ResetLevel(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 34)
def _set_ResetLevel(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 34, value, flags)
ResetLevel = property(_get_ResetLevel, _set_ResetLevel) # type: float
"""
The level of charge required for allowing the storage to discharge again after reaching the reserve storage level. After reaching this level, the storage control will not allow the storage device to discharge, forcing the storage to charge. Once the storage reaches this level, the storage will be able to discharge again. This value is a number between 0.2 and 1
DSS property name: `ResetLevel`, DSS property index: 34.
"""
def _get_Seasons(self) -> int:
return self._lib.Obj_GetInt32(self._ptr, 35)
def _set_Seasons(self, value: int, flags: enums.SetterFlags = 0):
self._lib.Obj_SetInt32(self._ptr, 35, value, flags)
Seasons = property(_get_Seasons, _set_Seasons) # type: int
"""
With this property the user can specify the number of targets to be used by the controller using the list given at "SeasonTargets"/"SeasonTargetsLow", which can be used to dynamically adjust the storage controller during a QSTS simulation. The default value is 1. This property needs to be defined before defining SeasonTargets/SeasonTargetsLow.
DSS property name: `Seasons`, DSS property index: 35.
"""
def _get_SeasonTargets(self) -> Float64Array:
return self._get_float64_array(self._lib.Obj_GetFloat64Array, self._ptr, 36)
def _set_SeasonTargets(self, value: Float64Array, flags: enums.SetterFlags = 0):
self._set_float64_array_o(36, value, flags)
SeasonTargets = property(_get_SeasonTargets, _set_SeasonTargets) # type: Float64Array
"""
An array of doubles specifying the targets to be used during a QSTS simulation. These targets will take effect only if SeasonRating=true. The number of targets cannot exceed the number of seasons defined at the SeasonSignal.The difference between the targets defined at SeasonTargets and SeasonTargetsLow is that SeasonTargets applies to discharging modes, while SeasonTargetsLow applies to charging modes.
DSS property name: `SeasonTargets`, DSS property index: 36.
"""
def _get_SeasonTargetsLow(self) -> Float64Array:
return self._get_float64_array(self._lib.Obj_GetFloat64Array, self._ptr, 37)
def _set_SeasonTargetsLow(self, value: Float64Array, flags: enums.SetterFlags = 0):
self._set_float64_array_o(37, value, flags)
SeasonTargetsLow = property(_get_SeasonTargetsLow, _set_SeasonTargetsLow) # type: Float64Array
"""
An array of doubles specifying the targets to be used during a QSTS simulation. These targets will take effect only if SeasonRating=true. The number of targets cannot exceed the number of seasons defined at the SeasonSignal.The difference between the targets defined at SeasonTargets and SeasonTargetsLow is that SeasonTargets applies to discharging modes, while SeasonTargetsLow applies to charging modes.
DSS property name: `SeasonTargetsLow`, DSS property index: 37.
"""
def _get_BaseFreq(self) -> float:
return self._lib.Obj_GetFloat64(self._ptr, 38)
def _set_BaseFreq(self, value: float, flags: enums.SetterFlags = 0):
self._lib.Obj_SetFloat64(self._ptr, 38, value, flags)
BaseFreq = property(_get_BaseFreq, _set_BaseFreq) # type: float
"""
Base Frequency for ratings.
DSS property name: `BaseFreq`, DSS property index: 38.
"""
def _get_Enabled(self) -> bool:
return self._lib.Obj_GetInt32(self._ptr, 39) != 0
def _set_Enabled(self, value: bool, flags: enums.SetterFlags = 0):
self._lib.Obj_SetInt32(self._ptr, 39, value, flags)
Enabled = property(_get_Enabled, _set_Enabled) # type: bool
"""
{Yes|No or True|False} Indicates whether this element is enabled.
DSS property name: `Enabled`, DSS property index: 39.
"""
def Like(self, value: AnyStr):
"""
Make like another object, e.g.:
New Capacitor.C2 like=c1 ...
DSS property name: `Like`, DSS property index: 40.
"""
self._set_string_o(40, value)
class StorageControllerProperties(TypedDict):
Element: Union[AnyStr, DSSObj]
Terminal: int
MonPhase: Union[AnyStr, int, enums.MonitoredPhase]
kWTarget: float
kWTargetLow: float
pctkWBand: float
kWBand: float
pctkWBandLow: float
kWBandLow: float
ElementList: List[AnyStr]
Weights: Float64Array
ModeDischarge: Union[AnyStr, int, enums.StorageControllerDischargeMode]
ModeCharge: Union[AnyStr, int, enums.StorageControllerChargeMode]
TimeDischargeTrigger: float
TimeChargeTrigger: float
pctRatekW: float
pctRateCharge: float
pctReserve: float
kWhTotal: float
kWTotal: float
kWhActual: float
kWActual: float
kWNeed: float
Yearly: Union[AnyStr, LoadShape]
Daily: Union[AnyStr, LoadShape]
Duty: Union[AnyStr, LoadShape]
EventLog: bool
InhibitTime: int
TUp: float
TFlat: float
TDn: float
kWThreshold: float
DispFactor: float
ResetLevel: float
Seasons: int
SeasonTargets: Float64Array
SeasonTargetsLow: Float64Array
BaseFreq: float
Enabled: bool
Like: AnyStr
class StorageControllerBatch(DSSBatch, CircuitElementBatchMixin):
_cls_name = 'StorageController'
_obj_cls = StorageController
_cls_idx = 30
__slots__ = []
def __init__(self, api_util, **kwargs):
DSSBatch.__init__(self, api_util, **kwargs)
CircuitElementBatchMixin.__init__(self)
def edit(self, **kwargs: Unpack[StorageControllerBatchProperties]) -> StorageControllerBatch:
"""
Edit this StorageController batch.
This method will try to open a new edit context (if not already open),
edit the properties, and finalize the edit context for objects in the batch.
It can be seen as a shortcut to manually setting each property, or a Pythonic
analogous (but extended) to the DSS `BatchEdit` command.
:param **kwargs: Pass keyword arguments equivalent to the DSS properties of the objects.
:return: Returns itself to allow call chaining.
"""
self._edit(props=kwargs)
return self
if TYPE_CHECKING:
def __iter__(self) -> Iterator[StorageController]:
yield from DSSBatch.__iter__(self)
def _get_Element_str(self) -> List[str]:
return self._get_batch_str_prop(1)
def _set_Element_str(self, value: Union[AnyStr, List[AnyStr]], flags: enums.SetterFlags = 0):
self._set_batch_string(1, value, flags)
Element_str = property(_get_Element_str, _set_Element_str) # type: List[str]
"""
Full object name of the circuit element, typically a line or transformer, which the control is monitoring. There is no default; Must be specified.In "Local" control mode, is the name of the load that will be managed by the storage device, which should be installed at the same bus.
DSS property name: `Element`, DSS property index: 1.
"""
def _get_Element(self) -> List[DSSObj]:
return self._get_batch_obj_prop(1)
def _set_Element(self, value: Union[AnyStr, DSSObj, List[AnyStr], List[DSSObj]], flags: enums.SetterFlags = 0):
self._set_batch_obj_prop(1, value, flags)
Element = property(_get_Element, _set_Element) # type: List[DSSObj]
"""
Full object name of the circuit element, typically a line or transformer, which the control is monitoring. There is no default; Must be specified.In "Local" control mode, is the name of the load that will be managed by the storage device, which should be installed at the same bus.
DSS property name: `Element`, DSS property index: 1.
"""
def _get_Terminal(self) -> BatchInt32ArrayProxy:
return BatchInt32ArrayProxy(self, 2)
def _set_Terminal(self, value: Union[int, Int32Array], flags: enums.SetterFlags = 0):
self._set_batch_int32_array(2, value, flags)
Terminal = property(_get_Terminal, _set_Terminal) # type: BatchInt32ArrayProxy
"""
Number of the terminal of the circuit element to which the StorageController control is connected. 1 or 2, typically. Default is 1. Make sure to select the proper direction on the power for the respective dispatch mode.
DSS property name: `Terminal`, DSS property index: 2.
"""
def _get_MonPhase(self) -> BatchInt32ArrayProxy:
return BatchInt32ArrayProxy(self, 3)
def _set_MonPhase(self, value: Union[AnyStr, int, enums.MonitoredPhase, List[AnyStr], List[int], List[enums.MonitoredPhase], Int32Array], flags: enums.SetterFlags = 0):
if isinstance(value, (str, bytes)) or (isinstance(value, LIST_LIKE) and isinstance(value[0], (str, bytes))):
self._set_batch_string(3, value, flags)
return
self._set_batch_int32_array(3, value, flags)
MonPhase = property(_get_MonPhase, _set_MonPhase) # type: BatchInt32ArrayProxy
"""
Number of the phase being monitored or one of {AVG | MAX | MIN} for all phases. Default=MAX. Must be less than the number of phases. Used in PeakShave, Follow, Support and I-PeakShave discharging modes and in PeakShaveLow, I-PeakShaveLow charging modes. For modes based on active power measurements, the value used by the control is the monitored one multiplied by the number of phases of the monitored element.
DSS property name: `MonPhase`, DSS property index: 3.
"""
def _get_MonPhase_str(self) -> List[str]:
return self._get_batch_str_prop(3)
def _set_MonPhase_str(self, value: AnyStr, flags: enums.SetterFlags = 0):
self._set_MonPhase(value, flags)
MonPhase_str = property(_get_MonPhase_str, _set_MonPhase_str) # type: List[str]
"""
Number of the phase being monitored or one of {AVG | MAX | MIN} for all phases. Default=MAX. Must be less than the number of phases. Used in PeakShave, Follow, Support and I-PeakShave discharging modes and in PeakShaveLow, I-PeakShaveLow charging modes. For modes based on active power measurements, the value used by the control is the monitored one multiplied by the number of phases of the monitored element.
DSS property name: `MonPhase`, DSS property index: 3.
"""
def _get_kWTarget(self) -> BatchFloat64ArrayProxy:
return BatchFloat64ArrayProxy(self, 4)
def _set_kWTarget(self, value: Union[float, Float64Array], flags: enums.SetterFlags = 0):
self._set_batch_float64_array(4, value, flags)
kWTarget = property(_get_kWTarget, _set_kWTarget) # type: BatchFloat64ArrayProxy
"""
kW/kamps target for Discharging. The Storage element fleet is dispatched to try to hold the power/current in band at least until the Storage is depleted. The selection of power or current depends on the Discharge mode (PeakShave->kW, I-PeakShave->kamps).
DSS property name: `kWTarget`, DSS property index: 4.
"""
def _get_kWTargetLow(self) -> BatchFloat64ArrayProxy:
return BatchFloat64ArrayProxy(self, 5)
def _set_kWTargetLow(self, value: Union[float, Float64Array], flags: enums.SetterFlags = 0):
self._set_batch_float64_array(5, value, flags)
kWTargetLow = property(_get_kWTargetLow, _set_kWTargetLow) # type: BatchFloat64ArrayProxy
"""
kW/kamps target for Charging. The Storage element fleet is dispatched to try to hold the power/current in band at least until the Storage is fully charged. The selection of power or current depends on the charge mode (PeakShavelow->kW, I-PeakShavelow->kamps).
DSS property name: `kWTargetLow`, DSS property index: 5.
"""
def _get_pctkWBand(self) -> BatchFloat64ArrayProxy:
return BatchFloat64ArrayProxy(self, 6)
def _set_pctkWBand(self, value: Union[float, Float64Array], flags: enums.SetterFlags = 0):
self._set_batch_float64_array(6, value, flags)
pctkWBand = property(_get_pctkWBand, _set_pctkWBand) # type: BatchFloat64ArrayProxy
"""
Bandwidth (% of Target kW/kamps) of the dead band around the kW/kamps target value. Default is 2% (+/-1%).No dispatch changes are attempted if the power in the monitored terminal stays within this band.
DSS property name: `%kWBand`, DSS property index: 6.
"""
def _get_kWBand(self) -> BatchFloat64ArrayProxy:
return BatchFloat64ArrayProxy(self, 7)
def _set_kWBand(self, value: Union[float, Float64Array], flags: enums.SetterFlags = 0):
self._set_batch_float64_array(7, value, flags)
kWBand = property(_get_kWBand, _set_kWBand) # type: BatchFloat64ArrayProxy
"""
Alternative way of specifying the bandwidth. (kW/kamps) of the dead band around the kW/kamps target value. Default is 2% of kWTarget (+/-1%).No dispatch changes are attempted if the power in the monitored terminal stays within this band.
DSS property name: `kWBand`, DSS property index: 7.