Configure PowerFactory contingency result recording - #89
qian-harvard merged 2 commits into
Conversation
|
Implemented and validated the contingency result-recording support in What changedAdded
Documentation was also updated in:
PR scopeThe PR contains one commit and changes only:
Diff summary:
Result contractA successful
Each entry in Automated validationPowerFactory-focused suite:
Repository suite:
GitHub Actions:
Live PowerFactory validationEnvironment:
The study case was activated successfully: {
"success": true,
"message": "Study case already existed and was activated: Case 1"
}The recording tool was then called with: {
"object_query": "Bus 08.ElmTerm",
"variables": [
"m:u",
"m:phiu"
],
"calculation_method": "ac",
"max_objects": 10
}Relevant response: {
"success": true,
"calculation_method": "ac",
"result_file": {
"name": "Contingency Analysis AC",
"class_name": "ElmRes"
},
"query": "Bus 08.ElmTerm",
"variables": [
"m:u",
"m:phiu"
],
"total_objects": 1,
"configured_objects": 1,
"configured_variables": 2,
"truncated": false,
"results": [
{
"object": {
"name": "Bus 08",
"class_name": "ElmTerm"
},
"variables": [
"m:u",
"m:phiu"
]
}
],
"message": "Result recording selection updated; rerun contingency analysis to populate the added variables"
}Idempotency validationThe result-file metadata was read before and after repeating the identical registration:
The unchanged column count confirms that repeating the request does not create duplicate result columns. No contingency calculation was executed during the live validation. |
qian-harvard
left a comment
There was a problem hiding this comment.
Good, focused addition. It's rebased on main, green on all four interpreters, and 41 pass in the PowerFactory suite locally. The core is right: dedup of repeated variable names, the FindColumn check so a repeat doesn't add duplicate columns, Release() in a finally, no Execute, and bounded object processing with a truncated flag. The test pins the skip-if-already-recorded path (AddVariable called once for two names when one exists), which is the part most likely to regress.
There's a nice cross-check in your live evidence, too. #78's run reported the AC result file at 838 columns; this one reports 840 after registering two variables for one bus. That's consistent with the first call genuinely adding columns, not just the repeat being a no-op. As before, I have no PowerFactory here, so AddVariable / FindColumn semantics rest on your live run. Everything below is from the fakes.
Unlike the mode issue on #84, the persistence here is the tool's stated purpose, and the docstring says so. No concern there.
1. A repeat is indistinguishable from a first call — and tells the caller to rerun every time
first : columns actually added=2 success=True configured_variables=2
message='Result recording selection updated; rerun contingency analysis to populate the added variables'
repeat: columns actually added=0 success=True configured_variables=2
message='Result recording selection updated; rerun contingency analysis to populate the added variables'
responses identical: True
added includes variables that were already recorded, so configured_variables and results can't say whether anything changed. The message always instructs a rerun. A model that calls this defensively before each analysis — the natural pattern for an idempotent setup tool — will rerun ComSimoutage every time, which on a real grid is seconds to minutes. It also can't tell a user whether their project was modified.
Splitting the two would fix both: per object, added and already_recorded; totals added_variables and already_recorded_variables; and the rerun instruction only when added_variables > 0. For example, "Already recorded; no change" otherwise.
2. An exception after writes have landed is reported as a failed read
This is the only mutating tool routed through _read_only_result; every other write goes through the agent via _agent_result. So anything that escapes _impl is labelled "PowerFactory read failed", including after AddVariable has already changed the project:
columns actually added: [('Bus 1', 'm:u'), ('Bus 3', 'm:u')]
reported: {'success': False, 'message': 'PowerFactory read failed: COM object detached'}
In this case the trigger was _object_summary(obj) raising for an object whose AddVariable had already succeeded; it runs after the adds, in both the configured.append and the errors.append paths. A caller reads "read failed" and concludes nothing was written, and the record of what was written is gone. The trigger is narrow, but the misreport is exactly the kind a model can't recover from.
Containing exceptions per object in the write loop would keep the partial record: append to errors and carry on, so results still lists what landed. Alternatively, move the write into the agent like create_contingency. Either way, the message shouldn't say "read".
The ordinary partial case is handled well, for what it's worth. A rejected AddVariable gives success: false, lists the rejected pair in errors, and keeps the applied pairs in results. Since additions are idempotent, a retry converges, so no rollback is needed.
Smaller
- Interaction with
get_contingency_summary. The summary refuses whenrows × (metadata + measurements) > 20,000, andm:ucolumns count as measurements. Recordingm:ufor ~1,000 buses with ~20 contingencies crosses that line, after which the summary tool stops working on that result file. Worth a sentence in this tool's docstring, since it's the tool that creates the condition. - No inverse. There's no way for a caller to remove a recorded variable. Fine for now; worth noting as a follow-up, since this is a persistent project change.
- Silent input filtering. Non-string entries in
variablesare dropped silently; returning them in the error, or rejecting, would be clearer. - Nice touch backfilling
functions_overview.txtfor the earlier contingency tools.
Happy to merge once 1 and 2 are sorted, or I can make both changes on the branch as with #84 — say which you'd prefer.
|
Thank you for the review. If you don't mind, please go ahead and apply the suggested changes directly to the branch. I will be pushing a new feature tomorrow as well. In the meantime, if there is any other functionality you think would be worth adding, please feel free to let me know. |
A first call that added two columns and an identical repeat that added none returned byte-identical responses, both telling the caller to rerun contingency analysis. A model calling this as an idempotent setup step would rerun ComSimoutage every time -- seconds to minutes on a real grid -- and could not tell a user whether the project had changed. Each entry in results now lists the variables added by this call and those already recorded, with added_variables and already_recorded_variables totalling them, and the rerun instruction is given only when something was added. A repeat says "All requested variables were already recorded; no change". Per-object variables keeps its request order and its meaning. Separately, this is the one mutating tool routed through _read_only_result, so anything raised after AddVariable had already changed the project surfaced as "PowerFactory read failed" with the record of what was written gone. The object is now identified before anything is written to it, and failures stay scoped to that object: recorded in errors with its object_index, while results keeps what landed. An object that cannot be identified is not written to. The remaining reads before the first write -- Load, FindColumn, the object query -- are genuinely reads, so the read-only wrapper now labels accurately. The docstring states the added/already-recorded split and when to rerun, and notes that recording many m:u or c:loading columns can push a file past get_contingency_summary's 20,000-cell limit. Tests were written first and fail on the previous head, one with KeyError: 'added_variables' and one with the "read failed" message. 43 pass in the PowerFactory suite; full CI 498 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed both fixes as Change reporting. Each Failure after a write. Each object is now identified before anything is written to it, and failures stay scoped to that object. They're recorded in I also added a docstring sentence on the Tests were written first and fail on your head: one with Thanks — the dedup, the |
Summary
Adds
add_contingency_result_variablesfor configuring which PowerFactory objects and variables are recorded in AC or DC contingency result files.ElmRes.Validation
PATH; both passed after adding the installed Git Bash directory.Case 1:m:uandm:phiuforBus 08.ElmTerm.configured_objects: 1configured_variables: 2