Table of Contents

Step Color Trees over HTTP

A color tree sorts the played steps into leaves by conditions on their step properties — the first node whose condition holds takes the step — and gives each leaf a color. This page is what a script or an agent needs to do that over the web service's HTTP API: the routes, the shape of a tree, the answers, and the color index every connected user shares. How a tree sorts and colors is in Color Trees, the editor a person uses is Step Colors, and the whole path from a question to a colored run is Coloring Steps by Condition over the HTTP API. Signing in, reading a reply and replaying a mission are Driving the Web Service over HTTP. The project's trees are edited under /api/execution/step-color-trees; an edit changes the open project, and POST /api/Project/save writes it.

Three Rules on a Shared Instance

Three rules keep a caller from disturbing anyone else on the instance:

  1. Check and preview a tree before putting it. check and preview change neither the project nor the color index nor the colors other users see.
  2. Set the color index only when the tree must show on screen, and write the old key back afterwards, while the color index is still the tree's key. The color index is a project setting every connected user sees (The Color Index).
  3. Add a tree with If-None-Match: *. A key another caller has taken meanwhile then answers 412 and keeps its tree, instead of being overwritten. Choose a key no entry of trees, registeredAtRun or keyOptions has, and that is not the color index itself: a deleted tree leaves its key as the color index, so a tree added under it recolors every screen at once.

The Routes

Route under /api/execution/step-color-trees Body Effect and answer
GET, ?lang= for the language of the key names — { success, generation, physicsShown, inspectingKey, trees, registeredAtRun, keyOptions }
GET {key} — one tree: { success, item, generation }, item as an entry of trees
PUT {key} a tree adds the tree at the end of the list, changes it, or renames it when the body's key is another: { success, item, appearanceOnly, renamedFrom, messages, generation }
DELETE {key} — removes every tree under the key, or the one occurrence names: { success, removedInspectingKey, messages, generation }
POST check a tree the engine's findings, { success, problems, messages, referencedKeys }; changes nothing
POST preview { tree, key, stepIndex, range } the played steps sorted under a tree, and one step explained: { success, selectedStep, histogram, microsPerStep, elapsedMs, storeReads, inspectingKey }; changes nothing

{key} is one URL-encoded path segment. ?occurrence=n on GET {key}, PUT and DELETE names one of the trees a project file repeats a key under, counted from 0 as GET counts them; on a PUT it also makes the request a change only, so a tree deleted meanwhile answers 404 instead of being added again. generation is the step-property registry's count, which GET /api/Execution/status reports as stepPropertiesGeneration: a list read at the generation the status names is current, but for inspectingKey and inspected, which follow the color index, and physicsShown and the physics keys of keyOptions, which follow Show Physics Options and the physics licence: a change to any of the three moves no generation, so read the list again before acting on those fields.

The List

trees holds the project's trees in their order, each { key, occurrence, name, origin, state, inspected, tree, leaves, referencedKeys, problems }. state is registered, refused (a problem keeps the tree from compiling; problems says which), unreadable (written by a version this one does not understand, and kept as written), keyTaken (a built-in step property's key, or one under MC.) or keyRepeated (a project step variable's key, or an earlier tree's). inspected marks the first tree under the color index's key; tree is the tree in the shape PUT takes, numbered; leaves are { id, lane, name, hue, hueAuto, color, valueKey }, color the #RRGGBB the charts and the 3D view paint. registeredAtRun lists the trees a mission script registered for the session, { key, name, leaves }, which these routes do not edit. keyOptions are the step properties a term can name, { key, name, unit, unitLabel, kind, isPhysics, source }: kind is quantity, bool (read as 1 or 0) or text (which only hasValue and noValue can ask of), and source is builtIn, projectVariable, session or training. While physicsShown is false — Show Physics Options off, or no physics licence — the physics keys are left out; a tree that names one is accepted with a warning and reads it all the same. inspectingKey is the color index as the project holds it.

A Tree

A tree is { key, name, nextId, nodes }, and a node { kind, id, name, when, hue, valueKey, children }. kind is leaf or group; when is { join, terms } with join all, the default, or any, or null for a node that takes every step reaching it; a term is { key, op, threshold }, op one of gt, ge, lt, le, eq, ne, hasValue and noValue, the last two without a threshold; hue is a leaf's hue in degrees, null for an automatic one; valueKey is the step property the charts show for a leaf's steps; children are a group's nodes, tried in order. A tree being added leaves out id and nextId, and the server numbers its nodes in the order written, from nextId, which only grows: a deleted node's number is never given again, and a nextId outside 1 to 1,048,575 is dropped without a word, as if left out. An edit sends the ids GET gave. An example, its threshold 1 — 100 % — only illustrating the shape:

