psr-factory 4.1.0b1__py3-none-win_amd64.whl → 4.1.0b3__py3-none-win_amd64.whl

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.
psr/cloud/data.py ADDED
@@ -0,0 +1,105 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ import os
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+ from typing import List, Optional, Tuple, Union
9
+
10
+
11
+ class CloudInputError(ValueError):
12
+ """Raised when invalid input is provided."""
13
+
14
+ pass
15
+
16
+
17
+ class CloudError(RuntimeError):
18
+ """Raised when case remote execution fails."""
19
+
20
+ pass
21
+
22
+
23
+ class Case:
24
+ def __init__(
25
+ self,
26
+ name: str,
27
+ data_path: Optional[Union[str, Path]],
28
+ program: str,
29
+ program_version: Union[str, int],
30
+ execution_type: Union[str, int],
31
+ price_optimized: bool,
32
+ number_of_processes: int,
33
+ memory_per_process_ratio: str,
34
+ **kwargs,
35
+ ) -> None:
36
+ self.name: str = name
37
+ self._validate_type(self.name, str, "Case name must be a string")
38
+
39
+ self.data_path: str = str(data_path)
40
+ if data_path and not os.path.isabs(data_path):
41
+ self.data_path = os.path.abspath(data_path)
42
+ if data_path and not Path(data_path).exists():
43
+ raise CloudInputError("Data path does not exist")
44
+
45
+ self.program: str = program
46
+ self._validate_type(self.program, str, "Program must be a string")
47
+
48
+ self.program_version: Union[str, int] = program_version
49
+ self._validate_type(
50
+ self.program_version,
51
+ (int, str),
52
+ "Program version must be an integer or string (id or name)",
53
+ )
54
+
55
+ self.execution_type: Union[str, int] = execution_type
56
+ self._validate_type(
57
+ self.execution_type,
58
+ (int, str),
59
+ "Execution type must be an integer or string (id or name)",
60
+ )
61
+
62
+ self.price_optimized: bool = price_optimized
63
+ self._validate_type(
64
+ self.price_optimized, bool, "price_optimized must be a boolean"
65
+ )
66
+
67
+ self.number_of_processes: int = number_of_processes
68
+ self._validate_type(
69
+ self.number_of_processes, int, "Number of processes must be an integer"
70
+ )
71
+
72
+ self.memory_per_process_ratio: str = memory_per_process_ratio
73
+ self._validate_type(
74
+ self.memory_per_process_ratio,
75
+ str,
76
+ "Memory per process ratio must be a string",
77
+ )
78
+
79
+ self.repository_duration: Optional[Union[str, int]] = kwargs.get("repository_duration", 2)
80
+ self._validate_type(
81
+ self.repository_duration,
82
+ (int, str),
83
+ "Repository duration must be an integer or string (id or name)",
84
+ )
85
+
86
+ self.id: Optional[int] = kwargs.get("id", None)
87
+ self.user: Optional[str] = kwargs.get("user", None)
88
+ self.parent_case_id: Optional[int] = kwargs.get("parent_case_id", None)
89
+ self.execution_date: Optional[datetime] = kwargs.get("execution_date", None)
90
+ self.budget: Optional[str] = kwargs.get("budget", None)
91
+ if self.budget is not None:
92
+ self.budget = self.budget.strip()
93
+
94
+ # Save In Cloud
95
+ self.upload_only = kwargs.get("upload_only", False)
96
+
97
+ @staticmethod
98
+ def _validate_type(
99
+ value, expected_type: Union[List[type], Tuple[type], type], error_message: str
100
+ ):
101
+ if not isinstance(value, expected_type):
102
+ raise CloudInputError(error_message)
103
+
104
+ def __str__(self):
105
+ return str(self.__dict__)
psr/cloud/desktop.py ADDED
@@ -0,0 +1,82 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ import os
6
+ import xml.etree.ElementTree as ET
7
+ from datetime import datetime
8
+ from typing import Optional
9
+
10
+ from .data import Case
11
+ from .xml import create_desktop_xml
12
+
13
+
14
+ def import_case(case: Case, console_cluster: str, instance_type_id: int) -> None:
15
+ case_counter = _get_last_case_id()
16
+ filepath = os.path.expandvars(
17
+ os.path.join(r"%appdata%\PSR\PSRCloud\Dados", f"Caso{case_counter}.xml")
18
+ )
19
+ now = datetime.now()
20
+ case_datetime = now.strftime("%d/%m/%Y %H:%M")
21
+ case_date = now.strftime("%d/%m/%Y")
22
+ case_lifetime = ""
23
+ case_budget = "" if case.budget is None else case.budget
24
+ repositorio_template = (
25
+ case.parent_case_id
26
+ if case.parent_case_id is not None and case.parent_case_id != 0
27
+ else ""
28
+ )
29
+
30
+ parameters = {
31
+ "Id": str(case_counter),
32
+ "IdRepositorio": str(case.id),
33
+ "IdFila": str(case.id),
34
+ "Modelo": case.program.upper(),
35
+ "RepositorioTemplate": repositorio_template,
36
+ "DirDados": case.data_path,
37
+ "TipoExecucao": str(case.execution_type),
38
+ "InstanciaTipo": str(instance_type_id),
39
+ "Cluster": console_cluster,
40
+ "ClusterSrv": console_cluster,
41
+ "DtX": case_datetime,
42
+ "NProc": str(case.number_of_processes),
43
+ "Versao": str(case.program_version),
44
+ "Status": "2",
45
+ "StatusX": "Executando",
46
+ "Budget": case_budget,
47
+ "PodeListarFila": "True",
48
+ "IdX": case.name,
49
+ "Nom": case.name,
50
+ "Tag": f"PyCloud\\{case_date.replace('/', '-')}",
51
+ "DuracaoRepositorio": case_lifetime,
52
+ "FlagMaqNormalS": "False",
53
+ }
54
+
55
+ with open(filepath, "w", encoding="utf-8") as f:
56
+ xml_contents = create_desktop_xml(parameters)
57
+ f.write(xml_contents)
58
+
59
+
60
+ def _get_last_case_id() -> Optional[int]:
61
+ config_path = os.path.expandvars(r"%appdata%\PSR\PSRCloud\ePSRConfig.xml")
62
+ data_path = os.path.expandvars(r"%appdata%\PSR\PSRCloud\Dados")
63
+
64
+ if os.path.isfile(config_path):
65
+ xml = ET.parse(config_path, parser=ET.XMLParser(encoding="utf-16"))
66
+ root = xml.getroot()
67
+ last_case_id = None
68
+ for child in root.iter("Aplicacao"):
69
+ last_case_id = int(child.get("idUltimoCaso"))
70
+ break
71
+ if last_case_id is not None:
72
+ # Check for existing files with the same
73
+ # last_case_id. Increment it if necessary.
74
+ last_case_id = int(last_case_id)
75
+ files = os.listdir(data_path)
76
+ while f"Caso{last_case_id}.xml" in files:
77
+ last_case_id += 1
78
+ return last_case_id
79
+ # No case has been run yet
80
+ return None
81
+ else:
82
+ raise Exception("ERROR: PSR Cloud Desktop is not installed.")
psr/cloud/log.py ADDED
@@ -0,0 +1,40 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ import logging
6
+ import os
7
+
8
+
9
+ def get_logger(
10
+ id: int, quiet: bool, debug_mode: bool, log_dir: str = os.getcwd()
11
+ ) -> logging.Logger:
12
+ logger = logging.getLogger(str(id))
13
+ logger.setLevel(logging.DEBUG)
14
+ formatter = logging.Formatter("%(asctime)s - %(message)s")
15
+
16
+ if debug_mode:
17
+ os.makedirs(log_dir, exist_ok=True)
18
+ file_handler = logging.FileHandler(f"{log_dir}/psr_cloud_console_{id}.log")
19
+ file_handler.setLevel(logging.DEBUG)
20
+ file_handler.setFormatter(formatter)
21
+ logger.addHandler(file_handler)
22
+
23
+ if not quiet:
24
+ console_handler = logging.StreamHandler()
25
+ if debug_mode:
26
+ console_handler.setLevel(logging.DEBUG)
27
+ else:
28
+ console_handler.setLevel(logging.INFO)
29
+ console_handler.setFormatter(formatter)
30
+ logger.addHandler(console_handler)
31
+
32
+ return logger
33
+
34
+
35
+ def enable_log_timestamp(logger: logging.Logger, enable: bool) -> None:
36
+ for handler in logger.handlers:
37
+ if enable:
38
+ handler.setFormatter(logging.Formatter("%(asctime)s - %(message)s"))
39
+ else:
40
+ handler.setFormatter(logging.Formatter("%(message)s"))
psr/cloud/status.py ADDED
@@ -0,0 +1,81 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ from enum import Enum
6
+
7
+
8
+ class ExecutionStatus(Enum):
9
+ QUEUE = 0
10
+ PENDING = 1
11
+ RUNNING = 2
12
+ SUCCESS = 3
13
+ ERROR = 4
14
+ SYNC_ERROR = 5
15
+ WAITING_CANCEL = 6
16
+ CANCELLED = 7
17
+ NOT_IN_QUEUE = 8
18
+ CANCELLED_PENDING = 9
19
+ WAITING_MACHINE = 10
20
+ WAITING_SPOT = 11
21
+ SPOT_ACTIVE = 12
22
+ SPOT_CANCELLED = 13
23
+ SPOT_CANCELLED_PENDING = 14
24
+ SERVER_CANCELLED = 15
25
+ ABORTED = 16
26
+ WAITING_STOP = 17
27
+ STOPPED = 18
28
+ CANCELLED_IDLE = 19
29
+ WAITING_START = 20
30
+ WAITING_MACHINE_ON = 21
31
+ WAITING_ARCHITECTURE = 22
32
+ WARNING = 23
33
+ PARENT_CASE_FAILED = 24
34
+ RESTART_INTERRUPTED = 27
35
+ SPECIAL_WAITING = 30
36
+ WAITING_UPLOAD_QUEUE = 31
37
+ UPLOADED = 32
38
+
39
+
40
+ FAULTY_TERMINATION_STATUS = [
41
+ ExecutionStatus.ERROR,
42
+ ExecutionStatus.SYNC_ERROR,
43
+ ExecutionStatus.CANCELLED,
44
+ ExecutionStatus.NOT_IN_QUEUE,
45
+ ExecutionStatus.ABORTED,
46
+ ExecutionStatus.CANCELLED_IDLE,
47
+ ExecutionStatus.RESTART_INTERRUPTED,
48
+ ]
49
+
50
+ FINISHED_STATUS = FAULTY_TERMINATION_STATUS + [ExecutionStatus.SUCCESS]
51
+
52
+ STATUS_MAP_TEXT = {
53
+ ExecutionStatus.QUEUE: "Item in the queue without machine allocations",
54
+ ExecutionStatus.PENDING: "Waiting to turn machines on",
55
+ ExecutionStatus.RUNNING: "Running",
56
+ ExecutionStatus.SUCCESS: "Finished successfully",
57
+ ExecutionStatus.ERROR: "Finished with errors",
58
+ ExecutionStatus.SYNC_ERROR: "Finished due to lack of update request in a synchronous execution",
59
+ ExecutionStatus.WAITING_CANCEL: "The cancellation was requested, but there is still no response from the queue processor",
60
+ ExecutionStatus.CANCELLED: "Cancelled process",
61
+ ExecutionStatus.NOT_IN_QUEUE: "Process is not in the queue",
62
+ ExecutionStatus.CANCELLED_PENDING: "The cancellation process has already been called, but there is still no response from the Process Handler to complete the cancellation",
63
+ ExecutionStatus.WAITING_MACHINE: "State where the queue is waiting for the machines to be connected to move to PENDING state",
64
+ ExecutionStatus.WAITING_SPOT: "Waiting for the spot offer to be made",
65
+ ExecutionStatus.SPOT_ACTIVE: "The bid is in active mode",
66
+ ExecutionStatus.SPOT_CANCELLED: "The platform requested cancellation, but there is still no response from the Queue Processor",
67
+ ExecutionStatus.SPOT_CANCELLED_PENDING: "The cancellation process has already been called by the server, but there is still no response from the Process Handler to complete the cancellation",
68
+ ExecutionStatus.SERVER_CANCELLED: "Cancelled process by the server",
69
+ ExecutionStatus.ABORTED: "The model runs more aborts due to lack of input files",
70
+ ExecutionStatus.WAITING_STOP: "Waiting for STOP by the queue processor",
71
+ ExecutionStatus.STOPPED: "STOP machines in the round are frozen",
72
+ ExecutionStatus.CANCELLED_IDLE: "Cancelled after being idle",
73
+ ExecutionStatus.WAITING_START: "Waiting for START by the queue processor",
74
+ ExecutionStatus.WAITING_MACHINE_ON: "Waiting for machine to turn on",
75
+ ExecutionStatus.WAITING_ARCHITECTURE: "Waiting for architecture change",
76
+ ExecutionStatus.WARNING: "Finished with warnings",
77
+ ExecutionStatus.PARENT_CASE_FAILED: "Parent case failed",
78
+ ExecutionStatus.SPECIAL_WAITING: "Special Waiting",
79
+ ExecutionStatus.WAITING_UPLOAD_QUEUE: "Waiting for uploading case",
80
+ ExecutionStatus.UPLOADED: "Uploaded and Saved in Cloud",
81
+ }
psr/cloud/tempfile.py ADDED
@@ -0,0 +1,117 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ import errno
6
+ import io
7
+ import os
8
+ from random import Random
9
+
10
+
11
+ class _RandomNameSequence:
12
+ """An instance of _RandomNameSequence generates an endless
13
+ sequence of unpredictable strings which can safely be incorporated
14
+ into file names. Each string is eight characters long. Multiple
15
+ threads can safely use the same instance at the same time.
16
+
17
+ _RandomNameSequence is an iterator."""
18
+
19
+ # Method extracted from tempfile Python's module.
20
+
21
+ characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
22
+
23
+ @property
24
+ def rng(self):
25
+ cur_pid = os.getpid()
26
+ if cur_pid != getattr(self, "_rng_pid", None):
27
+ self._rng = Random() # nosec
28
+ self._rng_pid = cur_pid
29
+ return self._rng
30
+
31
+ def __iter__(self):
32
+ return self
33
+
34
+ def __next__(self):
35
+ c = self.characters
36
+ choose = self.rng.choice
37
+ letters = [choose(c) for dummy in range(8)]
38
+ return "".join(letters)
39
+
40
+
41
+ def _get_tempfile_name(base_path: str, prefix: str):
42
+ """Calculate the default directory to use for temporary files.
43
+ This routine should be called exactly once.
44
+
45
+ We determine whether a candidate temp dir is usable by
46
+ trying to create and write to a file in that directory. If this
47
+ is successful, the test file is deleted. To prevent denial of
48
+ service, the name of the test file must be randomized."""
49
+ # Method extracted from tempfile Python's module.
50
+
51
+ _text_openflags = os.O_RDWR | os.O_CREAT | os.O_EXCL
52
+ if hasattr(os, "O_NOFOLLOW"):
53
+ _text_openflags |= os.O_NOFOLLOW
54
+
55
+ _bin_openflags = _text_openflags
56
+ if hasattr(os, "O_BINARY"):
57
+ _bin_openflags |= os.O_BINARY
58
+
59
+ namer = _RandomNameSequence()
60
+
61
+ if base_path != os.curdir:
62
+ base_path = os.path.abspath(base_path)
63
+ # Try only a few names per directory.
64
+ for seq in range(100):
65
+ name = next(namer)
66
+ filename = os.path.join(base_path, prefix + name)
67
+ try:
68
+ fd = os.open(filename, _bin_openflags, 0o600)
69
+ try:
70
+ try:
71
+ with io.open(fd, "wb", closefd=False) as fp:
72
+ fp.write(b"blat")
73
+ finally:
74
+ os.close(fd)
75
+ finally:
76
+ os.unlink(filename)
77
+ return filename
78
+ except FileExistsError:
79
+ pass
80
+ except PermissionError:
81
+ # This exception is thrown when a directory with the chosen name
82
+ # already exists on windows.
83
+ if (
84
+ os.name == "nt"
85
+ and os.path.isdir(base_path)
86
+ and os.access(base_path, os.W_OK)
87
+ ):
88
+ continue
89
+ break # no point trying more names in this directory
90
+ except OSError:
91
+ break # no point trying more names in this directory
92
+ raise FileNotFoundError(
93
+ errno.ENOENT, "No usable temporary file found in " % base_path
94
+ )
95
+
96
+
97
+ class CreateTempFile:
98
+ def __init__(
99
+ self,
100
+ base_path: str,
101
+ prefix: str,
102
+ xml_content: str,
103
+ delete_temp_xml: bool = True,
104
+ ):
105
+ self.delete_temp_xml = delete_temp_xml
106
+ # get temp file name
107
+ self.xml_file_name = _get_tempfile_name(base_path, prefix) + ".xml"
108
+ self.xml_content = xml_content
109
+
110
+ def __enter__(self):
111
+ with open(self.xml_file_name, "w", encoding="utf-8-sig") as xml_file:
112
+ xml_file.write(self.xml_content)
113
+ return xml_file
114
+
115
+ def __exit__(self, exc_type, exc_val, exc_tb):
116
+ if self.delete_temp_xml:
117
+ os.remove(self.xml_file_name)
psr/cloud/version.py ADDED
@@ -0,0 +1,5 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ __version__ = "0.3.0"
psr/cloud/xml.py ADDED
@@ -0,0 +1,55 @@
1
+ # PSR Cloud. Copyright (C) PSR, Inc - All Rights Reserved
2
+ # Unauthorized copying of this file, via any medium is strictly prohibited
3
+ # Proprietary and confidential
4
+
5
+ from typing import Any, Dict
6
+ from xml.etree import ElementTree as ET
7
+
8
+
9
+ def create_case_xml(parameters: Dict[str, Any]) -> str:
10
+ root = ET.Element("ColecaoParametro")
11
+ for name, value in parameters.items():
12
+ value = _handle_invalid_xml_chars(value)
13
+ parameter = ET.SubElement(root, "Parametro", nome=name, tipo="System.String")
14
+ parameter.text = value
15
+ ET.indent(root, " ")
16
+ return ET.tostring(root, encoding="unicode", method="xml")
17
+
18
+
19
+ def create_desktop_xml(parameters: Dict[str, Any]) -> str:
20
+ # use element tree to write the file contents instead
21
+ node = ET.Element("Repositorio")
22
+ case_node = ET.SubElement(node, "CasoOperacao")
23
+ for key, value in parameters.items():
24
+ value_escaped = _handle_invalid_xml_chars(value)
25
+ case_node.set(key, value_escaped)
26
+ tree = ET.ElementTree(node)
27
+ return ET.tostring(
28
+ tree.getroot(), encoding="unicode", method="xml", xml_declaration=False
29
+ )
30
+
31
+
32
+ def _return_invalid_xml_chars(xml_content: str) -> str:
33
+ special_chars = {
34
+ "&": "&",
35
+ "&lt;": "<",
36
+ "&gt;": ">",
37
+ "&quot;": '"',
38
+ "&apos;": "'",
39
+ }
40
+ for char, replacement in special_chars.items():
41
+ xml_content = xml_content.replace(char, replacement)
42
+ return xml_content
43
+
44
+
45
+ def _handle_invalid_xml_chars(xml_content: str) -> str:
46
+ special_chars = {
47
+ "&": "&amp;",
48
+ "<": "&lt;",
49
+ ">": "&gt;",
50
+ '"': "&quot;",
51
+ "'": "&apos;",
52
+ }
53
+ for char, replacement in special_chars.items():
54
+ xml_content = str(xml_content).replace(char, replacement)
55
+ return xml_content
psr/factory/__init__.py CHANGED
@@ -2,6 +2,6 @@
2
2
  # Unauthorized copying of this file, via any medium is strictly prohibited
