MiravoMiravo

Generators

Pick the generator that matches how a member behaves: a source signal, a transform of another value, or a lifecycle-dependent response.

Give a member a generator when its value should change at runtime instead of staying fixed.

Technical details

Generator families

  • Source generators produce a value on their own: sine, noise, random-walk, step, ramp, mean-reverting-noise, timetable, state-machine, waveform, chirp, impulse.
  • Transformers build on another member, a previous-tick value, a parameter, or an input port: first-order-lag, integrator, transport-delay, slew-rate-limiter, second-order, hysteresis-relay, weighted-sum, expression, gate.
  • Context-aware generators derive from another signal or switch by lifecycle stage. correlated couples a member directly to another. health-dependent gives each lifecycle stage its own source generator.

Where a generator reads its input

generator:
  type: first-order-lag
  tau: 30
  input: { member: "speed_feedback" }

Write an expression

Use expression when the value is a formula over other values and weighted-sum would need nested terms. Miravo parses the expression once at load and evaluates it every tick. It never calls eval. The language supports numbers, + - * /, unary minus, parentheses, min(a, b, ...), max(a, b, ...), and clamp(x, lo, hi).

generator:
  type: expression
  expression: "max(0, $param.design_load_kw * (18 - outdoor_temperature) / (18 - $param.design_outdoor_temp_c))"
  min: 0
  max: 6000
ReferenceReads
nameA member's value from the current tick. Declare that member earlier, as with input.member.
$prev.nameA member's value from the previous tick, like previous_member.
$param.nameA numeric parameter.
$port.nameA declared input port.

Names use letters, digits, and underscores, so a-b is a subtraction. Booleans read as 0 and 1. A result that is not finite, such as a division by zero, raises an error. Guard denominators with max(..., 0.001). The min and max fields clamp the result and accept numbers or $param expressions. Load-time validation checks syntax, that members, parameters, and ports exist, and member order.

Build a chain

speed_setpoint:
  kind: variable
  data_type: Double
  access: readwrite
  unit: rpm
  generator:
    type: timetable
    repeat: true
    interpolation: step
    points:
      - { time: 0, value: 0 }
      - { time: 21600, value: 1200 }
      - { time: 64800, value: 900 }

speed_feedback:
  kind: variable
  data_type: Double
  access: read
  unit: rpm
  generator:
    type: slew-rate-limiter
    input: { member: "speed_setpoint" }
    rate_up: 220
    rate_down: 320
    min: 0
    max: 1850

Keep dependencies easy to follow. Long chains are fine; hidden coupling is not. Member order is part of the runtime contract.

Rates and durations

  • state-machine transitions take an optional rate_per_hour. Without it, the transition is unconditional. A transition with on: fault fires only while the asset has an active fault.
  • impulse takes either rate_per_hour or interval (simulated seconds), plus duration_s and a decay factor per simulated second.
  • Rates use p = 1 - exp(-rate_per_hour * dt / 3600) per step.
  • random-walk increments scale by sqrt(dt), so variance follows simulated time.
  • noise draws an independent sample on every evaluation. It is not an event rate. For time-correlated variation, use mean-reverting-noise.
  • With substeps, previous_member inputs read the previous substep.

Start at a parameter value

The initial_value of first-order-lag, second-order, integrator, and slew-rate-limiter accepts a number or a $param expression, resolved on the first tick. A lag with initial_value: "$param.supply_temp_setpoint_c" starts at its setpoint instead of climbing to it, so a plant that is already running starts in steady state.

Reference

RoleGenerator types
Sourcesine, noise, random-walk, step, ramp, mean-reverting-noise, timetable, state-machine, waveform, chirp, impulse
Transformerfirst-order-lag, integrator, transport-delay, slew-rate-limiter, second-order, hysteresis-relay, weighted-sum, expression, gate
Context-awarecorrelated, health-dependent

Parameters by generator

Key parameters, one generator per row. Transformers and gate also take an input.

