Skip to content

Plans, degradation and maintenance

A plan turns a plant into a history: it names the plant's operating points, moves between them, lets equipment degrade, and restores it with maintenance. Every change is an ordinary event, recorded in run.meta["events"], and the plan's intervals are recorded in run.meta["timeline"].

This is examples/plant_history.yaml, two months of a temperature loop:

# Two months of plant history generated from a historical plan: grade changes, fouling that
# grows faster at higher temperatures, transmitter drift, valve wear, the maintenance that
# resets them, and one unplanned fault. Every change is recorded in run.meta["events"], and
# the plan's regimes, transitions and maintenance intervals in run.meta["timeline"].
seed: 11
duration: 60d
dt: 20s
library: process@1

units:
  - {id: TIC-101, template: temperature_loop}

exogenous:
  - target: TIC-101.feed_temp
    unit: degC
    source: {kind: ou, mean: 25, std: 2, tau: 8h}

regimes:
  grade_A: {TIC-101.sp: 80, TIC-101.plant.K: 0.8}
  grade_B: {TIC-101.sp: 88, TIC-101.plant.K: 0.9}
  grade_C: {TIC-101.sp: 75, TIC-101.plant.K: 0.75}

degradation:
  - {target: TIC-101, kind: fouling, rate: 0.01}        # 1 % of the heating gain per day at 80 degC
  - {target: TIC-101, kind: sensor_drift, rate: 0.03}   # 0.06 degC per day
  - {target: TIC-101, kind: valve_wear, rate: 0.05}     # the static friction band grows 0.05 % per day

plan:
  start: grade_A
  production:
    - {at: 10d, to: grade_B, over: 6h}
    - {at: 22d, to: grade_C, over: 4h}
    - {at: 35d, to: grade_A, over: 6h}
    - {at: 48d, to: grade_B, over: 6h}
  maintenance:
    - {at: 20d, task: clean, target: TIC-101}
    - {at: 30d, task: calibrate, target: TIC-101}
    - {at: 40d, task: stop, target: TIC-101, duration: 2d}
    - {at: 41d, task: clean, target: TIC-101}           # during the stop
    - {at: 41d, task: replace_valve, target: TIC-101}
    - {at: 55d, task: calibrate, target: TIC-101}

interventions:
  - {at: 45d, target: TIC-101, fault: sensor_noise, magnitude: 3}   # unplanned

output:
  every: 1min

Regimes

regimes gives names to sets of values: setpoints, parameters, modes, ports and custom schedules. A product grade is a typical regime.

regimes:
  grade_A: {TIC-101.sp: 80, TIC-101.plant.K: 0.8}
  grade_B: {TIC-101.sp: 88, TIC-101.plant.K: 0.9}

Production

plan.start is the regime at the start of the run; with init: steady the plant settles in it, so the run starts without a transient. Each entry of plan.production moves to another regime at at, ramping every numeric value of the new regime over over; a mode switches at once. Values that the new regime does not name keep their current value.

Transitions are recorded with the label transition:<from>-><to>.

Degradation

degradation lets a unit wear with operation. Each entry names a unit, a kind and its parameters:

degradation:
  - {target: TIC-101, kind: fouling, rate: 0.01}        # 1 % of the heating gain per day at 80 degC
  - {target: TIC-101, kind: sensor_drift, rate: 0.03}   # % of span per day
  - {target: TIC-101, kind: valve_wear, rate: 0.05}     # growth of the friction band, % of travel per day
Kind What degrades Reset by
fouling The heating gain falls, faster at higher temperatures. clean
sensor_drift The transmitter reading drifts at a steady rate. calibrate, replace_sensor
valve_wear The valve's stick-slip friction grows. replace_valve
catalyst_decay A reactor's catalyst loses activity, faster at higher temperatures. replace_catalyst

A degradation is an ageing state built from core operators. It is held at its initial value while the plant settles, so every run starts with new equipment. The process library lists each kind's parameters.

Maintenance

Each entry of plan.maintenance applies a task to one unit or several:

plan:
  maintenance:
    - {at: 20d, task: clean, target: TIC-101}
    - {at: 30d, task: calibrate, target: [TIC-101, TIC-102]}
    - {at: 40d, task: stop, target: TIC-101, duration: 2d}
Task What it does
clean Fouling returns to zero.
calibrate The transmitter's offset and drift return to zero.
replace_sensor A new transmitter: calibrated, with nominal noise and a fresh state.
replace_valve Friction and wear return to nominal.
replace_catalyst The catalyst is fresh again.
stop The loop goes to manual with the valve closed for duration, then returns to automatic.
remove_sensor, install_sensor The reading becomes NaN until a sensor is installed again.

A task that does not apply is an error, for example cleaning a unit without fouling. Tasks are recorded with the label maintenance:<task>.

The timeline

run.meta["timeline"] lists the plan's intervals: each regime, each transition (zero length for a step), and each maintenance task, with its start and end in seconds. It only covers the simulated duration. It is the ground truth for regime-aware analyses, and settle_times reads it to measure how long each loop takes to settle after each transition.

Plans can also generate themselves from random processes: see Self-running plans.