Problem Background
Currently, Dirigo relies on a manually written system_config.toml file to describe the available hardware and the minimum parameters required to initialize it. By design, this file is intended to include only information that cannot be discovered automatically from the device API (e.g. serial numbers, axis labels, scanner angle limits, COM ports). Switchable or frequently adjusted parameters (e.g. default stage velocity) are discouraged and should instead live in a separate hardware profile file (typically default.toml).
While this approach is flexible, it presents a significant usability barrier. Users must know in advance which arguments each device expects, which values are required vs optional, and what the valid ranges or units are. Because the file is written manually, it is easy to make errors that are only caught at runtime. This friction is likely to discourage new users and makes configuration harder to validate, test, and evolve.
A more robust system would allow Dirigo to formally describe the expected configuration for each device and expose that information through a discoverable schema. This would enable both better validation and the development of an interactive configuration wizard (TUI or GUI) that can guide users through system setup.
Proposed solution
System Config
Rewrite the current dirigo/components/io:SystemConfig as dirigo/config/system:SystemConfig and implement it as a Pydantic BaseModel.
At a minimum, this model should include:
- A schema_version field to support future evolution and migration.
- Basic metadata such as system name, creation time, and last-modified time.
- A structured collection of device instances that make up the system configuration.
Rather than a raw list of devices, the system config should explicitly represent device instances, each of which specifies:
- The hardware interface it satisfies (e.g. stage, stages, fast_raster_scanner).
- The plugin to use (identified via entry points, e.g. group + name).
- A device-specific configuration payload that will be validated against that plugin’s schema.
This keeps SystemConfig responsible for describing what hardware exists in the system and how it is instantiated, without embedding runtime state or switchable acquisition parameters.
Device configuration schemas
Each hardware plugin should define a formal configuration schema using Pydantic. This schema represents the set of user-provided inputs required to initialize that device.
Concretely:
- Each device implementation exposes a Pydantic BaseModel (e.g. Device.Config) that defines:
- Required vs optional fields.
- Valid types, ranges, enums, and units.
- Default values where appropriate.
- The schema must be usable without hardware present (i.e. no device I/O during validation).
- The schema should support a form of schema export so it can be introspected by tooling.
Device classes should then provide a clear boundary between configuration and runtime behavior, for example via a from_config(config) classmethod or equivalent factory. Configuration validation happens first. Hardware initialization happens only after validation succeeds.
Validation and error reporting
Because the system and device configs are Pydantic models, validation should occur at load time with clear, structured error messages. Errors should:
- Point to the exact location in the config file (e.g. devices.stage_x.config.position_limits.min).
- Clearly describe what is invalid and why (missing field, wrong unit, out-of-range value, etc.).
This makes configuration issues easy to diagnose without requiring trial-and-error execution.
Units and representation
Configuration values that require units (e.g. lengths, velocities, times) should continue to be represented in a human-readable form (e.g. "5 mm", "1 ms"). Device config schemas are responsible for validating and normalizing these values into Dirigo’s internal units system.
The unit representation and parsing rules should be consistent across all device configs.
Interactive configuration wizard
With formal schemas in place, an interactive configuration wizard becomes feasible. The wizard (initially CLI-based, later GUI-based) would:
- Discover available device plugins via entry points.
- Introspect each plugin’s configuration schema.
- Prompt the user for required fields, validate inputs immediately, and provide helpful feedback.
- Generate a valid
system_config.toml file.
The wizard is not required to be implemented immediately, but the configuration architecture should explicitly support this use case.
Versioning and migration
SystemConfig should include a schema version field. When schema changes are introduced, Dirigo should provide a clear migration path (manual or automated) to update older configs. This allows the configuration format to evolve without breaking existing systems.
Plan
I'll start a new branch to experiment with the new SystemConfig. Later, I'll start implementing device schemas for all the plugins.
Problem Background
Currently, Dirigo relies on a manually written
system_config.tomlfile to describe the available hardware and the minimum parameters required to initialize it. By design, this file is intended to include only information that cannot be discovered automatically from the device API (e.g. serial numbers, axis labels, scanner angle limits, COM ports). Switchable or frequently adjusted parameters (e.g. default stage velocity) are discouraged and should instead live in a separate hardware profile file (typicallydefault.toml).While this approach is flexible, it presents a significant usability barrier. Users must know in advance which arguments each device expects, which values are required vs optional, and what the valid ranges or units are. Because the file is written manually, it is easy to make errors that are only caught at runtime. This friction is likely to discourage new users and makes configuration harder to validate, test, and evolve.
A more robust system would allow Dirigo to formally describe the expected configuration for each device and expose that information through a discoverable schema. This would enable both better validation and the development of an interactive configuration wizard (TUI or GUI) that can guide users through system setup.
Proposed solution
System Config
Rewrite the current
dirigo/components/io:SystemConfigasdirigo/config/system:SystemConfigand implement it as a PydanticBaseModel.At a minimum, this model should include:
Rather than a raw list of devices, the system config should explicitly represent device instances, each of which specifies:
This keeps SystemConfig responsible for describing what hardware exists in the system and how it is instantiated, without embedding runtime state or switchable acquisition parameters.
Device configuration schemas
Each hardware plugin should define a formal configuration schema using Pydantic. This schema represents the set of user-provided inputs required to initialize that device.
Concretely:
Device classes should then provide a clear boundary between configuration and runtime behavior, for example via a from_config(config) classmethod or equivalent factory. Configuration validation happens first. Hardware initialization happens only after validation succeeds.
Validation and error reporting
Because the system and device configs are Pydantic models, validation should occur at load time with clear, structured error messages. Errors should:
This makes configuration issues easy to diagnose without requiring trial-and-error execution.
Units and representation
Configuration values that require units (e.g. lengths, velocities, times) should continue to be represented in a human-readable form (e.g. "5 mm", "1 ms"). Device config schemas are responsible for validating and normalizing these values into Dirigo’s internal units system.
The unit representation and parsing rules should be consistent across all device configs.
Interactive configuration wizard
With formal schemas in place, an interactive configuration wizard becomes feasible. The wizard (initially CLI-based, later GUI-based) would:
system_config.tomlfile.The wizard is not required to be implemented immediately, but the configuration architecture should explicitly support this use case.
Versioning and migration
SystemConfigshould include a schema version field. When schema changes are introduced, Dirigo should provide a clear migration path (manual or automated) to update older configs. This allows the configuration format to evolve without breaking existing systems.Plan
I'll start a new branch to experiment with the new SystemConfig. Later, I'll start implementing device schemas for all the plugins.