3
3
  # Proprietary and confidential
4
4
 
5
- __version__ = "4.1.0b1"
5
+ __version__ = "4.1.0b3"
6
6
 
7
7
  from .api import *
psr/factory/api.py CHANGED
@@ -2174,6 +2174,10 @@ def _initialize():
2174
2174
  "INDEX_STARTS_AT_ZERO": True,
2175
2175
  "NAME": "Python",
2176
2176
  "VERSION": f"{sys.version}",
2177
+ "EXE": f"{sys.executable}",
2178
+ "LIB": f"{factorylib.get_lib_path()}",
2179
+ "BASE_PREFIX": f"{sys.base_prefix}",
2180
+ "REAL_PREFIX": f"{sys.prefix}",
2177
2181
  }
2178
2182
  for prop, value in map_prop_values.items():
2179
2183
  _value = Value()
psr/factory/factory.dll CHANGED
Binary file
psr/factory/factory.pmd CHANGED
@@ -2914,6 +2914,8 @@ DEFINE_MODEL MODL:Optmain_Options
2914
2914
  PARM INTEGER RFBF
2915
2915
  PARM INTEGER ASNM
2916
2916
  PARM INTEGER ASDT
2917
+ PARM INTEGER TUNE
2918
+ PARM INTEGER NCVR
2917
2919
  END_MODEL
