YAML Configuration
PyRogue supports configuration and state import/export through YAML APIs on
Root and through subtree export on Node.
These APIs are the standard way to capture a known-good configuration, restore it later, or inspect the current tree as structured YAML rather than as interactive Variables.
Typical YAML Workflows
Configuration baselines for known-good startup values
Captured runtime state for debug and issue reproduction
Status snapshots for validation and operator handoff
Main Entry Points
The main YAML entry points are:
Node.getYaml(...)to export one subtree as YAML text.Root.saveYaml(...)to write YAML to a file, with optional auto-naming.Root.loadYaml(...)to read YAML from one or more files or directories.Root.setYaml(...)to apply YAML text directly.
These APIs also back the built-in hidden Root commands:
SaveConfig/LoadConfigSaveStateSetYamlConfig/GetYamlConfig/GetYamlState
The command wrappers mainly pre-select useful defaults for modes and group filters.
Configuration Vs State Filters
Typical defaults:
Config operations use modes
['RW', 'WO']and excludeNoConfigState operations use modes
['RW', 'RO', 'WO']and excludeNoState
That means:
Read-only Variables are normally ignored for config load
Commands are ignored by YAML set/load (
BaseCommand._setDictis a no-op)
This is why configuration YAML usually reads like “things you can set”, while state YAML reads like “everything worth observing”.
Saving YAML
Node.getYaml(...) and Root.saveYaml(...) both serialize current tree
values using the same underlying tree-dictionary path.
Important export options:
readFirst=Trueperforms a Root-wide read before export.modescontrols which Variable access modes are included.incGroupsandexcGroupsapply the same group-filtering model used elsewhere in the tree.recurseongetYaml(...)controls whether child Devices are included.
saveYaml(...) can either write to a named file or auto-generate a
timestamped filename. If the target name ends in .zip, it writes the YAML
payload into a compressed zip member.
Loading And Applying YAML
Root.loadYaml(...) accepts more than a single file path. In the current
implementation, the input can be:
A single
.ymlor.yamlfile.A directory, in which case all
.ymland.yamlfiles in that directory are loaded in sorted order.A zip-file subdirectory path.
A Python list of those entries.
A comma-separated string of entries.
Root.setYaml(...) applies YAML text directly without going through the
filesystem.
For loadYaml(..., writeEach=False) and setYaml(..., writeEach=False),
the application workflow is:
Parse YAML input to ordered dictionaries.
Traverse the tree and assign Variable display values with
setDisp(..., write=False).After the full YAML payload is staged in shadow state, run the normal Root configuration-commit path through
Root._write().
Implications:
If a Variable is assigned more than once while loading, the last assignment wins in shadow memory before commit
Hardware is not touched until the bulk commit step
If writeEach=True, each setDisp write is issued immediately while YAML
is being traversed (no final consolidated Root._write() pass).
The load path is wrapped in both Root.pollBlock() and Root.updateGroup()
so polling does not race with the configuration operation and listeners see a
coalesced update batch.
The staged values are then committed using the normal tree transaction path. For the bulk write, verify, read, and check model behind that commit step, see Device Block Operations.
Practical Guidance
Separate baseline configuration from transient runtime state.
Track YAML files in source control when they represent release artifacts.
Document version compatibility when tree names or meaning change.
Prefer
writeEach=Falsefor coordinated configuration loads unless you specifically need immediate per-entry writes.
Array Matching And Slicing In YAML Keys
YAML load supports array-style Node matching:
AmcCard[0]:AmcCard[1:3]:AmcCard[:]:AmcCard[*]:
Examples:
Root:
AmcCard[:]:
DacEnable[0]: True
AmcCard[1:3]:
DacEnable: True
The matching rules follow the same array-aware nodeMatch() behavior used by
the tree:
[0]selects one element.[:]and[*]select all elements.[1:3]uses Python-style slice semantics, so it selects elements 1 and 2.
Array Variables can also be targeted at the Variable level, for example with
DacEnable[0].
Related settings on Root:
ForceWrite: force writes of non-stale Blocks in bulk config pathsInitAfterConfig: callinitialize()after config apply
What To Explore Next
Root lifecycle and built-in commands: Root
Group filtering semantics: Groups
Device block traversal and commit behavior: Device Block Operations