GeneratorKey parametersProduces
sinecenter, amplitude, periodSmooth oscillation
noisecenter, stddevIndependent Gaussian samples each tick
random-walkmin, max, stepA bounded, drifting value
stepvalues[], intervalCycles through fixed values
rampstart_value, rate, duration, start_time, min, maxLinear change over time, then a hold
mean-reverting-noisemean, tau, sigma, initial_value, min, maxCorrelated wander around a mean
timetablepoints[{time, value}], repeat, interpolation (linear or step)A scheduled profile
state-machinestates[], initial, transitions[{from, to, rate_per_hour, on}]Discrete state labels
waveformshape (sawtooth, triangle, square, pulse), center, amplitude, period, duty_cycleA periodic non-sine signal
chirpcenter, amplitude, start_freq_hz, end_freq_hz, sweep_duration, sweep (linear or exponential), repeatA frequency sweep
impulsebaseline, amplitude, rate_per_hour or interval, duration_s, decayRandom or periodic spikes
first-order-lagtau, initial_value, gain, bias, min, maxA smoothed input with thermal or mechanical inertia
integratorgain, bias_rate, initial_value, min, max, wrap, wrap_atA running total of a rate
transport-delaydelay, initial_value, interpolation (linear or zoh)The input shifted in time
slew-rate-limiterrate_up, rate_down (defaults to rate_up), initial_value, min, maxAn input with a limited rate of change
second-ordernatural_freq_hz, damping_ratio, initial_velocity, initial_value, gain, bias, min, maxAn oscillating response with overshoot
hysteresis-relayon_threshold, off_threshold, output_on, output_off, initial_state (on or off), mode (rising or falling)On and off with a dead zone
weighted-sumterms[{weight, input}], bias, min, maxA blend of several inputs
expressionexpression, min, maxA formula over members, $prev, $param, and $port
gateenabled_member, input, disabled_valueThe input while a Boolean member is true, otherwise a fallback
correlatedsource, factor, offset, powerfactor * source^power + offset, with power a positive integer
health-dependentstages{stage: generator}A different source generator per lifecycle stage

$param coefficients

These fields accept a $param expression instead of a number: center (sine, noise, waveform, chirp), mean (mean-reverting-noise), factor and offset (correlated), initial_value, gain, and bias (first-order-lag and second-order), initial_value and gain (integrator), initial_value (slew-rate-limiter), delay (transport-delay), the thresholds of hysteresis-relay, the bias, weights, min, and max of weighted-sum, and the min and max of expression.

A $param field is an expression over numbers and $param.X only. It supports + - * /, parentheses, min, max, and clamp. Examples: factor: "$param.rated_voltage_v / $param.rated_frequency_hz" or max: "($param.rated_frequency_hz + 2) * 1.01". Miravo evaluates it once per asset, so it rejects member, $prev, and $port references at load. Use an expression generator for those.

Observation effects

Generators and faults define the process truth. Observation effects then distort what a sensor reports, the way a real instrument would. Declare them in observation_effects on a numeric read variable. Relative parameters use the member's eu_range span as the scale, or an explicit scale on the effect.

EffectParametersQualityPurpose
white_noisestrength (0 to 1, of scale)goodMeasurement noise floor
drifttau (seconds), sigma (0 to 1, of scale)goodSlow sensor drift
outlierprobability, magnitude (multiple of scale)uncertainOccasional spikes
gapprobability, duration (ticks, default 10)badSensor dropout. Value and timestamp freeze.
noise_burstprobability, duration (ticks, default 5), strengthuncertainIntermittent interference
quantizeresolution, or bits (8 to 24, needs eu_range)goodADC or display resolution
deadbandabsolute, or percent of the eu_range spangoodReport by exception: unchanged values are not republished
stuckprobability, duration_s (number or [min, max]), qualitygood or uncertainA frozen transmitter. The timestamp keeps moving.

Declare white_noise, drift, outlier, and noise_burst first, in any order. Then quantize, then deadband and stuck. The schema rejects other orders. miravo lint warns when a quantize step exceeds 1% of the eu_range span or a deadband exceeds 5%. See Asset models for a full member example.

Was this page useful?

Last updated on