dss-extensions / dss-extensions/dss_capi
Lines.R1()/X1()/C1() silently return stale defaults for matrix-defined lines
- Dominant language
- Pascal
- Stars
- 39
- Forks
- 19
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
`Lines.R1()`, `Lines.X1()`, and `Lines.C1()` (and the equivalent `LineCodes.*` properties) are symmetric-component fields. They only reflect reality when a line/LineCode was defined via `r1=`/`x1=`/`c1=`. Once a line/LineCode is switched to a matrix definition (`rmatrix=`/`xmatrix=`/`cmatrix=`), those fields are never cleared or recomputed -- they silently hold whatever they were constructed with (`R1 := 0.0580`, `X1 := 0.1206`, per `TLineObj`/`TLineCodeObj` construction in the original Pascal source), and the direct numeric getters return that stale value with no indication anything is wrong.
This is distinct from #36 (which is about a scaling inconsistency between the `RMatrix`/`XMatrix` getter and setter) -- this is about `R1`/`X1`/`C1` becoming meaningless, not mis-scaled, once matrix mode is active.
## Reproduction
```
New Circuit.test basekv=0.4 pu=1.0 phases=3
New LineCode.lc1 nphases=3 baseFreq=50 units=km
~ rmatrix=[0.868 | 0.1 0.868 | 0.1 0.1 0.868]
~ xmatrix=[0.077 | 0.01 0.077 | 0.01 0.01 0.077]
New Line.l1 bus1=a.1.2.3 bus2=b.1.2.3 phases=3 linecode=lc1 length=1 units=km
```
```python
import opendssdirect as dss
dss.Command("...redirect the above...")
dss.Lines.Name("l1")
dss.Lines.R1(), dss.Lines.X1()
# -> (0.058, 0.1206) -- the hard-coded construction default, not 0.868/0.077 -- or
# anything derivable from the declared matrix.
```
Confirmed via the Pascal source that the text-based property interface handles this correctly -- querying the `R1` property by name returns `'----'` once `SymComponentsModel` is `False` (see `LineCode.pas`: `If SymComponentsModel Then Result := Format(...) else Result := '----'`). The direct numeric getter used by the C-API/OpenDSSDirect.py doesn't perform the same check, so there is no way to tell, from the numeric API alone, that the returned value is meaningless.
## Impact
Any matrix-defined line, any conductor count -- not neutral- or phase-count-specific. We hit this while validating a pandapower OpenDSS importer against a real utility network (an explicit-neutral 4-conductor European LineCode looked like a Kron-reduction issue at first; a plain 3-conductor matrix LineCode with no neutral at all reproduced the identical stale value), which is what led us to check the Pascal source. Any tool that reads `Lines.R1()/X1()/C1()` directly (rather than going through the text/property-name interface, or manually deriving from `RMatrix()`/`XMatrix()`/`CMatrix()`) on a matrix-defined line will silently get wrong data with no error, warning, or way to detect it via the numeric API.
## Suggested fix
Given #36 was closed as not-planned (presumably to avoid changing numeric behavior that might already be relied upon / for EPRI-COM-compatibility reasons), I'd guess changing what `R1()`/`X1()`/`C1()` themselves return is a similarly hard sell. Two lower-risk options that don't touch existing behavior:
1. **Document it** on the `Lines.R1`/`X1`/`C1` (and `LineCode.R1`/`X1`/`C1`) properties: "meaningless once the line/LineCode has been defined via a matrix; check `SymComponentsModel`" (or equivalent) -- currently there's no hint of this anywhere a numeric-API user would see it.
2. **Expose `SymComponentsModel`** as a new read-only boolean getter (e.g. `Lines.SymComponentsModel()` / `LineCodes.SymComponentsModel()`). Purely additive, no behavior change, and it would let API consumers detect the unsafe case themselves and fall back to `RMatrix()`/`XMatrix()`/`CMatrix()`.
Happy to help test either, or just to have this documented if that's the preferred resolution.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the Lines.R1(), X1(), and C1() entry points and compare their direct numeric behavior with the text-property handling in LineCode.pas, especially the SymComponentsModel check. Reproduce the matrix-defined line example, then determine whether the issue is resolved by documenting the limitation or exposing a read-only model-status getter so callers can detect it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100