{
  "key": "RatioCheck",
  "name": "Ratio check",
  "nodes": [
    { "kind": "leaf", "name": "Rapid",
      "when": { "join": "all", "terms": [ { "key": "IsRapid", "op": "eq", "threshold": 1 } ] } },
    { "kind": "group", "name": "Ratios known",
      "when": { "join": "all", "terms": [ { "key": "YieldingStressRatio", "op": "hasValue" } ] },
      "children": [
        { "kind": "leaf", "name": "Above 100 %", "hue": 0,
          "when": { "join": "any", "terms": [
            { "key": "YieldingStressRatio", "op": "gt", "threshold": 1 },
            { "key": "MaxSpindleTorqueRatio", "op": "gt", "threshold": 1 },
            { "key": "MaxSpindlePowerRatio", "op": "gt", "threshold": 1 } ] } },
        { "kind": "leaf", "name": "Within", "valueKey": "MaxSpindlePowerRatio" }
      ] },
    { "kind": "leaf", "name": "Other" }
  ]
}

IsRapid is a yes / no read as 1 or 0, so eq with 1 asks for yes. Put under RatioCheck, the nodes are numbered 1 to 5 and nextId is 6. The three ratios are physics values: on a play without the physics they have no value, and every step that is not rapid goes to Other.

Putting, Deleting and Checking

PUT checks the tree first, and a tree it refuses changes nothing (the codes under Answers); a body without key keeps the route's. An edit that changes only the names and the hues of the project's first tree under the key, every id sent as GET gave it, is taken in place (appearanceOnly: true): the colors change and no step is read again. Any other edit registers the project's step definitions again, and the charts and the colors follow once a background scan has read the steps again. A rename (renamedFrom) takes along what the project keeps under the old key, when nothing else is left under it: the color index, the color guide, the chart's Y-axis setting and the other trees' references. messages lists, as session-message rows, what is odd but legal — a term's key that no step property has (StepColorTree-Term--KeyUnresolved), that is another tree's and reads as no value (StepColorTree-Term--ColorTreeKey) or that the interface hides (StepColorTree-Term--PhysicsHidden); a value key that is no quantity (StepColorTree-Leaf--ValueKeyNotQuantity); a hue outside 0 to 360 (StepColorTree-Leaf--HueOutOfRange); more than 32 leaves, past which the chart no longer stripes a pixel column by leaf (StepColorTree-Tree--TooManyLeavesForChart); a node with the last id, 1,048,575, which leaves the tree no number to give next (StepColorTree-Tree--NextIdOutOfRange); no node that takes every step (StepColorTree-Node--NoOtherwise), a node no step reaches (StepColorTree-Node--Unreachable), a condition without terms (StepColorTree-Condition--Empty), a group without children (StepColorTree-Group--Empty) — and what the refresh reports about the project's other definitions.

DELETE takes the tree's color guide with it when no tree under the key remains, and leaves the color index as it is. When the color index was the deleted tree's key, no tree of the project is left under it, and no other step property holds it once the project's step definitions are registered again — a script's tree or step variable for the session, set aside while the project's tree held the key, takes the key back then — removedInspectingKey names it and messages carries StepColorTree-Delete--InspectingKey: the charts and the 3D view show no value under the key, and the next play reports Play-InspectingKey--Unresolved, until the color index is set to a key that names something. Otherwise removedInspectingKey is null, and messages carries no such row.

check answers the engine's problems as { code, path, refuses } — refuses: true keeps the tree from registering, and a tree without a key reports KeyMissing here instead of being refused — with the warnings PUT would answer (but for StepColorTree-Tree--NextIdOutOfRange, which only a PUT answers, once it has numbered the tree) and referencedKeys, every key the tree reads.

Previewing

preview takes tree, a tree as check takes it, or key, a registered tree's, the project's or a script's; stepIndex, the strip index of a step to explain, or none for the selected step; and range, display for the range the strip charts show, anything else for every step. It reads the played steps themselves, not the cached values the charts draw. histogram is { range, begin, end, scannedSteps, leaves: [ { id, name, steps, seconds, share, firstStepIndex } ], noValue: { steps, seconds, share }, faultedSteps, skippedPositions }, share the part of the scanned steps' time; selectedStep is { stepIndex, leafId, leafName, leafValue, values: [ { key, value } ], trace: [ { id, name, kind, held } ], error } — the values the tree read and the nodes it tried, in order — or null when no step is selected and none is named. A value that is not a number travels as the string "NaN". One preview runs at a time on the instance, whoever sends it: a newer one — another caller's, a browser's included — stops the one running, which answers 409, and so does a preview whose steps change under it (a Reset, a recompute, a key registered or set as the color index, values written onto the steps); send it again. A preview whose client goes away stops too.

Answers

