Driver.config#
The configuration system in AFL-automation is designed to provide persistent settings management that automatically saves changes to disk. This document explains how the Driver.config
system works and how to use it effectively.
Core Components#
The configuration system is built on two main components:
Driver.config
- The configuration interface accessible through any Driver instancePersistentConfig
- The underlying dictionary-like class that handles persistence
How It Works#
When a Driver instance is created, a PersistentConfig
object is initialized at self.config
. This creates or loads a configuration file in the user’s home directory at ~/.afl/<driver_name>.config.json
. The configuration is a key-value store that behaves like a dictionary.
# Example of creating a Driver with configuration
from AFL.automation.APIServer.Driver import Driver
# Initialize with defaults and overrides
driver = Driver(
name="MyDriver",
defaults={"setting1": "default_value"},
overrides={"priority_setting": "override_value"}
)
Configuration Lifecycle#
The PersistentConfig
class manages the full lifecycle of configuration values:
Initialization: Loads existing config from disk if available
Default Values: Applies default values for missing keys
Overrides: Applies override values that take precedence over existing values
History Tracking: Records a history of configuration changes with timestamps
Persistence: Automatically writes changes to disk when values are modified
Configuration Methods#
The Driver class provides several methods to interact with the configuration remotely:
# Set configuration values
driver.set_config(key1="value1", key2="value2")
# Get a specific configuration value
value = driver.get_config("key1")
# Get a configuration value and print it to console
value = driver.get_config("key1", print_console=True)
# Get all configuration values
config_dict = driver.get_configs()
# Get all configurations and print them to console
config_dict = driver.get_configs(print_console=True)
The underlying PersistentConfig
object can also be used directly for more advanced operations:
# Dictionary-like access
driver.config["key"] = "value"
value = driver.config["key"]
# Update multiple values
driver.config.update({"key1": "value1", "key2": "value2"})
# Convert to JSON
json_data = driver.config.toJSON()
# Revert to a previous configuration state
driver.config.revert(nth=-2) # Revert to second-most recent config
Browser-Based Configuration Editor#
AFL-automation provides a browser-based GUI configuration editor that makes it easy to modify configuration values with simple data types. This editor is automatically available through the web interface and provides:
User-Friendly Interface: Edit configuration values without writing code
Type-Aware Inputs: Appropriate input controls based on data type (text fields, toggles, dropdowns, etc.)
Real-Time Updates: Changes are immediately applied and persisted
The configuration editor supports these simple data types: - Strings - Numbers (integers and floats) - Booleans - Lists of simple types - Simple dictionaries
Complex data structures (deeply nested objects, custom classes) are not editable through the GUI editor and require programmatic access.
The configuration editor can be accessed directly through the web interface at /config
when running an AFL server.
Configuration History#
One powerful feature of the PersistentConfig
class is its ability to track the history of configuration changes. Each time a configuration is modified, the entire configuration state is saved with a timestamp. This allows for:
Auditing: See when configuration changes were made
Reverting: Revert to previous configuration states
Tracking: Track the history of specific configuration values
# Get historical values for a specific key
dates, values = driver.config.get_historical_values("key1")
# Get historical values with datetime objects instead of string timestamps
dates, values = driver.config.get_historical_values("key1", convert_to_datetime=True)
Best Practices#
When working with the Driver.config system:
Use Defaults: Provide sensible defaults when creating Driver instances
Documentation: Document the configuration keys your Driver expects
Validation: Validate configuration values before using them
Error Handling: Handle missing configuration gracefully
Keep It Simple: Avoid deeply nested configuration structures
Examples#
Here’s a complete example of using the Driver.config system:
from AFL.automation.APIServer.Driver import Driver
# Create a Driver with default configuration
defaults = {
"serial_port": "/dev/ttyUSB0",
"baud_rate": 9600,
"timeout": 1.0
}
driver = Driver("DeviceController", defaults=defaults)
# Override a configuration value
driver.set_config(timeout=2.0)
# Use configuration in methods
def connect_to_device(self):
port = self.get_config("serial_port")
baud = self.get_config("baud_rate")
timeout = self.get_config("timeout")
# Connect using these parameters...
Conclusion#
The Driver.config system provides a robust way to manage persistent configuration in AFL-automation. By leveraging the PersistentConfig
class, it offers a simple dictionary-like interface with powerful features like history tracking and automatic persistence to disk.