2918
2920
 
2919
2921
  //--------------------------------------------------------------------------------------------------
@@ -4103,6 +4105,7 @@ DEFINE_MODEL MODL:SDDP_V10.2_Hidro
4103
4105
  VETOR DATE Data @addyear_modification
4104
4106
  VETOR INTEGER Existing INDEX Data
4105
4107
  VETOR INTEGER Unidades INDEX Data
4108
+ VETOR REAL MinGen INDEX Data
4106
4109
  VETOR REAL PotInst INDEX Data
4107
4110
  VETOR REAL FPMed INDEX Data
4108
4111
  VETOR REAL Qmin INDEX Data
@@ -4245,6 +4248,10 @@ DEFINE_MODEL MODL:SDDP_V10.2_Hidro
4245
4248
  PARM INTEGER SingleReserveInfo
4246
4249
  PARM INTEGER SingleReserveUnit
4247
4250
 
4251
+ PARM REAL MinTurbiningPenalty
4252
+ VETOR DATE DataMinTurbining @chronological @addyear_chronological
4253
+ VETOR REAL MinTurbining INDEX DataMinTurbining
4254
+
4248
4255
  PARM REAL MaxTurbiningPenalty
4249
4256
  VETOR DATE DataMaxTurbining @chronological @addyear_chronological