Answer Sent for
400 NoProjectLoaded no project open; the two GETs answer it as 200 with success: false
400 StepColorTreeKeyEmpty an empty key, a body key of "" included
400 StepColorTreeKeySlash a key holding /, which no path segment can carry
400 StepColorTreeKeyDotSegment a key that is . or ..
400 StepColorTreeKeyTaken a built-in step property's key, or one under MC.
400 StepColorTreeInvalidCharacter a key, name, value key or term key holding a character a project file cannot store, such as a form feed; path names the text: key, name, nodes[0].name, nodes[0].valueKey, nodes[0].when.terms[1].key
400 StepColorTreeNodeMalformed a node that is not a leaf or a group as written above; reason is kind, leafWithChildren, groupWithHue, groupWithValueKey, join, hue (NaN or an infinity) or null, and for preview compile, a tree that does not compile
400 StepColorTreeTermMalformed a term without a key, with an op not among the eight, or without the threshold its comparison needs; reason is key, op, threshold or null
400 StepColorTreeIdRepeated an id another node has
400 StepColorTreeIdOutOfRange an id outside 1 to 1,048,575, or a number a node sent without an id would get beyond it
400 StepColorTreeNoStep preview: a stepIndex with no step on the strip; args stepIndex and stripCount
400 StepColorTreeStepNotBuiltYet preview: a stepIndex that is the next step of a play that stopped before building it, or is building it; args add running
404 StepColorTreeNotFound a key, a rename's old key or an occurrence the project has no tree under; for preview, a key no registered tree has
409 StepColorTreeKeyRepeated a rename onto a key the project defines a tree or a step variable under, or an add under a project step variable's key; a PUT under a key a project file repeats, without occurrence
412 StepColorTreeKeyRepeated If-None-Match: * while the project has a tree under the key
409 StepColorTreePreviewSuperseded preview: stopped by a newer preview, or by a change to the steps under it

A refusal is { success: false, code, message }, most codes with args beside them; where the code is about a place, args.path points into the body, nodes[1].children[0].when.terms[2]. A preview with neither tree nor key answers 400 with a message alone.

The Color Index

The color index is shared. POST /api/execution/inspecting-key with {"inspectingKey": "<key>"} sets it, and answers { success, currentKey, messages } — messages about the color range in effect — or success: false with no project open. It is a project setting, saved with the project: the Color Index Time Chart, the colors of the tool path and the cut faces, and the selected color guide follow it on every connected screen. The field is inspectingKey and nothing else in the body is read, so {"key": "RatioCheck"} clears the color index and still answers success: true, with currentKey: null. Read the key the project holds before setting another — inspectingKey of GET /api/execution/step-color-trees — and post it back the same way afterwards, null for none — only while the color index is still the tree's key: a key another user has set since is theirs to keep. currentKey of GET /api/execution/step-properties is not that key while the physics keys are hidden (physicsShown: false) and the color index is a physics key: it then names the key shown in its place.

Once a tree is the color index, the screens' own routes describe it: the Individual strip chart's item carries colorTree, with leafTotals per leaf over the steps it draws, GET /api/execution/color-guide carries tree, and GET /api/execution/step-properties lists every key the interface shows whose value is a number, with its source and unitLabel, a tree's with source: "colorTree" — all in Strip Charts. The Individual chart answers for the color index alone, so a count per leaf that leaves every screen as it is comes from the preview's histogram. A step file has a column under the tree's key, holding each step's leaf id.

Values Written onto Steps after They Were Built

The charts and the colors read each step's cached value of the color index, filled as the step is built and refilled by a background scan whenever the cache is marked stale; a preview reads the steps themselves. A value a step-built handler writes onto the step being built is in the cache when the step is published. A batch written with WriteStepVariables(API) marks the cache stale once per batch, and a single step["key"] = value after the play marks it itself. Host code that writes with the indexer onto an earlier step while a play runs calls NotifyStepValuesWritten(API) once its writes are done: such a write can travel to the step cache with that step's own results, and then marks nothing stale. When the cache is filled and refilled: When a Tree Is Evaluated.

The Requests in Order

The requests in order, on a project whose mission has played; every body is JSON, sent with Content-Type: application/json:

GET  /api/execution/step-color-trees               -> keyOptions, physicsShown
POST /api/execution/step-color-trees/check         the tree above                          -> problems: []
POST /api/execution/step-color-trees/preview       {"tree": <the tree above>, "range": "all"}
PUT  /api/execution/step-color-trees/RatioCheck    the tree above, header If-None-Match: *  -> item.state: "registered", item.tree.nextId: 6
GET  /api/execution/step-color-trees               -> keep inspectingKey
POST /api/execution/inspecting-key                 {"inspectingKey": "RatioCheck"}         only to show it
GET  /api/execution/step-color-trees               -> inspectingKey still "RatioCheck", else skip the next request
POST /api/execution/inspecting-key                 {"inspectingKey": <the key kept>}
POST /api/Project/save

See Also