psr-factory 5.0.0b16__py3-none-win_amd64.whl → 5.0.0b18__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/cloud.py CHANGED
@@ -767,7 +767,7 @@ class Client:
767
767
 
768
768
  if extensions:
769
769
  Client._validate_extensions(extensions)
770
- filter_elements.extend([f".*.{ext}" for ext in extensions])
770
+ filter_elements.extend([f"*.{ext}" for ext in extensions])
771
771
 
772
772
  if files:
773
773
  filter_elements.extend(files)
psr/execqueue/client.py CHANGED
@@ -70,13 +70,13 @@ def upload_and_run_file(zip_path: str, server_url: str, cloud_execution: bool =
70
70
  return None
71
71
 
72
72
 
73
- def get_execution_status(execution_id: str, server_url: str, cloud_execution: bool = False, return_status_id: bool = False) -> Tuple[bool, dict]:
73
+ def get_execution_status(execution_id: str, server_url: str, cloud_execution: bool = False) -> Optional[tuple[int, str]]:
74
74
  """Get the status of an execution."""
75
- data = {'cloud_execution': cloud_execution, 'return_status_id': return_status_id}
75
+ print("Getting status for execution ID:", execution_id)
76
+ data = {'cloud_execution': cloud_execution}
76
77
  response = requests.get(f"{server_url}/status/{execution_id}", data=data)
77
78
  result = response.status_code == 200
78
- return result, response.json()
79
-
79
+ return response.json().get('status_id'), response.json().get('status_msg') if result else None
80
80
 
81
81
  def get_results(execution_id, server_url, cloud_execution=False) -> Optional[List[str]]:
82
82
  """Download the results of an execution."""
@@ -88,7 +88,7 @@ def get_results(execution_id, server_url, cloud_execution=False) -> Optional[Lis
88
88
  print("Files:", files)
89
89
  return files
90
90
  else:
91
- print("Download failed:", response.text)
91
+ print("Results download failed:", response.text)
92
92
  return None
93
93
 
94
94
 
psr/execqueue/db.py CHANGED
@@ -24,6 +24,7 @@ class CloudStatus(Enum):
24
24
  FINISHED = 3
25
25
  ERROR = 4
26
26
  RESULTS_AVAILABLE = 5
27
+ LOGS_AVAILABLE_ERROR = 6
27
28
 
28
29
 
29
30
  DB_NAME = "app.db"
@@ -217,4 +218,7 @@ def get_cloud_execution_status(session, repository_id: int) -> Optional[int]:
217
218
  return cloud_execution.status if cloud_execution else None
218
219
 
219
220
  def get_cloud_finished_executions(session) -> List[CloudExecution]:
220
- return session.query(CloudExecution).filter(CloudExecution.status == CloudStatus.FINISHED.value).all()
221
+ return session.query(CloudExecution).filter(CloudExecution.status == CloudStatus.FINISHED.value).all()
222
+
223
+ def get_cloud_failed_executions(session) -> List[CloudExecution]:
224
+ return session.query(CloudExecution).filter(CloudExecution.status == CloudStatus.ERROR.value).all()
psr/execqueue/server.py CHANGED
@@ -42,7 +42,7 @@ except psr.cloud.CloudInputError as e:
42
42
 
43
43
  _cloud_execution_case_map = {}
44
44
 
45
- app = Flask(__name__)
45
+ app = Flask(__name__, root_path=os.getcwd())
46
46
  session = None
47
47
 
48
48
 
@@ -76,7 +76,7 @@ def run_cloud_case(execution_id: str, case_path: str):
76
76
  name="LSEG Server "+ execution_id,
77
77
  data_path=case_path,
78
78
  program="SDDP",
79
- program_version = "17.2.12",
79
+ program_version = "17.3.9",
80
80
  execution_type="Default",
81
81
  memory_per_process_ratio='2:1',
82
82
  price_optimized=False,
@@ -180,6 +180,20 @@ def monitor_cloud_runs():
180
180
  result_path = os.path.join(CLOUD_RESULTS_FOLDER, str(repository_id))
181
181
  client.download_results(repository_id, result_path)
182
182
  db.update_cloud_execution_status(session, repository_id, db.CloudStatus.RESULTS_AVAILABLE.value)
183
+
184
+ #download failed executions
185
+ for cloud_execution in db.get_cloud_failed_executions(session):
186
+ try:
187
+ repository_id = cloud_execution.repository_id
188
+ print(f"Downloading results for {repository_id}...")
189
+ result_path = os.path.join(CLOUD_RESULTS_FOLDER, str(repository_id))
190
+ client.download_results(repository_id, result_path, extensions=['log'])
191
+ db.update_cloud_execution_status(session, repository_id, db.CloudStatus.LOGS_AVAILABLE_ERROR.value)
192
+ except Exception as e:
193
+ print(f"Error downloading results for {repository_id}: {e}")
194
+ print("Forcing execution to Failed downloaded execution")
195
+ db.update_cloud_execution_status(session, repository_id, db.CloudStatus.LOGS_AVAILABLE_ERROR.value)
196
+ continue
183
197
  else:
184
198
  print("Database not initialized. Retrying in 30s...")
185
199
  time.sleep(30)
@@ -282,30 +296,43 @@ def get_status(execution_id):
282
296
  200:
283
297
  description: Execution status
284
298
  schema:
285
- type: string
299
+ type: object
286
300
  404:
287
301
  description: Execution ID not found
288
- """
302
+ """
289
303
  global client
290
304
  global session
291
305
  cloud_execution = request.form.get('cloud_execution', 'false').lower() == 'true'
292
- return_status_id = request.form.get('return_status_id', 'false').lower() == 'true'
293
306
 
294
307
  if cloud_execution:
295
308
  repository_id = db.get_repository_id_from_cloud_upload_id(session, execution_id)
296
309
  if repository_id is None:
297
310
  return jsonify({'error': 'Execution ID not found in Cloud'}), 404
298
311
  status = db.get_cloud_execution_status(session, repository_id)
299
- if return_status_id:
300
- return jsonify({'status_id': status}), 200
312
+ print(status)
301
313
  if status == db.CloudStatus.ERROR.value:
302
- return jsonify({'message': 'Execution finished with errors'}), 200
314
+ status_msg = 'Execution finished with errors. Only log files will be downloaded'
303
315
  elif status == db.CloudStatus.RUNNING.value:
304
- return jsonify({'message': 'Execution not finished yet'}), 200
316
+ status_msg = 'Execution not finished yet'
305
317
  elif status == db.CloudStatus.FINISHED.value:
306
- return jsonify({'message': 'Execution finished, but download not yet downloaded from Cloud server'}), 200
318
+ status_msg = 'Execution finished, but download not yet started from Cloud server'
307
319
  elif status == db.CloudStatus.RESULTS_AVAILABLE.value:
308
- return jsonify({'message': 'Execution finished and results are available to download'}), 200
320
+ status_msg = 'Execution finished and results are available to download'
321
+ elif status == db.CloudStatus.LOGS_AVAILABLE_ERROR.value:
322
+ status_msg = 'Execution finished with errors and log files are avaialble to download'
323
+ else:
324
+ status_msg = 'Unknown status'
325
+ return jsonify({'status_id': status, 'status_msg': status_msg}), 200
326
+ else:
327
+ status = db.get_local_execution_status(session, execution_id)
328
+ if status == db.LOCAL_EXECUTION_ERROR:
329
+ status_msg = 'Execution finished with errors'
330
+ elif status != db.LOCAL_EXECUTION_FINISHED:
331
+ status_msg = 'Execution not finished yet'
332
+ else:
333
+ status_msg = 'Execution finished'
334
+ return jsonify({'status_id': status, 'status_msg': status_msg}), 200
335
+
309
336
 
310
337
  @app.route('/results/<execution_id>', methods=['GET'])
311
338
  def get_results(execution_id: str):
@@ -319,18 +346,17 @@ def get_results(execution_id: str):
319
346
  return jsonify({'error': 'Execution ID not found in Cloud'}),
320
347
  status = db.get_cloud_execution_status(session, execution_id)
321
348
 
322
- if status == db.CloudStatus.ERROR:
323
- return jsonify({'error': 'Execution Finished with errors'}), 401
324
- elif status == db.CloudStatus.RUNNING:
325
- return jsonify({'error': 'Execution not finished yet'}), 402
349
+ if status == db.CloudStatus.RUNNING:
350
+ return jsonify({'error': f'{repository_id} execution not finished yet'}), 402
326
351
  elif status == db.CloudStatus.FINISHED:
327
- return jsonify({'error': 'Results not available yet'}), 403
352
+ return jsonify({'error': f'{repository_id} results not available yet'}), 403
328
353
  else:
329
354
  #fazer download da pasta do resultado
330
355
  result_path = os.path.join(CLOUD_RESULTS_FOLDER, str(repository_id))
331
356
  if not os.path.exists(result_path):
332
- return jsonify({'error': 'Execution result folder not found'}), 404
357
+ return jsonify({'error': f'{repository_id} execution result folder not found'}), 404
333
358
  result_files = os.listdir(result_path)
359
+ result_files = [f for f in result_files if os.path.isfile(os.path.join(result_path, f))]
334
360
  return jsonify({'execution_id': repository_id, 'files': result_files}), 200
335
361
  else:
336
362
  status = db.get_local_execution_status(session, execution_id)
@@ -357,14 +383,18 @@ def download_file(execution_id: str, file):
357
383
  else:
358
384
  result_path = os.path.join(LOCAL_RESULTS_FOLDER, execution_id)
359
385
  if not os.path.exists(result_path):
360
- return jsonify({'error': 'Execution result folder not found'}), 404
386
+ if cloud_execution:
387
+ msg = f'{repository_id} execution result folder not found'
388
+ else:
389
+ msg = f'Execution result folder not found'
390
+ return jsonify({'error': msg}), 404
361
391
 
362
- file_path = os.path.join(result_path, file)
392
+ file_path = os.path.normpath(os.path.join(result_path, file)).replace("\\", "/")
363
393
  if not os.path.exists(file_path):
364
394
  return jsonify({'error': 'File not found'}), 404
365
395
 
366
396
  try:
367
- return send_file(file_path, as_attachment=True)
397
+ return send_file(file_path, download_name=file, as_attachment=True)
368
398
  except Exception as e:
369
399
  return jsonify({'error': str(e)}), 500
370
400
 
psr/execqueue/watcher.py CHANGED
@@ -12,7 +12,7 @@ SERVER_URL = os.getenv("SERVER_URL", "http://127.0.0.1:5000")
12
12
  WATCH_DIR = os.getenv("WATCH_DIR")
13
13
  PROCESSED_DIR = os.getenv("PROCESSED_DIR")
14
14
  RESULTS_DIR = os.getenv("RESULTS_DIR", "results")
15
- SLEEP_SECONDS = int(os.getenv("WATCHER_SLEEP", "30"))
15
+ SLEEP_SECONDS = int(os.getenv("WATCHER_SLEEP", "1"))
16
16
  DB_PATH = os.getenv("WATCHER_DB_PATH", "watcher.sqlite")
17
17
 
18
18
 
@@ -42,14 +42,32 @@ def _log_to_db(filename, cloud_upload_id):
42
42
  conn.commit()
43
43
  conn.close()
44
44
 
45
-
45
+ def _is_file_locked(filepath):
46
+ """Returns True if the file is locked by another process (e.g., still being copied)."""
47
+ if not os.path.exists(filepath):
48
+ return True
49
+ try:
50
+ # Try to open for exclusive writing
51
+ with open(filepath, 'rb+') as f:
52
+ pass
53
+ return False
54
+ except (OSError, PermissionError):
55
+ return True
56
+
46
57
  def _process_zip_files():
47
58
  for filename in os.listdir(WATCH_DIR):
48
59
  if filename.lower().endswith('.zip'):
49
60
  zip_path = os.path.join(WATCH_DIR, filename)
61
+
62
+ # Check if the file is locked
63
+ if _is_file_locked(zip_path):
64
+ logging.info(f"Skipping {zip_path}: file is locked or being copied.")
65
+ continue
66
+
50
67
  logging.info(f"zip file found: {zip_path}")
51
68
 
52
- case_id = execqueue.upload_case_file(zip_path, SERVER_URL)
69
+ #case_id = execqueue.upload_case_file(zip_path, SERVER_URL)
70
+ case_id = 1
53
71
  if not case_id:
54
72
  logging.error(f"Failed uploading file {zip_path}")
55
73
  continue
@@ -73,12 +91,14 @@ def _check_and_download_results():
73
91
  rows = cursor.fetchall()
74
92
  for row in rows:
75
93
  record_id, filename, cloud_upload_id = row
76
- result, response = execqueue.get_execution_status(cloud_upload_id, SERVER_URL, cloud_execution=True, return_status_id=True)
77
- status = response.get('status_id', 0)
78
- message = response.get('message', None)
79
- error = response.get('error', None)
80
- if status == "5" or status == 5:
94
+ status_id, status_msg = execqueue.get_execution_status(cloud_upload_id, SERVER_URL, cloud_execution=True)
95
+ logging.info(f"Execution status for {cloud_upload_id}: {status_id} - {status_msg}")
96
+ if status_id is None:
97
+ logging.error(f"Failed to get status for {cloud_upload_id}. Skipping download.")
98
+ continue
99
+ if status_id == 5 or status_id == 6:
81
100
  files = execqueue.get_results(cloud_upload_id, SERVER_URL, cloud_execution=True)
101
+ print("Files:", files)
82
102
  if files:
83
103
  base_filename = os.path.splitext(filename)[0]
84
104
  download_folder_name = f"{base_filename}-{cloud_upload_id}"
@@ -91,10 +111,6 @@ def _check_and_download_results():
91
111
  cursor.execute("UPDATE processed_files SET downloaded=1 WHERE id=?", (record_id,))
92
112
  conn.commit()
93
113
  logging.info(f"Results of {cloud_upload_id} downloaded to {download_path}")
94
- elif status == "4" or status == 4:
95
- logging.info(f"Execution {cloud_upload_id} is finished with errors.")
96
- cursor.execute("UPDATE processed_files SET downloaded=4 WHERE id=?", (record_id,))
97
- conn.commit()
98
114
 
99
115
  conn.close()
100
116
 
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__ = "5.0.0b16"
5
+ __version__ = "5.0.0b18"
6
6
 
7
7
  from .api import *
psr/factory/factory.dll CHANGED
Binary file
psr/factory/factory.pmd CHANGED
@@ -5036,6 +5036,8 @@ DEFINE_MODEL MODL:SDDP_V10.2_Bateria
5036
5036
 
5037
5037
  MERGE_MODEL SDDP_MAINTENANCE_PER_STAGE
5038
5038
  MERGE_MODEL SDDP_MAINTENANCE_PER_HOUR
5039
+
5040
+ PARM REFERENCE ControlledBus PSRBus
5039
5041
  END_MODEL
5040
5042
  //--------------------------------------------------------------------------------------------------
5041
5043
  // Modelo para Consumo de Combustivel
@@ -5044,6 +5046,7 @@ DEFINE_MODEL MODL:SDDP_ConsumoCombustivel
5044
5046
  DIMENSION block
5045
5047
  DIMENSION segment
5046
5048
  VETOR DATE Data
5049
+ VETOR REAL GerMax INDEX Data
5047
5050
  VETOR REAL O&MCost INDEX Data
5048
5051
  VETOR REAL G DIM(segment) INDEX Data
5049
5052
  VETOR REAL CTransp INDEX Data
psr/factory/factory.pmk CHANGED
@@ -16290,37 +16290,39 @@ END_MASK
16290
16290
  DEFINE_MASK CSVDATA SDDP_dbusshunt
16291
16291
  DEFINE_HEADER
16292
16292
  $version=1
16293
- !Code,Name,Bus,ControlledBus,ShuntControlType,Existing,NumberOfUnits,G,B
16293
+ !Code,Name,Bus,ControlledBus,ShuntControlType,Existing,NumberOfUnits,G,B,Decommissioned
16294
16294
  END_HEADER
16295
16295
  DEFINE_DATA
16296
- Code INTEGER,1
16297
- Name STRING,2
16298
- BusCode INTEGER,3
16299
- ControlledBusCode INTEGER,4
16300
- ShuntControlType INTEGER,5 AUTOSET(model.parm("ShuntControlType"))
16301
- Existing INTEGER,6 AUTOSET
16302
- NumberOfUnits INTEGER,7 AUTOSET
16303
- G REAL,8 AUTOSET
16304
- B REAL,9 AUTOSET
16296
+ Code INTEGER,1
16297
+ Name STRING,2
16298
+ BusCode INTEGER,3
16299
+ ControlledBusCode INTEGER,4
16300
+ ShuntControlType INTEGER,5 AUTOSET(model.parm("ShuntControlType"))
16301
+ Existing INTEGER,6 AUTOSET
16302
+ NumberOfUnits INTEGER,7 AUTOSET
16303
+ G REAL,8 AUTOSET
16304
+ B REAL,9 AUTOSET
16305
+ Decommissioned INTEGER,10 AUTOSET
16305
16306
  END_DATA
16306
16307
  END_MASK
16307
16308
  //---------------------------------------------------------------------
16308
16309
  DEFINE_MASK CSVDATA SDDP_mbusshunt
16309
16310
  DEFINE_HEADER
16310
16311
  $version=1
16311
- !Day,Month,Year,Code,Name,Bus,Existing,NumberOfUnits,G,B
16312
+ !Day,Month,Year,Code,Name,Bus,Existing,NumberOfUnits,G,B,Decommissioned
16312
16313
  END_HEADER
16313
16314
  DEFINE_DATA
16314
- Day INTEGER,1
16315
- Month INTEGER,2
16316
- Year INTEGER,3
16317
- Code INTEGER,4
16318
- Name STRING,5
16319
- BusCode INTEGER,6
16320
- Existing INTEGER,7 AUTOSET
16321
- NumberOfUnits INTEGER,8 AUTOSET
16322
- G REAL,9 AUTOSET
16323
- B REAL,10 AUTOSET
16315
+ Day INTEGER,1
16316
+ Month INTEGER,2
16317
+ Year INTEGER,3
16318
+ Code INTEGER,4
16319
+ Name STRING,5
16320
+ BusCode INTEGER,6
16321
+ Existing INTEGER,7 AUTOSET
16322
+ NumberOfUnits INTEGER,8 AUTOSET
16323
+ G REAL,9 AUTOSET
16324
+ B REAL,10 AUTOSET
16325
+ Decommissioned INTEGER,11 AUTOSET
16324
16326
  END_DATA
16325
16327
  END_MASK
16326
16328
 
@@ -16329,37 +16331,39 @@ END_MASK
16329
16331
  DEFINE_MASK CSVDATA SDDP_dlineshunt
16330
16332
  DEFINE_HEADER
16331
16333
  $version=1
16332
- !Code,Name,Circuit,Existing,Gfrom,Bfrom,Gto,Bto
16334
+ !Code,Name,Circuit,Existing,Gfrom,Bfrom,Gto,Bto,Decommissioned
16333
16335
  END_HEADER
16334
16336
  DEFINE_DATA
16335
- Code INTEGER,1
16336
- Name STRING,2
16337
- CircuitCode INTEGER,3
16338
- Existing INTEGER,4 AUTOSET
16339
- Gfrom REAL,5 AUTOSET
16340
- Bfrom REAL,6 AUTOSET
16341
- Gto REAL,7 AUTOSET
16342
- Bto REAL,8 AUTOSET
16337
+ Code INTEGER,1
16338
+ Name STRING,2
16339
+ CircuitCode INTEGER,3
16340
+ Existing INTEGER,4 AUTOSET
16341
+ Gfrom REAL,5 AUTOSET
16342
+ Bfrom REAL,6 AUTOSET
16343
+ Gto REAL,7 AUTOSET
16344
+ Bto REAL,8 AUTOSET
16345
+ Decommissioned INTEGER,9 AUTOSET
16343
16346
  END_DATA
16344
16347
  END_MASK
16345
16348
  //---------------------------------------------------------------------
16346
16349
  DEFINE_MASK CSVDATA SDDP_mlineshunt
16347
16350
  DEFINE_HEADER
16348
16351
  $version=1
16349
- !Day,Month,Year,Code,Name,Circuit,Existing,Gfrom,Bfrom,Gto,Bto
16352
+ !Day,Month,Year,Code,Name,Circuit,Existing,Gfrom,Bfrom,Gto,Bto,Decommissioned
16350
16353
  END_HEADER
16351
16354
  DEFINE_DATA
16352
- Day INTEGER,1
16353
- Month INTEGER,2
16354
- Year INTEGER,3
16355
- Code INTEGER,4
16356
- Name STRING,5
16357
- CircuitCode INTEGER,6
16358
- Existing INTEGER,7 AUTOSET
16359
- Gfrom REAL,8 AUTOSET
16360
- Bfrom REAL,9 AUTOSET
16361
- Gto REAL,10 AUTOSET
16362
- Bto REAL,11 AUTOSET
16355
+ Day INTEGER,1
16356
+ Month INTEGER,2
16357
+ Year INTEGER,3
16358
+ Code INTEGER,4
16359
+ Name STRING,5
16360
+ CircuitCode INTEGER,6
16361
+ Existing INTEGER,7 AUTOSET
16362
+ Gfrom REAL,8 AUTOSET
16363
+ Bfrom REAL,9 AUTOSET
16364
+ Gto REAL,10 AUTOSET
16365
+ Bto REAL,11 AUTOSET
16366
+ Decommissioned INTEGER,12 AUTOSET
16363
16367
  END_DATA
16364
16368
  END_MASK
16365
16369
  //---------------------------------------------------------------------
@@ -16367,7 +16371,7 @@ END_MASK
16367
16371
  DEFINE_MASK CSVDATA SDDP_dsvc
16368
16372
  DEFINE_HEADER
16369
16373
  $version=1
16370
- !Code,Name,Bus,ControlledBus,ReactivePowerControlType,LimitsCorrectionType,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,Droop
16374
+ !Code,Name,Bus,ControlledBus,ReactivePowerControlType,LimitsCorrectionType,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,Droop,Decommissioned
16371
16375
  END_HEADER
16372
16376
  DEFINE_DATA
16373
16377
  Code INTEGER,1
@@ -16381,6 +16385,7 @@ NumberOfUnits INTEGER,8 AUTOSET
16381
16385
  MinReactivePower REAL,9 AUTOSET
16382
16386
  MaxReactivePower REAL,10 AUTOSET
16383
16387
  Droop REAL,11 AUTOSET
16388
+ Decommissioned INTEGER,12 AUTOSET
16384
16389
  END_DATA
16385
16390
  END_MASK
16386
16391
  //---------------------------------------------------------------------
@@ -16388,7 +16393,7 @@ END_MASK
16388
16393
  DEFINE_MASK CSVDATA SDDP_msvc
16389
16394
  DEFINE_HEADER
16390
16395
  $version=1
16391
- !Day,Month,Year,Code,Name,Bus,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,Droop
16396
+ !Day,Month,Year,Code,Name,Bus,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,Droop,Decommissioned
16392
16397
  END_HEADER
16393
16398
  DEFINE_DATA
16394
16399
  Day INTEGER,1
@@ -16402,6 +16407,7 @@ NumberOfUnits INTEGER,8 AUTOSET
16402
16407
  MinReactivePower REAL,9 AUTOSET
16403
16408
  MaxReactivePower REAL,10 AUTOSET
16404
16409
  Droop REAL,11 AUTOSET
16410
+ Decommissioned INTEGER,12 AUTOSET
16405
16411
  END_DATA
16406
16412
  END_MASK
16407
16413
  //---------------------------------------------------------------------
@@ -16409,7 +16415,7 @@ END_MASK
16409
16415
  DEFINE_MASK CSVDATA SDDP_dsync
16410
16416
  DEFINE_HEADER
16411
16417
  $version=1
16412
- !Code,Name,Bus,ControlledBus,DeviceType,ReactivePowerControlType,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,GR,GX,TR,TX,Tap
16418
+ !Code,Name,Bus,ControlledBus,DeviceType,ReactivePowerControlType,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,GR,GX,TR,TX,Tap,Decommissioned
16413
16419
  END_HEADER
16414
16420
  DEFINE_DATA
16415
16421
  Code INTEGER,1
@@ -16427,6 +16433,7 @@ GX REAL,12 AUTOSET
16427
16433
  TR REAL,13 AUTOSET
16428
16434
  TX REAL,14 AUTOSET
16429
16435
  Tap REAL,15 AUTOSET
16436
+ Decommissioned INTEGER,16 AUTOSET
16430
16437
  END_DATA
16431
16438
  END_MASK
16432
16439
  //---------------------------------------------------------------------
@@ -16434,7 +16441,7 @@ END_MASK
16434
16441
  DEFINE_MASK CSVDATA SDDP_msync
16435
16442
  DEFINE_HEADER
16436
16443
  $version=1
16437
- !Day,Month,Year,Code,Name,Bus,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,GR,GX,TR,TX,Tap
16444
+ !Day,Month,Year,Code,Name,Bus,Existing,NumberOfUnits,MinReactivePower,MaxReactivePower,GR,GX,TR,TX,Tap,Decommissioned
16438
16445
  END_HEADER
16439
16446
  DEFINE_DATA
16440
16447
  Day INTEGER,1
@@ -16452,6 +16459,7 @@ GX REAL,12 AUTOSET
16452
16459
  TR REAL,13 AUTOSET
16453
16460
  TX REAL,14 AUTOSET
16454
16461
  Tap REAL,15 AUTOSET
16462
+ Decommissioned INTEGER,16 AUTOSET
16455
16463
  END_DATA
16456
16464
  END_MASK
16457
16465
  //---------------------------------------------------------------------
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psr-factory
3
- Version: 5.0.0b16
3
+ Version: 5.0.0b18
4
4
  Summary: PSR database management module.
5
5
  Author-email: "PSR Inc." <psrfactory@psr-inc.com>
6
6
  License-Expression: MIT
@@ -55,69 +55,3 @@ Requires-Dist: pefile; extra == "all"
55
55
  Requires-Dist: boto3; extra == "all"
56
56
  Requires-Dist: botocore; extra == "all"
57
57
  Dynamic: license-file
58
-
59
- PSR Factory (version 4.0.38)
60
- ============================
61
-
62
- Factory is a library that helps to manage SDDP cases.
63
- It contains functions that create, load, and save studies, and also functions that create,
64
- access, and modify objects in a study.
65
-
66
-
67
- Installation
68
- ------------
69
-
70
- ### System-wide installation
71
-
72
- Open the command prompt and run the following command:
73
-
74
- ```bash
75
- pip install psr_factory-4.0.38-py3-none-win_amd64.whl
76
- ```
77
-
78
- Factory will be available to all Python scripts in your system after importing it:
79
-
80
- ```python
81
- import psr.factory
82
- ```
83
-
84
- ### Local/project-specific usage
85
-
86
- Copy the folder `psr` and its contents to your project folder or a specific folder (e.g., `C:\path\to\factory`). Then, in your Python script, add the following lines:
87
-
88
- ```python
89
- import sys
90
- sys.path.append(r"C:\path\to\factory")
91
- import psr.factory
92
- ```
93
-
94
-
95
- Usage sample
96
- ------------
97
-
98
- ```python
99
- import psr.factory
100
-
101
- study = psr.factory.load_study(r"C:\temp\my\study")
102
- system_1 = study.find("System.*")[0]
103
-
104
- battery = psr.factory.create("Battery")
105
- battery.code = 1
106
- battery.name = "Battery 1"
107
- battery.set("InstalledCapacity", 10.0)
108
- battery.set("RefSystem", system_1)
109
- study.add(battery)
110
-
111
- study.save(r"C:\temp\my\updated_study")
112
- ```
113
-
114
-
115
- Full documentation
116
- ------------------
117
-
118
- The full documentation and reference is available at [https://docs.psr-inc.com/factory/](https://docs.psr-inc.com/manual/factory/).
119
-
120
- Releases
121
- --------
122
-
123
- New releases can be found in the release notes at [https://psrenergy-docs.github.io/factory/releases.html](https://psrenergy-docs.github.io/factory/releases.html).
@@ -3,7 +3,7 @@ psr/apps/apps.py,sha256=V8Ewht7P1I-3sSkV3dnbxbLjF2slxPjcmtzmVaLjiNY,6746
3
3
  psr/apps/version.py,sha256=vs459L6JsatAkUxna7BNG-vMCaXpO1Ye8c1bmkEx4U4,194
4
4
  psr/cloud/__init__.py,sha256=inZMwG7O9Fca9hg1BhqYObOYtTTJOkpuTIuXnkHJZkI,246
5
5
  psr/cloud/aws.py,sha256=ro8kBNVxpGDXgZ5haceqX-MAD-0F5KFDJJ4M6rRvwS8,9915
6
- psr/cloud/cloud.py,sha256=RNFUXCAj4IRAMWUUyiEeZfwOqVVZdN28UZPLPSbm-5Y,59207
6
+ psr/cloud/cloud.py,sha256=gLwVL4aJITo75F4x2k53TJx0-giBLF614p3t3NdfD9o,59206
7
7
  psr/cloud/data.py,sha256=oDJyzcNsA7aAYi_qJKCUjCeGZvN-25E8KjZ-5RamNLE,4160
8
8
  psr/cloud/desktop.py,sha256=JFroCMEFV1Nz3has74n7OVrGCg2lS7Ev5bcjdw2hRxY,2980
9
9
  psr/cloud/log.py,sha256=Dvhz1enIWlFWeaRK7JAAuZVPfODgoEIRNcHEmbEliyQ,1366
@@ -11,18 +11,18 @@ psr/cloud/status.py,sha256=vcI4B9S6wCt9maT5NNrVwYaEgGIvy6kkC1UVpJjYbtw,3607
11
11
  psr/cloud/tempfile.py,sha256=1IOeye0eKWnmBynK5K5FMWiTaEVhn4GbQ8_y0THEva0,3893
12
12
  psr/cloud/version.py,sha256=jwq5nQsan38iZF0lj5GFK7l9EIe4aSF1NzdcupAfHP4,192
13
13
  psr/cloud/xml.py,sha256=ac2lyflOQm8khPvJn0zmI26I4sfUDY6A_OTsxzbMQEs,1896
14
- psr/execqueue/client.py,sha256=EjhXXWZli8MZP1rkKuYA1EL-VxO4aAUYZKsRa1mrG6Q,4374
14
+ psr/execqueue/client.py,sha256=P89Yt76W2GqRXaG_MLsa0kXf0jPp-weBd3aSTRcDzcs,4443
15
15
  psr/execqueue/config.py,sha256=3KVwASOgRlymOSPeabotgBdLVB5sPKnPQ9og2q3LQfw,1418
16
- psr/execqueue/db.py,sha256=0pH5ksXChz6PR_GQs6OPokK3zVkY1-OZRAqYbVIEh9k,8281
17
- psr/execqueue/server.py,sha256=IwqVq0hTMAqAyvCF7FXQsf8i82NyWq2BjnZFDOjwg9s,13936
18
- psr/execqueue/watcher.py,sha256=34TdU6quJIjWoOBlIbP1fA6fxaX5WmV1tAhvrIL30Uo,5213
19
- psr/factory/__init__.py,sha256=5e6hOun9Gvg6IvtaHvmGapXhLCKr3HSbTvTf3Y-Go9M,219
16
+ psr/execqueue/db.py,sha256=e0DN3Z4a-iPuTXGqjrZQYKzntIjsSHjCb2242hcSM9c,8485
17
+ psr/execqueue/server.py,sha256=hZG8N_YWSfCgNIkVUNAhJrq1JMTEdsW64yr2cOHFaZ8,15671
18
+ psr/execqueue/watcher.py,sha256=OA6VlwB_wBzyzjn5PvTH2Q23iiG0_sWOzwpUQSFpbGQ,5698
19
+ psr/factory/__init__.py,sha256=pjwQFbgo2qEQbMdwUWidn9AjJIaCTy8qhFdyJihg3Qg,219
20
20
  psr/factory/api.py,sha256=OsjFnXgl6ltYtcpDIhvjauGFprVrIaHWPcMgCGJ1C1E,101464
21
- psr/factory/factory.dll,sha256=MUDduRCLNUWFKeZSTGcp3eHOf6-flroHH8JY39NUWrs,18274128
22
- psr/factory/factory.pmd,sha256=NEOeQifMlZfrfQqSgDdvH8yKqdIYhj7biZHeceROr8M,250454
23
- psr/factory/factory.pmk,sha256=2kvj37seFO_POOqRIdOZuWRs4wSZuWT7z1LuaXi6qbg,579764
21
+ psr/factory/factory.dll,sha256=j9OfgdGnEaJj2O0ZAhMDhM3grP_Eopcff7O7yEHbR6Y,18301440
22
+ psr/factory/factory.pmd,sha256=HryDY8T6vAV5r0W4ytKNPiIYcdn4LexrsVZ5qFYBZ-g,250535
23
+ psr/factory/factory.pmk,sha256=THhHxBKTBchru3fxTCos-pBAPJJnuug8T2dw0xniDfQ,580185
24
24
  psr/factory/factorylib.py,sha256=rwqu9lucfBhiFECDd5UVuy1K9jIJ54mUfxNPh4JhY4I,28182
25
- psr/factory/libcurl-x64.dll,sha256=3jBgZlBIITj6jzCW39wpf_2UE15DPORnnhLssEqtn5A,5317968
25
+ psr/factory/libcurl-x64.dll,sha256=6WGBmqX4q_eD8Vc0E2VpCvVrFV3W7TQoaKqSdbhXBu0,5313096
26
26
  psr/factory/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  psr/factory/samples/__init__.py,sha256=xxOch5Fokzjy571a6OHD87FWM17qKgvfcbr8xn-n36I,80
28
28
  psr/factory/samples/sddp_case01.py,sha256=eLhtOAS2STl9-H7Nr5VUG4ATO0bVcn-CJtCn3Rf-vpI,5044
@@ -33,8 +33,8 @@ psr/psrfcommon/tempfile.py,sha256=5S13wa2DCLYTUdwbLm_KMBRnDRJ0WDlu8GO2BmZoNdg,39
33
33
  psr/runner/__init__.py,sha256=kI9HDX-B_LMQJUHHylFHas2rNpWfNNa0pZXoIvX_Alw,230
34
34
  psr/runner/runner.py,sha256=L_YOCArpkr_O-UJH6aT3K46NlEYT_o7LA1Ldk81BULQ,27326
35
35
  psr/runner/version.py,sha256=mch2Y8anSXGMn9w72Z78PhSRhOyn55EwaoLAYhY4McE,194
36
- psr_factory-5.0.0b16.dist-info/licenses/LICENSE.txt,sha256=N6mqZK2Ft3iXGHj-by_MHC_dJo9qwn0URjakEPys3H4,1089
37
- psr_factory-5.0.0b16.dist-info/METADATA,sha256=14_8lrA8js0kxIo0wQSWJqkBq8fGSM1cQMobvtGPwgE,3957
38
- psr_factory-5.0.0b16.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
39
- psr_factory-5.0.0b16.dist-info/top_level.txt,sha256=Jb393O96WQk3b5D1gMcrZBLKJJgZpzNjTPoldUi00ck,4
40
- psr_factory-5.0.0b16.dist-info/RECORD,,
36
+ psr_factory-5.0.0b18.dist-info/licenses/LICENSE.txt,sha256=N6mqZK2Ft3iXGHj-by_MHC_dJo9qwn0URjakEPys3H4,1089
37
+ psr_factory-5.0.0b18.dist-info/METADATA,sha256=9sExuScetDk6-Dol258BScFa1k26f4w_p8LNH-QA320,2333
38
+ psr_factory-5.0.0b18.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
39
+ psr_factory-5.0.0b18.dist-info/top_level.txt,sha256=Jb393O96WQk3b5D1gMcrZBLKJJgZpzNjTPoldUi00ck,4
40
+ psr_factory-5.0.0b18.dist-info/RECORD,,