4250
4257
  VETOR REAL MaxTurbining INDEX DataMaxTurbining
@@ -4998,7 +5005,7 @@ DEFINE_MODEL MODL:SDDP_WaterWay
4998
5005
  PARM REAL FlowMax
4999
5006
  VETOR DATE DataFlowMaximum
5000
5007
  VETOR REAL FlowMaximum INDEX DataFlowMaximum
5001
- PARM INTEGER TravelTime
5008
+ PARM REAL TravelTime
5002
5009
  PARM INTEGER Disabled
5003
5010
  END_MODEL
5004
5011
 
@@ -5238,6 +5245,38 @@ DEFINE_MODEL MODL:SDDP_Execution_Options
5238
5245
  PARM INTEGER HIRS
5239
5246
  PARM INTEGER FINJ
5240
5247
  PARM INTEGER ETYP
5248
+ PARM INTEGER RFCF
5249
+ PARM INTEGER PFCF
5250
+ PARM INTEGER PENL
5251
+ PARM INTEGER LSFI
5252
+ PARM INTEGER FIXL
5253
+ PARM INTEGER HCMT
5254
+ PARM REAL MXFT
5255
+ PARM INTEGER HLFR
5256
+ PARM INTEGER LSUP
5257
+ PARM INTEGER PVNC
5258
+ PARM INTEGER HMEM
5259
+ PARM INTEGER HTPP
5260
+ PARM INTEGER FSCN
5261
+ PARM INTEGER SKPS
5262
+ PARM REAL MMPP
5263
+ PARM INTEGER FMIP
5264
+ PARM INTEGER MUPR
5265
+ PARM INTEGER MXBD
5266
+ PARM REAL TOLR
5267
+ PARM INTEGER IGMR
5268
+ PARM REAL GCTE
5269
+ PARM INTEGER LCIR
5270
+ PARM INTEGER VSEC
5271
+ PARM INTEGER SRPD
5272
+ PARM INTEGER LSST
5273
+ PARM REAL LLSF
5274
+ PARM INTEGER GLLS
5275
+ PARM INTEGER LSAL
5276
+ PARM INTEGER PTOU
5277
+ PARM INTEGER SHOT
5278
+ PARM INTEGER FCFO
5279
+ PARM INTEGER HYRM
5241
5280
 
