rules¶
expression¶
Expression parser for Rules Model conditions.
Parses condition expressions including compound boolean expressions like:
"<simtime> == 34h""<clocktime> == 12:00""drinking_water.level >= 23""drinking_water.level <= 21 && drinking_water.level >= 23""(level < 10 || level > 90) && status == true""a > b"(attribute vs attribute)"23 >= level"(literal vs attribute)
Both sides of a comparison can be an attribute name, a literal value, or a time variable.
Uses pyparsing with infix_notation for proper operator precedence.
- class BooleanExpression(operator: str, operands: list[BooleanExpression | Comparison] = <factory>)¶
Bases:
objectA compound boolean expression with AND/OR/NOT operators.
- evaluate(simtime: float | None = None, clocktime: float | None = None, attributes: dict[str, Any] | None = None) bool¶
Evaluate this boolean expression.
- Parameters:
simtime – Simulation time in seconds since start
clocktime – Clock time in seconds since midnight
attributes – Dict mapping attribute names to values
- Returns:
True if expression is satisfied
- Return type:
bool
- get_attribute_names() set[str]¶
Return set of all attribute names referenced in this expression.
- Returns:
Set of attribute names
- Return type:
set[str]
- get_time_thresholds() list[tuple[ExpressionType, float]]¶
Return time thresholds from all operands recursively.
- Returns:
List of (ExpressionType, threshold_value) tuples
- Return type:
list[tuple[ExpressionType, float]]
- operands: list[BooleanExpression | Comparison]¶
- operator: str¶
- class Comparison(left: ComparisonSide, operator: ComparisonOperator, right: ComparisonSide)¶
Bases:
objectA single comparison expression (e.g.,
level >= 23).- evaluate(simtime: float | None = None, clocktime: float | None = None, attributes: dict[str, Any] | None = None) bool¶
Evaluate this comparison.
- Parameters:
simtime – Simulation time in seconds since start
clocktime – Clock time in seconds since midnight
attributes – Dict mapping attribute names to values
- Returns:
True if comparison is satisfied
- Return type:
bool
- get_attribute_names() set[str]¶
Return set of attribute names referenced by this comparison.
- Returns:
Set of attribute names (empty if simtime/clocktime/literal only)
- Return type:
set[str]
- get_time_thresholds() list[tuple[ExpressionType, float]]¶
Return time thresholds from this comparison.
If one side is SIMTIME/CLOCKTIME and the other is LITERAL, returns the literal value tagged with the time type.
- Returns:
List of (ExpressionType, threshold_value) tuples
- Return type:
list[tuple[ExpressionType, float]]
- left: ComparisonSide¶
- operator: ComparisonOperator¶
- right: ComparisonSide¶
- class ComparisonOperator(*values)¶
Bases:
EnumComparison operators with their evaluation functions.
- EQ = '=='¶
- GE = '>='¶
- GT = '>'¶
- LE = '<='¶
- LT = '<'¶
- NE = '!='¶
- evaluate(left: Any, right: Any) bool¶
Evaluate the comparison between left and right values.
- Parameters:
left – Left-hand side value
right – Right-hand side value
- Returns:
Result of the comparison
- Return type:
bool
- class ComparisonSide(expr_type: ExpressionType, attribute_name: str | None = None, value: Any = None)¶
Bases:
objectOne side of a comparison expression.
- attribute_name: str | None = None¶
- expr_type: ExpressionType¶
- value: Any = None¶
- class ExpressionType(*values)¶
Bases:
EnumType of one side of a condition expression.
- ATTRIBUTE = 'attribute'¶
- CLOCKTIME = 'clocktime'¶
- LITERAL = 'literal'¶
- SIMTIME = 'simtime'¶
- parse_clock_time(expr: str) float¶
Parse a clock time expression to seconds since midnight.
Supports formats like:
"12:30"→ 45000 seconds (12 hours 30 minutes)"08:15"→ 29700 seconds"23:59:59"→ 86399 seconds
- Parameters:
expr – Clock time expression string (HH:MM or HH:MM:SS)
- Returns:
Seconds since midnight
- Return type:
float
- Raises:
ValueError – If the expression cannot be parsed
- parse_condition(expr_string: str) Comparison | BooleanExpression¶
Parse a condition expression string.
Supports simple comparisons and compound boolean expressions. Both sides of a comparison can be an attribute, literal, or time variable:
"<simtime> == 34h""level >= 23""a > b"(attribute vs attribute)"23 >= level"(literal vs attribute)"level <= 21 && level >= 23""(level < 10 || level > 90) && status == true""NOT status == true"
- Parameters:
expr_string – Condition expression string
- Returns:
Parsed condition (Comparison or BooleanExpression)
- Return type:
ParsedCondition
- Raises:
ValueError – If the expression cannot be parsed
- parse_duration(expr: str) float¶
Parse a duration expression to seconds.
Supports formats like:
"34h"→ 122400 seconds"5m"→ 300 seconds"1d5h30s"→ 104430 seconds"12h30m"→ 45000 seconds
- Parameters:
expr – Duration expression string (e.g., “1d5h30m”)
- Returns:
Duration in seconds
- Return type:
float
- Raises:
ValueError – If the expression cannot be parsed
model¶
Rules Model for conditional attribute updates.
This model updates entity attributes based on conditions defined in rules datasets or model configuration.
- class DatasetReferenceIndex(ids: 'dict[str, dict[int, int]]', references: 'dict[str, dict[str, int]]')¶
Bases:
object- get_entity_idx_by_id(entity_id: int) tuple[str, int] | tuple[None, None]¶
Retrieve location of an entity id :param entity_id: an entity id
- Returns:
A tuple (entity group name, entity_idx)
- get_entity_idx_by_reference(ref: str) tuple[str, int] | tuple[None, None]¶
Retrieve location of an entity by reference :param ref: an entity reference
- Returns:
A tuple (entity group name, entity_idx)
- ids: dict[str, dict[int, int]]¶
- references: dict[str, dict[str, int]]¶
- class Model(config: dict)¶
Bases:
TrackedModelModel that applies conditional rules to update entity attributes.
Rules can be defined in the model config or in a separate rules dataset. Both sources are merged if both are provided.
Each rule specifies:
A condition (time-based or attribute-based)
A target entity (by id or reference)
An output attribute and value to set when the condition is true
Optionally, an else_value when the condition is false
- setup(state: TrackedState, schema: AttributeSchema, settings: Settings, init_data_handler: InitDataHandler, logger: Logger, **__: Any) None¶
Set up the model with state and schema.
- Parameters:
state – TrackedState instance for managing entity data
schema – AttributeSchema for attribute registration
settings – Global settings
init_data_handler – Handler for initial data loading
logger – Logger instance
- timeline_info: t.Optional[t.Any]¶
- update(state: TrackedState, moment: Moment) Moment | None¶
Update entity attributes based on rules.
- Parameters:
state – TrackedState instance
moment – Current simulation moment
- Returns:
Next moment when an update is needed, or None
- Return type:
Optional[Moment]
- class Rule(condition: Comparison | BooleanExpression, output: str, value: bool | int | float | str, else_value: bool | int | float | str | None, to_entity_idx: int, output_array: UniformAttribute, from_entity_idx: int | None, source_attributes: dict[str, UniformAttribute])¶
Bases:
objectA single rule that updates a target attribute based on a condition.
- condition: Comparison | BooleanExpression¶
- else_value: bool | int | float | str | None¶
- from_entity_idx: int | None¶
- classmethod from_spec(spec: RuleSpec, reference_indices: dict[str, DatasetReferenceIndex], state: TrackedState, schema: AttributeSchema)¶
- output: str¶
- output_array: UniformAttribute¶
- source_attributes: dict[str, UniformAttribute]¶
- to_entity_idx: int¶
- value: bool | int | float | str¶
- class RuleSpec(condition: 'str', output: 'str', value: 'bool | int | float | str | None', to_dataset: 't.Optional[str]' = None, from_dataset: 't.Optional[str]' = None, from_id: 't.Optional[int]' = None, from_reference: 't.Optional[str]' = None, to_id: 't.Optional[int]' = None, to_reference: 't.Optional[str]' = None, else_value: 't.Any' = None)¶
Bases:
object- condition: str¶
- else_value: Any = None¶
- from_dataset: str | None = None¶
- from_id: int | None = None¶
- from_reference: str | None = None¶
- output: str¶
- to_dataset: str | None = None¶
- to_id: int | None = None¶
- to_reference: str | None = None¶
- value: bool | int | float | str | None¶
- exception RuleValidationError¶
Bases:
ValueErrorRaised when a rule specification is invalid.