0.60

ReferenceRangesArc ranges

Create ranges in Arc

Mark each test run, stage, abort, or out-of-limits period from an Arc automation.

An Arc automation can create a range when a test starts and end it when the test ends. Each run gets its own range, and no one has to mark it in the Console. This page shows the common patterns. For every parameter, see the ranges module.

Four rules apply to every pattern:

  • Import the module with import ranges.
  • Store the key that ranges.create outputs in a variable declared with $=, and give that variable to ranges.end. A $= variable keeps its value from one stage to the next.
  • Set a color. Line plots show only ranges that have a color.
  • ranges.create with no input runs once each time its stage starts. The range starts at that time.

Mark each test run

import ranges

sequence test {
    run_key str $= ""
    stage idle {
        start_cmd == 1 => run
    }
    stage run {
        ranges.create{name="Hotfire", color="#3bc454"} -> run_key
        1 -> press_vlv_cmd
        stop_cmd == 1 => done
    }
    stage done {
        ranges.end{key=run_key}
        0 -> press_vlv_cmd
        start_cmd == 1 => run
    }
}

true => test

true => test starts the sequence when the automation starts. Each time run starts, Arc creates a new range named Hotfire. done sets the end of that range to the current time. All the runs have the same name, so find a run by its time in the range explorer.

Mark each stage with a child range

Give the key of the run range to parent. The child range shows in the child ranges section of the range overview of the run.

import ranges
import time

sequence test {
    run_key str $= ""
    hold_key str $= ""
    stage idle {
        start_cmd == 1 => pressurize
    }
    stage pressurize {
        ranges.create{name="Press test", color="#3bc454"} -> run_key
        1 -> press_vlv_cmd
        tank_pt > 300.0 => hold
    }
    stage hold {
        ranges.create{name="Hold", parent=run_key, color="#8b5cf6"} -> hold_key
        0 -> press_vlv_cmd
        time.wait{duration=30s} => vent
    }
    stage vent {
        ranges.end{key=hold_key}
        1 -> vent_vlv_cmd
        tank_pt < 5.0 => done
    }
    stage done {
        ranges.end{key=run_key}
        0 -> vent_vlv_cmd
        start_cmd == 1 => pressurize
    }
}

true => test

Each child range needs its own variable. Here, hold_key holds the key of the Hold range, and vent ends it.

Mark an abort

Create a red child range when the test aborts. A reader of the data sees where the test stopped and why.

import ranges

sequence test {
    run_key str $= ""
    abort_key str $= ""
    stage idle {
        start_cmd == 1 => pressurize
    }
    stage pressurize {
        ranges.create{name="Press test", color="#3bc454"} -> run_key
        1 -> press_vlv_cmd
        tank_pt > 450.0 => abort
        abort_cmd == 1 => abort
        tank_pt > 300.0 => vent
    }
    stage vent {
        0 -> press_vlv_cmd
        1 -> vent_vlv_cmd
        tank_pt < 5.0 => done
    }
    stage abort {
        ranges.create{name="Abort", parent=run_key, color="#e5484d"} -> abort_key
        0 -> press_vlv_cmd
        1 -> vent_vlv_cmd
        tank_pt < 5.0 => safe
    }
    stage done {
        ranges.end{key=run_key}
        0 -> vent_vlv_cmd
        start_cmd == 1 => pressurize
    }
    stage safe {
        ranges.end{key=abort_key}
        ranges.end{key=run_key}
        0 -> vent_vlv_cmd
        start_cmd == 1 => pressurize
    }
}

true => test

The abort path ends in its own stage, safe. Do not end abort_key in done: after a run with no abort, abort_key holds the key of an earlier abort, and ranges.end would move the end of that range.

Mark when a value is out of limits

Create a range each time a value goes above a limit, and end it when the value comes back. Use two limits, so that a value near one limit does not create many short ranges.

import ranges

sequence watch {
    range_key str $= ""
    stage normal {
        tank_pt > 600.0 => high
    }
    stage high {
        ranges.create{name="Overpressure", color="#f59e0b"} -> range_key
        tank_pt < 580.0 => recovered
    }
    stage recovered {
        ranges.end{key=range_key}
        tank_pt > 600.0 => high
    }
}

true => watch

normal runs only before the first range. recovered ends each range after it, so ranges.end never runs with an empty key.

What Arc cannot do

Arc can create a range and end it. Use the Console or a client for everything else:

To See
Find a range Find ranges
Read the data of a range Read and write range data
Add metadata or labels Metadata and labels
Set a channel alias Channel aliases
Rename a range or change its time Edit and delete ranges
Snapshot a task or a schematic Snapshots

Each ranges.create makes a new range, also when a range with the same name exists. The graph editor has no range blocks, so write range calls in the text editor.

Troubleshooting

A range stays in progress

The automation stopped, or you deployed it again, before ranges.end ran. Stopping an automation does not end its ranges, and the automation loses the keys that it stored. Complete the range in the Console. See change the times or the stage.

The automation shows a ranges warning

When a ranges call fails, Synnax shows a warning, the call outputs an empty key, and the automation keeps running.

Warning Cause
ranges.end: invalid range key "" ranges.end ran before ranges.create stored a key in the variable.
ranges.create: invalid parent key "" The child range was created before the parent range stored its key.

Put each ranges.end, and each child ranges.create, in a stage that runs only after the ranges.create that it needs.

The range does not show on a line plot

The range has no color. Set color in ranges.create.

The range is not in the ranges toolbar

The ranges toolbar shows only your favorite ranges. Find the range in the range explorer, and favorite it.