5242
5281
  PARM REAL NCPL_MIPR
5243
5282
  PARM REAL NCPL_LTOL
@@ -5281,10 +5320,13 @@ END_MODEL
5281
5320
  // Generic variable
5282
5321
  //--------------------------------------------------------------------------------------------------
5283
5322
  DEFINE_MODEL PSRGenericVariable
5284
- PARM STRING unit
5285
- PARM INTEGER resol
5323
+ PARM STRING unit
5324
+ PARM INTEGER resol
5286
5325
  PARM INTEGER type // 0 continuous, 1 binary
5326
+ PARM INTEGER UseCostAndBounds //determines if following values are used
5287
5327
  PARM REAL cost
5328
+ PARM REAL UpperBound
5329
+ PARM REAL LowerBound
5288
5330
  END_MODEL
5289
5331
 
5290
5332
  //--------------------------------------------------------------------------------------------------
@@ -5295,6 +5337,7 @@ DEFINE_MODEL PSRHydroUnit
5295
5337
  VETOR INTEGER Nunits INDEX Data
5296
5338
  VETOR REAL MinTurb INDEX Data
5297
5339
  VETOR REAL MaxTurb INDEX Data
5340
+ VETOR REAL MinGen INDEX Data
5298
5341
  VETOR REAL MaxGen INDEX Data
