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 builtInTrees, 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, builtInTrees, trees, registeredAtRun, keyOptions }
GET {key} — one tree: { success, item, generation }, item as an entry of trees, or of builtInTrees when the project has no tree under a built-in tree's key and occurrence is 0 or left out
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 }; 409 under a built-in tree's key
DELETE {key} — removes every tree under the key, or the one occurrence names: { success, removedInspectingKey, messages, generation }; 409 under a built-in tree's key
POST {key}/copy { newKey, name }, either left out, or none copies the built-in tree {key} to the end of the project's list: 201 { success, item, messages, generation }, with Location the copy's GET {key} (Built-in Trees)
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, readOnly, state, inspected, tree, leaves, referencedKeys, problems }, origin project and readOnly false. 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, a built-in tree's, 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, shortName, hue, hueAuto, color, valueKey }, shortName the lane's label (empty shows the name, cut to fit), 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. builtInTrees lists HiNC's own trees in the shape of trees' entries, origin builtIn and readOnly true, occurrence 0, state registered, inspected while the color index is the tree's key, and the names in the language ?lang= asks for; neither trees nor registeredAtRun lists them, and keyOptions leaves out every tree's key.

A Tree

A tree is { key, name, nextId, nodes }, and a node { kind, id, name, shortName, when, hue, valueKey, children }. shortName is a leaf's lane label; a group that carries one is refused. 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": "StressRatio", "op": "hasValue" } ] },
      "children": [
        { "kind": "leaf", "name": "Above 100 %", "hue": 0,
          "when": { "join": "any", "terms": [
            { "key": "StressRatio", "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, the short 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.

Built-in Trees

HiNC defines two trees of its own, registered whenever a project is open and never saved with it, and builtInTrees lists them in this order (Engineering View Coloring): MachiningState, Machining State, sorts every step into Collision (leaf 1), Rapid cut (2), the group Cutting (12) of a touched step with its nine load leaves — Stress overload (4), Spindle torque sustained overload (5), Spindle power sustained overload (13), Spindle torque brief overload (6), Spindle power brief overload (14), Spindle overheat (7), Load not evaluated (8), Thermal stress overload (15), Normal cutting (9) — Air cut (10) or Rapid (11), its nextId 16; MachiningStateGeometry, Machining State (No Physics), sorts it into Collision (1), Rapid cut (2), Cutting (load not evaluated) (8), Air cut (10) or Rapid (11) from the play alone, its nextId 12. The two keys are reserved as a built-in step property's key is: no project tree or step variable takes them. MachiningState reads the physics, so it is a physics key: step-properties leaves it out while the physics is hidden, and the chart stands the other tree in for it (The Color Index).

  • PUT and DELETE under a built-in tree's key answer 409 StepColorTreeBuiltIn, with args key, and change nothing. A project file edited by hand may hold a project tree under such a key: trees lists it with state keyTaken, never inspected, and GET {key} answers it rather than the built-in tree, which builtInTrees alone then carries; a DELETE, or a PUT that renames it away, takes it, and a PUT under the key itself answers 400 StepColorTreeKeyTaken.
  • POST {key}/copy copies a built-in tree to the end of the project's list: an ordinary project tree, saved with the project and editable, which HiNC's later versions leave as it is. The body { newKey, name } may leave out either, or be left out. Without newKey, the copy takes the first of {key}Copy, {key}Copy2, … that no tree or step variable of the project, no step property and not the color index holds; a newKey given passes PUT's key refusals, and "" is refused (StepColorTreeKeyEmpty) rather than taken for none. Without name, it takes the built-in tree's name in the request's language. The copy keeps the built-in tree's node ids, nextId, conditions and hues, its leaves named in the request's language, and leaves the color index as it is. item is the copy as trees lists it; a key that holds no built-in tree — a project tree's among them — answers 404.
  • preview by a built-in tree's key works as for any registered tree, its names in the request's language.

Elsewhere a built-in tree is a tree like the others: a term on its key reads as no value (StepColorTree-Term--ColorTreeKey), and the step file has a column under its key.

Previewing

preview takes tree, a tree as check takes it, or key, a registered tree's, the project's, a script's or a built-in one; 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 "" and a copy's newKey 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, a built-in tree's (MachiningState, MachiningStateGeometry) as a new key — a rename, a copy's newKey — or one under MC.
400 StepColorTreeInvalidCharacter a key, name, short 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].shortName, 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, groupWithShortName, 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; for a copy, a key that holds no built-in tree
409 StepColorTreeBuiltIn a PUT or a DELETE under a built-in tree's key; args key
409 StepColorTreeKeyRepeated a rename or a copy 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, while the currentKey that POST /api/execution/inspecting-key answers stays the key stored. For MachiningState, the one tree that stands in for another, the key shown is MachiningStateGeometry: the Individual strip chart asked for MachiningState answers pending: true with items empty every time, so read currentKey and ask for MachiningStateGeometry, whose item carries colorTree.standsInFor: "MachiningState", its lanes coloured by the full tree's guide, while the color guide's tree stays the full tree.

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, both with the tree's origin — builtIn, project or session — and its notes, 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", and its group, engineering for a tree's key and science for any other, and builtInTree, true for a built-in tree's — all in Strip Charts and Step Colors REST. 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; with a project open it has the built-in trees', MachiningState and MachiningStateGeometry, as well.

Notes of a Built-in Tree

A built-in tree's colorTree and tree carry notes: what the steps since the last reset were played under that the leaves cannot show. Start does not reset, so the notes cover every play since the steps were last cleared — a reset (POST /api/Execution/reset), a review opened or closed, another project. Each note is { code, message, args }, message the server's English; a client writes its own text from code, args.scope and the rest of args, and names the leaves args.leafIds gives by id from the same answer's leaves. The notes come in the table's order, those the table marks MachiningState for that tree alone; an empty strip has none, and under review a tree has one note alone, RecordedPlay for MachiningStateGeometry and RecordedPlayLoad for MachiningState:

code Sent when args
CollisionDetectionOff collision detection was off for a step: scope all for every step, part for the ranges, often for part of them once the detection was switched more than limit times scope, ranges ({ first, last }, inclusive, at most 8), moreRanges (how many are not listed), limit (4096), leafIds.collision
CollisionDetectionUnlicensed collision detection was on and answered nothing for a step — no collision licence, or no machining chain to detect against — by the same scopes as above, leafIds.collision
NoRapidSemantics steps came from a CSV program, by the same scopes, often once the program kind changed more than limit times as above, leafIds.rapid, rapidCut and airCut
PhysicsOff MachiningState: the physics was off for a step, by the same scopes as above, leafIds.loadNotEvaluated
SpindleCapability MachiningState, once the physics was on for some step and some cut got a physics result: the spindle capability the spindle ratios are read against source — file, embedded (in the project) or none (no capability loaded: the file the project names could not be read) — name (null for none), file (the file's name, its .default marker left out; null when embedded), leafIds.loadNotEvaluated
StressRatioNotEvaluated MachiningState: tools whose stress ratio could not be evaluated on any cut, the tools Play-StressRatio--None names toolIds (ascending), leafIds.loadNotEvaluated
RecordedPlay MachiningStateGeometry under review: whether the detection was on is not recorded, and no rapid cut is judged, so a rapid that touched is its Cutting (load not evaluated) leafIds.cutting
RecordedPlayLoad MachiningState under review: the same, a rapid that touched sorted as a cut by the load the recording holds; and the recording's spindle torque overload, spindle power overload and stress overload runs are not folded, so its spindle torque, spindle power and stress overload revolutions read 0: Spindle torque sustained overload and Spindle power sustained overload are never judged; Stress overload and Thermal stress overload read the recorded stress ratio and thermal stress ratio themselves and are judged leafIds.spindleTorqueSustainedOverload, spindlePowerSustainedOverload, stressOverload and thermalStressOverload

A project's or a session's tree answers notes: [], a copy of a built-in tree included.

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