MiravoMiravo

Templates

Compose assets into a runnable `.miravo.yaml` template: topology, namespace, protocols, production flow, and runtime settings.

Write a template when you need your own plant topology, namespace layout, protocol scope, or runtime settings.

Technical details

Start from a minimal template

kind: MiravoTemplate
version: "1"
name: "My Template"

namespace:
  enterprise: AcmeCorp
  site: detroit-plant

areas:
  - name: production
    lines:
      - name: line-1
        assets:
          - model: centrifugal-pump
            count: 3
            variation: 0.05

settings:
  tick_interval_ms: 1000
  time_multiplier: 1
  limits:
    max_members_per_model: 1000
    max_asset_count: 100

Save the file as my-plant.miravo.yaml. Validate it without starting a runtime by running miravo start with --dry-run.

miravo start --template ./my-plant.miravo.yaml --dry-run

Then inspect the resolved topology and referenced models with miravo templates inspect.

miravo templates inspect ./my-plant.miravo.yaml

Model the topology

A template defines areas, each with lines, each with assets. An asset assignment sets the model, the asset count, optional parameter overrides, optional starting hours, and optional protocol scope.

The namespace is either ISA-95 style (enterprise and site) or a flat prefix. Published paths continue with area, line, asset, and member.

Wire assets together

An assignment can bind the input ports its model declares to a member of another asset in the same template.

areas:
  - name: plant
    lines:
      - name: boilers
        assets:
          - { model: hot-water-boiler, id: boiler-001 }
  - name: customers
    lines:
      - name: hospital
        assets:
          - model: heat-substation
            id: sub-hospital-001
            inputs:
              network_supply_temp: { asset: boiler-001, member: supply_temperature }
  • asset must be the explicit id of another assignment, the same ids that flow stations use. Generated ids include the template id, so you cannot reference them.
  • With count above 1, every spawned asset gets the same binding.
  • The source member must be numeric. An asset can bind to its own member, which feeds back the previous substep.
  • miravo validate, miravo lint, and miravo start report an undeclared port, an unknown source asset or member, or a non-numeric member, with the path areas[i].lines[j].assets[k].inputs.<port>.
  • A bound port reads the source from the previous substep. See Asset models for the fallback rules.

Choose protocols and their scope

A protocols entry enables that adapter and sets its port. MQTT is on by default; OPC UA and Modbus start when the template lists them or when you pass --opcua or --modbus.

protocols:
  opcua:
    port: 4840
  mqtt:
    port: 1883

areas:
  - name: machining
    protocol_scope: [opcua]
    lines:
      - name: cnc-cell
        assets:
          - model: cnc-spindle
            count: 2
          - model: storage-tank
            count: 1
            protocol_scope: [mqtt]

protocol_scope limits which protocols publish an asset. The nearest scope wins, in this order: asset assignment, line, area, then the global protocols block.

Production flows and shifts

An optional flow on a line defines serial stations. Each station references an assignment id (with count: 1) and sets cycle time, scrap, and buffers. An optional top-level shifts block defines weekly schedules, breaks, and part-count changeovers. See Production lines.

The built-in Smart Factory template shows both. It has seven assets: CNC, transfer and wash conveyor, press, and inspection conveyor on the line, plus a chiller, compressor, and pump. It uses seed 20261004, two Monday to Friday shifts with breaks, and publishes every asset on every protocol.

Simulated-time steps

tick_interval_ms sets how often Miravo publishes in wall-clock time. time_multiplier sets how fast simulated time runs. Two more settings control how a tick is divided:

  • max_step_s defaults to 1 simulated second and must be greater than 0.
  • max_substeps defaults to 60 and must be an integer of at least 1.

For a tick of simulated duration dt, the engine evaluates n = min(ceil(dt / max_step_s), max_substeps) equal steps of dt / n. When the cap applies, steps can be longer than max_step_s. Only the final state is published, as one delta and one tick:complete per wall-clock tick. Nyquist validation uses dt / n, including the cap.

The cap decides what stays reproducible. With the same template and seed, runs match at the same simulated time across different --speed and --tick only while speed × tick_seconds ≤ max_substeps (60 by default), because every substep then stays 1 s. Above that the cap lengthens the steps and the trajectory changes. The same speed and tick always reproduce exactly.

Each substep evaluates every asset, so CPU cost grows with n. For large templates at high speed, raise max_step_s to trade accuracy for throughput.

Reference

Field or blockNotes
kindMust be MiravoTemplate
versionMust be "1"
name, descriptionname is required; description is optional
namespace{ enterprise, site } or { prefix }
areas[].lines[].assets[]model, id, count, variation, starting_hours, parameters, inputs, protocol_scope
areas[].lines[].flowSerial stations. See Production lines.
protocolsmqtt, opcua, modbus
shiftsWeekly schedule. See Production lines.
settingstick_interval_ms (default 1000), max_step_s, max_substeps, time_multiplier (default 1, up to 1000), seed, overrun_threshold_multiplier, limits
settings.limitsmax_members_per_model (default 1000) and max_asset_count (default 10000). Raise them for large templates.

Was this page useful?

Last updated on