5299
5342
  VETOR INTEGER Existing INDEX Data
5300
5343
  END_MODEL
@@ -5329,10 +5372,10 @@ END_MODEL
5329
5372
  DEFINE_MODEL MODL:SDDP_Area
5330
5373
  DIMENSION block
5331
5374
 
5332
- //--- Importação da Area do ---
5333
- VETOR DATE DateTransfer @addyear_modification
5334
- VETOR REAL MaxImport DIM(block) INDEX DateTransfer
5335
- VETOR REAL MaxExport DIM(block) INDEX DateTransfer
5375
+ VETOR DATE DateMinTransfer @addyear_modification
5376
+ VETOR DATE DateMaxTransfer @addyear_modification
5377
+ VETOR REAL MinTransfer DIM(block) INDEX DateMinTransfer
5378
+ VETOR REAL MaxTransfer DIM(block) INDEX DateMaxTransfer
5336
5379
  END_MODEL
5337
5380
 
5338
5381
  //----------------------------------------------------------------------
@@ -5694,6 +5737,7 @@ DEFINE_MODEL MODL:SDDP_FlowController
5694
5737
  VETOR REAL Xmax INDEX Data
5695
5738
  VETOR REAL Rn INDEX Data
5696
5739
  VETOR REAL Re INDEX Data
5740
+ VETOR REAL MaxPower INDEX Data
5697
5741
 
5698
5742
  PARM INTEGER Location
5699
5743
  PARM INTEGER FlowControlType
@@ -5949,6 +5993,7 @@ DEFINE_CLASS PSRGenerationOfferHydroPlant
5949
5993
  VECTOR DATE Date @addyear_modification
5950
5994
  VECTOR REAL Price INDEX Date
5951
5995
  VECTOR REAL Quantity INDEX Date
5996
+ PARM REFERENCE Plant PSRHydroPlant
5952
5997
  END_CLASS
5953
5998
 
5954
5999
  DEFINE_CLASS PSRGenerationOfferThermalPlant
@@ -5958,6 +6003,7 @@ DEFINE_CLASS PSRGenerationOfferThermalPlant
5958
6003
  VECTOR DATE Date @addyear_modification
5959
6004
  VECTOR REAL Price INDEX Date
5960
6005
  VECTOR REAL Quantity INDEX Date
6006
+ PARM REFERENCE Plant PSRThermalPlant
5961
6007
  END_CLASS
5962
6008
 
5963
6009
  DEFINE_CLASS PSRGenerationOfferRenewablePlant
@@ -5967,6 +6013,7 @@ DEFINE_CLASS PSRGenerationOfferRenewablePlant
5967
6013
  VECTOR DATE Date @addyear_modification
5968
6014
  VECTOR REAL Price INDEX Date
5969
6015
  VECTOR REAL Quantity INDEX Date
6016
+ PARM REFERENCE Plant PSRGndPlant
5970
6017
  END_CLASS
5971
6018
 
5972
6019
  //----------------------------------------------------------------------