Archived
566 lines
37 KiB
HTML
566 lines
37 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Persistent Variables | HiAPI-C# 2025 </title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="title" content="Persistent Variables | HiAPI-C# 2025 ">
|
||
|
||
|
||
<link rel="icon" href="../../../../img/HiAPI.favicon.ico">
|
||
<link rel="stylesheet" href="../../../../public/docfx.min.css">
|
||
<link rel="stylesheet" href="../../../../public/main.css">
|
||
<meta name="docfx:navrel" content="../../../../toc.html">
|
||
<meta name="docfx:tocrel" content="toc.html">
|
||
|
||
<meta name="docfx:rel" content="../../../../">
|
||
|
||
|
||
|
||
<meta name="loc:inThisArticle" content="In this article">
|
||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||
<meta name="loc:tocFilter" content="Filter by title">
|
||
<meta name="loc:nextArticle" content="Next">
|
||
<meta name="loc:prevArticle" content="Previous">
|
||
<meta name="loc:themeLight" content="Light">
|
||
<meta name="loc:themeDark" content="Dark">
|
||
<meta name="loc:themeAuto" content="Auto">
|
||
<meta name="loc:changeTheme" content="Change theme">
|
||
<meta name="loc:copy" content="Copy">
|
||
<meta name="loc:downloadPdf" content="Download PDF">
|
||
|
||
<script type="module" src="./../../../../public/docfx.min.js"></script>
|
||
|
||
<script>
|
||
const theme = localStorage.getItem('theme') || 'auto'
|
||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||
</script>
|
||
|
||
</head>
|
||
|
||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||
<header class="bg-body border-bottom">
|
||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||
<div class="container-xxl flex-nowrap">
|
||
<a class="navbar-brand" href="../../../../index.html">
|
||
<img id="logo" class="svg" src="../../../../img/HiAPI.logo.png" alt="">
|
||
|
||
</a>
|
||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||
<i class="bi bi-three-dots"></i>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="navpanel">
|
||
<div id="navbar">
|
||
<form class="search" role="search" id="search">
|
||
<i class="bi bi-search"></i>
|
||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
</header>
|
||
|
||
<main class="container-xxl">
|
||
<div class="toc-offcanvas">
|
||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||
<div class="offcanvas-header">
|
||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||
</div>
|
||
<div class="offcanvas-body">
|
||
<nav class="toc" id="toc"></nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="content">
|
||
<div class="actionbar">
|
||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||
<i class="bi bi-list"></i>
|
||
</button>
|
||
|
||
<nav id="breadcrumb"></nav>
|
||
</div>
|
||
|
||
<article data-uid="Anatomy-ControllerPersistentVariables">
|
||
<h1 id="persistent-variables">Persistent Variables</h1>
|
||
|
||
<p>Persistent Variables is the pair of program-variable ledgers the Controller branch grows for one
|
||
brand or the other, and no shipped preset carries both: the Fanuc-style retained common variables
|
||
and the Sinumerik R parameters. Both live on the General Setup page at <code>/general-setup</code> under the
|
||
Control-Tree ids <code>equipment/controller/program-data/retained-variables</code> and
|
||
<code>equipment/controller/program-data/r-parameters</code> — reached as
|
||
<code>?tree=equipment/controller/program-data/retained-variables</code> and
|
||
<code>?tree=equipment/controller/program-data/r-parameters</code> — and the tree labels them
|
||
<strong>Retained Common Variables</strong> and <strong>R Parameters</strong>. They share a page because no preset shows both:
|
||
each node is grown by a flag that one set of brand presets satisfies and the other set does not.</p>
|
||
<div class="IMPORTANT">
|
||
<h5>Important</h5>
|
||
<p>Anatomy makes no claim that any id named here is stable across versions. The migration hop that
|
||
keeps an older <code>?tree=</code> value resolving is described in
|
||
<a class="xref" href="../../../platform/tree-ids-and-routes.html">Tree Ids and Routes</a>.</p>
|
||
</div>
|
||
<h2 id="two-nodes-that-exclude-each-other">Two Nodes That Exclude Each Other</h2>
|
||
<p>The branch builder pushes each of the two nodes inside a test of its own, one snapshot flag each, and
|
||
each flag is a single type probe over the runner's proxy-resolved dependency list —
|
||
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Fanuc.RetainedCommonVariableTable.html">RetainedCommonVariableTable</a> behind one and
|
||
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Siemens.SiemensRParameterTable.html">SiemensRParameterTable</a> behind the other. Which brand
|
||
satisfies which gate is <a class="xref" href="../brand-matrix.html">Brand Matrix</a>; the short answer is that
|
||
the Fanuc, Syntec and Mazak presets carry a retained-common-variable proxy, the Siemens preset carries
|
||
an R-parameter proxy, and the Heidenhain preset carries neither.</p>
|
||
<p><strong>The exclusion is a property of the five preset lists, not a rule in the builder.</strong> Nothing in the
|
||
tree code forbids the two rows from standing together; no shipped preset simply carries both entries,
|
||
and the brand select can produce nothing but a preset. A runner composed by hand or loaded from a
|
||
controller file whose pipeline list named both tables would grow both rows, each with its own working
|
||
panel — and the Object-Management menu on the branch root, described in
|
||
<a class="xref" href="../index.html">Controller Branch</a>, installs such a file without inspecting what its
|
||
pipeline names, so that route is open from inside the branch.</p>
|
||
<p>The two panels are separate components rather than one component discriminating on the node id, so
|
||
neither reads the node it was given. What they share is a shell: the same three-state body, the same
|
||
dense table, the same footer, and the same commit, rollback and toast rules the whole branch follows
|
||
— <a class="xref" href="../editing-contract.html">Editing Contract</a>.</p>
|
||
<h2 id="what-each-ledger-is">What Each Ledger Is</h2>
|
||
<h3 id="retained-common-variables">Retained Common Variables</h3>
|
||
<p><a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Fanuc.RetainedCommonVariableTable.html">RetainedCommonVariableTable</a> models the Fanuc-style ISO
|
||
controller's common variables in the retained range <code>#500</code>–<code>#999</code> — the range a real control keeps in
|
||
non-volatile memory across a power cycle, which is why the model stores it with the project rather
|
||
than with the run. It is the range, not the whole macro-variable surface: the table answers a <code>#nnn</code>
|
||
lookup only for 500 through 999 and returns nothing for any other key, so an out-of-range reference
|
||
falls through to the next lookup in the evaluator's chain.</p>
|
||
<p>The neighbouring ranges are deliberately elsewhere, and none of them has a node on this branch.
|
||
<code>#1</code>–<code>#33</code> are call-frame locals bounded by a macro call rather than by a power cycle. <code>#100</code>–<code>#499</code>
|
||
are the non-retained commons, carried block to block in the per-block dataflow and cleared on the
|
||
block that ends the program. <code>#1000</code> and above are read-only or computed from runtime state rather
|
||
than stored here: some resolve against other dependencies — the brand parameter table behind the
|
||
work-coordinate addresses, the tool offset table behind <code>#2001</code>–<code>#2200</code> — and some come from the
|
||
block's own record, which is where the position variables are read and where a system-control write
|
||
is recorded rather than emulated.</p>
|
||
<p>The type name and the tree label both say <em>common variable</em> rather than <em>macro variable</em>, because the
|
||
model reserves “macro” for Custom Macro B's call frame. The hint above the table is the one string in
|
||
the leaf that says <strong>Retained macro variables</strong> instead.</p>
|
||
<h3 id="r-parameters">R Parameters</h3>
|
||
<p><a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Siemens.SiemensRParameterTable.html">SiemensRParameterTable</a> models the Sinumerik arithmetic
|
||
variable surface <code>R0</code>–<code>R999</code> — the <code>R63=100.5</code> and <code>C=R61</code> of a Siemens program. On the control these
|
||
sit in retentive memory and survive both program end and a power cycle, and the model keeps them the
|
||
same way: stored with the project, not reset with the session.</p>
|
||
<p>The table answers an <code>Rn</code> key in the canonical uppercase form the Siemens expression parser produces,
|
||
and a lowercase <code>rn</code> from a raw capture resolves as well. Every other key returns nothing.</p>
|
||
<h2 id="addressing-and-ranges">Addressing and Ranges</h2>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th></th>
|
||
<th>Retained Common Variables</th>
|
||
<th>R Parameters</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Node id</td>
|
||
<td><code>equipment/controller/program-data/retained-variables</code></td>
|
||
<td><code>equipment/controller/program-data/r-parameters</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Snapshot flag</td>
|
||
<td><code>hasRetainedVariables</code></td>
|
||
<td><code>hasRParameters</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Backing table</td>
|
||
<td><a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Fanuc.RetainedCommonVariableTable.html">RetainedCommonVariableTable</a></td>
|
||
<td><a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Siemens.SiemensRParameterTable.html">SiemensRParameterTable</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Brands</td>
|
||
<td>Fanuc, Syntec, Mazak</td>
|
||
<td>Siemens</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Key column header</td>
|
||
<td><strong>Variable</strong></td>
|
||
<td><strong>Parameter</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Key cell reads</td>
|
||
<td><code>#</code> then the number</td>
|
||
<td><code>R</code> then the number</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Accepted ids</td>
|
||
<td>500–999</td>
|
||
<td>0–999</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Bounds on the add field</td>
|
||
<td>minimum 500, maximum 999</td>
|
||
<td>minimum 0, maximum 999</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Absent-table body</td>
|
||
<td><em>"No retained common variable table on the active runner."</em></td>
|
||
<td><em>"No R-parameter table on the active runner."</em></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Each range is a pair of constants declared on the table type, and four separate places enforce it.
|
||
The panel refuses an add whose id is not a whole number inside the range and says so in a toast of its
|
||
own. The numeric field carrying that id rejects a <em>finite</em> value outside its bounds before the panel
|
||
ever sees it — the infinity and NaN literals the field also parses skip the bounds test entirely and
|
||
are stopped by the panel's whole-number check instead. The write endpoint compares the id against the
|
||
same two constants and answers unsuccessfully with the range spelled out in the message. And behind
|
||
all three, the table's own writer ignores an out-of-range id — the guard that holds for a caller
|
||
reaching the table directly rather than through the endpoint, which is how a run writes.</p>
|
||
<p>The endpoint's guard is not reachable from a project this app wrote. The rows a panel writes to came
|
||
from the table, the add path is already filtered, and the serializer drops an out-of-range key on the
|
||
way out, so no file the app saves carries one. Loading applies no such filter: a project file edited
|
||
by hand can carry an id outside the range, the read lists it and the panel shows it, and editing that
|
||
row's value is the one way a reader meets the endpoint's range message.</p>
|
||
<p><strong>No range is narrowed by machine data.</strong> The R range in particular is the fixed pair 0–999 on the
|
||
table type; the endpoint reads no value from the Siemens machine-data table before accepting an id,
|
||
so the parameter count a real control would allocate does not constrain what this leaf accepts.</p>
|
||
<p><strong>Neither table is dense.</strong> A row exists for an id that has been written, and for no other, so a
|
||
thirty-row table and a four-row table are equally normal and the numbers in the key column need not be
|
||
contiguous. A project that has never written one shows an empty table body under the header, because
|
||
the proxy that materialises the table installs a bare instance carrying nothing —
|
||
<a class="xref" href="index.html">Program Data Plane</a> covers the seedless proxies this plane is
|
||
built from. The read returns the rows in ascending id order and the panel never re-sorts: an edit
|
||
leaves a row where it is, a delete removes it in place, and only the re-read that follows an add
|
||
re-orders anything.</p>
|
||
<h2 id="what-persists-and-what-clears">What Persists, and What Clears</h2>
|
||
<p>Both tables are per-case entries of the project's own dependency list, reached through a get-or-create
|
||
placeholder in the runner's pipeline list. The runner file records only an empty placeholder element,
|
||
so the values are written into the project file rather than into a controller asset.</p>
|
||
<p>Four things in the runtime could plausibly discard what these tables hold. Three of them leave both
|
||
tables alone; the fourth removes a table outright rather than clearing it.</p>
|
||
<ul>
|
||
<li><strong>A new session does not clear them.</strong> The session-init edge that rebuilds the syntax pipeline
|
||
sweeps every dependency and syntax declaring session-scoped state — iteration counters, index
|
||
allocators — and calls each one's reset. Neither table declares any, so both are skipped.</li>
|
||
<li><strong>A power reset does not clear them.</strong> The power-reset command sweeps the proxy-resolved dependency
|
||
list for dependencies declaring a volatile subset and then resets the session state, dropping the
|
||
per-block dataflow. None of the dependencies a brand preset carries declares a volatile subset, so
|
||
what a power reset actually discards is the dataflow — which is where the non-retained commons live
|
||
— while every value in these two tables stands.</li>
|
||
<li><strong>Program end does not clear them.</strong> The syntax that models a control's <code>M02</code> / <code>M30</code> reset empties
|
||
the block's volatile dictionary and cancels an active modal macro. It writes into the block's own
|
||
record and reaches no dependency at all, so neither table is in its path.</li>
|
||
<li><strong>A brand switch removes the whole table rather than clearing it.</strong> The sweep that follows a runner
|
||
swap keeps exactly the per-case tables the new runner resolves through a proxy, so a switch to a
|
||
brand that proxies neither drops the table outright, and switching back materialises a fresh empty
|
||
one rather than the values that were there. Retained Common Variables is the wider of the two: all
|
||
three of Fanuc, Syntec and Mazak proxy it, so it survives any switch among those three and is
|
||
removed on a switch to Siemens or Heidenhain. R Parameters survives only a Siemens-to-Siemens
|
||
re-flash. What a switch keeps, resets and destroys across the whole plane is
|
||
<a class="xref" href="index.html">Program Data Plane</a>.</li>
|
||
</ul>
|
||
<h3 id="a-run-writes-into-the-same-table">A run writes into the same table</h3>
|
||
<p>These are not a snapshot of what a program did — they are the store the program uses. Each brand's
|
||
syntax list carries a reading syntax that consumes a literal assignment out of the parsed block and
|
||
writes it straight into the table: <code>#500 = 1.234</code> on the three Fanuc-style brands, <code>R63 = 100.5</code> on
|
||
Siemens. No mirror is kept in the per-block dataflow; the table is the single source of truth. A
|
||
non-literal right-hand side is resolved to a literal earlier in the same block by the expression
|
||
normaliser and then lands by the same route, so <code>#600 = #500 + 1</code> reaches the table as well.</p>
|
||
<p>Reads run the other way through the same object: each table is a variable lookup on the effective
|
||
dependency list, so an expression naming an id in range reads whatever the leaf shows.</p>
|
||
<p>Two consequences follow for a reader of this leaf. A played program changes what the table holds, and
|
||
because no panel in the branch is pushed at, the change appears only when the panel is remounted by
|
||
selecting another node and coming back. And because the table is written into the project file, those
|
||
run-time writes are what the next load of that project starts from — once the project is saved.
|
||
Nothing in the branch and nothing on the run path saves on its own: a panel edit and a run-time write
|
||
alike stand in memory until an explicit save, and closing the project without one discards them.</p>
|
||
<h3 id="vacant-is-a-value-and-it-fails-loud">Vacant is a value, and it fails loud</h3>
|
||
<p>A stored null is a <strong>vacant</strong> entry, and so is a missing key — the table reads the two identically.
|
||
Vacant is not zero. An expression that evaluates a vacant id does not fall back to a number: the
|
||
evaluator returns a failure carrying the code <code>Variable--Vacant</code> and a message naming the key, which
|
||
is what the R-parameter hint means by reporting an error instead of silently using 0.</p>
|
||
<p>Vacant and deleted are different operations even though they read the same at run time. Clearing a
|
||
cell keeps the key with a null value; the delete button drops the key. The distinction survives a save,
|
||
because a vacant entry is written as an element carrying an id and no value while a deleted one is
|
||
written as nothing at all — so a vacant row comes back as a row, and a deleted one does not come back.</p>
|
||
<h2 id="the-editor-body">The Editor Body</h2>
|
||
<p>Above the table sits a one-line hint, and it is the only prose either panel shows. Both render the
|
||
literal text <code><vacant></code> inside it as inline code.</p>
|
||
<ul>
|
||
<li>Retained Common Variables: <em>"Retained macro variables #500–#999 (power-off safe). Empty =
|
||
<code><vacant></code>. #100–#499 are volatile and live in the run's dataflow, not here."</em></li>
|
||
<li>R Parameters: <em>"Sinumerik R parameters R0–R999 (retentive). Empty = <code><vacant></code> — a program reading
|
||
a vacant R parameter reports an error instead of silently using 0."</em></li>
|
||
</ul>
|
||
<p>The table below it has three columns. The first is the key — headed <strong>Variable</strong> or <strong>Parameter</strong> —
|
||
rendered bold as plain text and not editable, which is the branch's rule for a key column. The second
|
||
is headed <strong>Value</strong> and holds the shared numeric field. The third carries the row's delete button
|
||
under a blank header, so the branch's shared <strong>Actions</strong> heading does not appear on either leaf.</p>
|
||
<h3 id="editing-a-value">Editing a value</h3>
|
||
<p>A value cell is the shared numeric widget, so it commits on blur or on Enter and never per keystroke;
|
||
its parsing, its bound behaviour and the double commit an Enter can cause are
|
||
<a class="xref" href="../../../widget/numeric-input.html">Numeric Input</a>. No value cell is bounded — neither panel passes a minimum
|
||
or a maximum to it — so any finite number is accepted and stored, negatives included.</p>
|
||
<p><strong>These two panels are the branch's only pair that commits a null.</strong> Every other numeric handler in
|
||
the branch treats a cleared cell as no edit and returns before the request; here the null is sent,
|
||
because vacating an entry is a real state of both tables and there is no other control that reaches
|
||
it. Clearing the cell is therefore how a row is made vacant while keeping its key.</p>
|
||
<p>The handler is otherwise the branch's ordinary optimistic write — assign, send, and on failure put the
|
||
captured value back and raise the toast — and it carries no finiteness test. The widget parses
|
||
<code>Infinity</code> and <code>-Infinity</code> as values, and neither survives JSON encoding: the request body reaches the
|
||
server carrying a null, and the entry is set vacant. The cell keeps showing <code>Infinity</code> until the panel
|
||
is remounted, so that is the one place in the table body where the screen and the store disagree
|
||
after a write the server accepted. A typed <code>NaN</code> takes the same route to vacant, and the cell renders
|
||
it as empty, which is what a vacant entry looks like anyway.</p>
|
||
<h3 id="adding-and-removing-a-row">Adding and removing a row</h3>
|
||
<p>The footer under the table is the branch's fielded add form: a numeric field for the id — labelled
|
||
<strong>Variable # (500–999)</strong> or <strong>Parameter # (0–999)</strong> — a second numeric field labelled <strong>Value</strong>, and a
|
||
primary <strong>Add / Set</strong> button. Both fields are the same numeric widget as the value cells, so what they
|
||
hold reaches the panel on blur or Enter rather than per keystroke, and neither input submits on Enter.</p>
|
||
<p>The button label's second word is the accurate one: the write is an upsert. Entering an id the table
|
||
already lists overwrites that row's value rather than adding a second row. Leaving <strong>Value</strong> empty
|
||
creates the row vacant. A successful add is followed by a full re-read of the table, which is what
|
||
puts the new row in ascending order; the two fields keep what was typed in them.</p>
|
||
<p>Two refusals sit in front of that write, and they read differently. An id outside the field's own
|
||
bounds is rejected inside the widget, which shows its message under the box, emits nothing and leaves
|
||
the rejected text on screen — so the panel still holds the id the field last committed to it. On a
|
||
panel that has committed none, that is nothing at all, and pressing <strong>Add / Set</strong> reports the panel's
|
||
own message: <em>"Variable number must be an integer in 500–999."</em> or <em>"Parameter number must be an
|
||
integer in 0–999."</em> The panel's message is also what a fractional id produces, since the panel
|
||
requires a whole number and the field does not.</p>
|
||
<p>A field that has already committed a valid id keeps it, and nothing clears either field after an add.
|
||
So an out-of-range id typed over one the field already accepted is the second place on these leaves
|
||
where the screen and the store part company: the box shows the rejected number, the panel still holds
|
||
the earlier id, and <strong>Add / Set</strong> upserts that earlier id with whatever the value field holds — no
|
||
message of any kind, and the re-read that follows leaves the rejected number in the box.</p>
|
||
<p>Removal is one icon button per row, with no label, no tooltip and no confirmation dialog: the click
|
||
sends the delete, and the row is filtered out of the panel's list once the request resolves. The branch
|
||
guards some of its deletions with a confirmation dialog; neither of these two leaves is among them.
|
||
The endpoint removes the key and reports success whether or not the key was there.</p>
|
||
<h2 id="what-the-surface-covers">What the Surface Covers</h2>
|
||
<p>A third table of the same shape exists in the engine and has no node.
|
||
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Heidenhain.HeidenhainQParameterTable.html">HeidenhainQParameterTable</a> holds the Heidenhain persistent
|
||
Q parameters — the free range <code>Q0</code>–<code>Q99</code> and the permanent <code>QR0</code>–<code>QR499</code>, in two stores of its own —
|
||
and the Heidenhain preset carries a proxy for it beside the two documented above. It is materialised
|
||
into the project's per-case list exactly as they are, is serialized into the project file the same way,
|
||
is swept by a brand switch away from Heidenhain the same way, and is read and written during a run by
|
||
the Heidenhain reading syntax that routes <code>Qn</code> and <code>QRn</code> assignments by id range.</p>
|
||
<p>What it has no part in is this branch. The snapshot the tree is built from declares no flag that
|
||
probes it, the branch's REST surface declares no route that reaches it, and the branch builder mints
|
||
no node for it. The Controller branch's editable persistent-variable surface is the two tables named
|
||
above; a Heidenhain project's Q parameters are set and read by the program that runs, and are carried
|
||
by the project file between runs.</p>
|
||
<h2 id="layout">Layout</h2>
|
||
<ul>
|
||
<li><strong>General Setup</strong> Control Tree — the left dock of <code>/general-setup</code>
|
||
<ul>
|
||
<li><strong>Controller</strong> Node Row
|
||
<ul>
|
||
<li><strong>Program Data</strong> Group Row — <code>equipment/controller/program-data</code>
|
||
<ul>
|
||
<li><strong>Retained Common Variables</strong> Node Row —
|
||
<code>equipment/controller/program-data/retained-variables</code>; grown while the snapshot reports a
|
||
retained common variable table</li>
|
||
<li><strong>R Parameters</strong> Node Row — <code>equipment/controller/program-data/r-parameters</code>; grown while the
|
||
snapshot reports a Siemens R-parameter table</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>Editor Row — the panel of whichever node is selected
|
||
<ul>
|
||
<li><strong>Retained Common Variables</strong> Panel
|
||
<ul>
|
||
<li>No-Runner Body — the shared <em>"No NC runner — load a project first."</em>; shown first</li>
|
||
<li>Absent-Table Body — <em>"No retained common variable table on the active runner."</em></li>
|
||
<li>Editor Body
|
||
<ul>
|
||
<li>Hint Caption — <em>"Retained macro variables #500–#999 (power-off safe). Empty = <code><vacant></code>.
|
||
#100–#499 are volatile and live in the run's dataflow, not here."</em></li>
|
||
<li>Variable Table — dense, flat, bordered
|
||
<ul>
|
||
<li>Header Row — <strong>Variable</strong>, <strong>Value</strong>, and a blank third heading</li>
|
||
<li>Variable Row, one per stored id
|
||
<ul>
|
||
<li>Variable Number Label — bold plain text, <code>#</code> then the number, not editable</li>
|
||
<li>Value Numeric Field — unbounded; cleared commits vacant</li>
|
||
<li>Delete Button — a bin icon, flat and dense, no label and no confirmation</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>Add Row Footer
|
||
<ul>
|
||
<li><strong>Variable # (500–999)</strong> Numeric Field — minimum 500, maximum 999</li>
|
||
<li><strong>Value</strong> Numeric Field — unbounded; left empty adds the row vacant</li>
|
||
<li><strong>Add / Set</strong> Button — primary, unelevated</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><strong>R Parameters</strong> Panel — the same shell with the Siemens strings
|
||
<ul>
|
||
<li>No-Runner Body — the shared <em>"No NC runner — load a project first."</em></li>
|
||
<li>Absent-Table Body — <em>"No R-parameter table on the active runner."</em></li>
|
||
<li>Editor Body
|
||
<ul>
|
||
<li>Hint Caption — <em>"Sinumerik R parameters R0–R999 (retentive). Empty = <code><vacant></code> — a program
|
||
reading a vacant R parameter reports an error instead of silently using 0."</em></li>
|
||
<li>Parameter Table — dense, flat, bordered
|
||
<ul>
|
||
<li>Header Row — <strong>Parameter</strong>, <strong>Value</strong>, and a blank third heading</li>
|
||
<li>Parameter Row, one per stored id
|
||
<ul>
|
||
<li>Parameter Number Label — bold plain text, <code>R</code> then the number, not editable</li>
|
||
<li>Value Numeric Field — unbounded; cleared commits vacant</li>
|
||
<li>Delete Button — a bin icon, flat and dense, no label and no confirmation</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>Add Row Footer
|
||
<ul>
|
||
<li><strong>Parameter # (0–999)</strong> Numeric Field — minimum 0, maximum 999</li>
|
||
<li><strong>Value</strong> Numeric Field — unbounded; left empty adds the row vacant</li>
|
||
<li><strong>Add / Set</strong> Button — primary, unelevated</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>Neither panel opens a dialog, and neither carries a select, a toggle or a <strong>Show all</strong> control.</p>
|
||
<h2 id="source-code-path">Source Code Path</h2>
|
||
<p>See <a class="xref" href="../../../index.html">HiNC App Anatomy</a> for git repository links.</p>
|
||
<h3 id="web-application">Web Application</h3>
|
||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||
<ul>
|
||
<li><code>wwwroot-src/src/components/controlTree/SoftNcRetainedVariablesPanel.vue</code> — the <code>#500</code>–<code>#999</code>
|
||
ledger: the hint with its vacant slot, the three-column table, the value handler that sends a null
|
||
without a finiteness test, the unconfirmed delete, and the add form with its whole-number and range
|
||
check.</li>
|
||
<li><code>wwwroot-src/src/components/controlTree/SoftNcRParametersPanel.vue</code> — the <code>R0</code>–<code>R999</code> ledger: the
|
||
same shell with the Siemens strings, the <code>R</code>-prefixed key cell, and the add field bounded from 0.</li>
|
||
<li><code>wwwroot-src/src/components/controlTree/softNcItemTypes.ts</code> — the branch builder: the two node ids,
|
||
their labels and label keys, the two flags each is pushed behind, and the item types binding them to
|
||
the two panels.</li>
|
||
<li><code>wwwroot-src/src/api/softNcRunner.ts</code> — the two readers, their identical row shape with a nullable
|
||
value, the two setters and the two removers, and the two snapshot flags the builder tests.</li>
|
||
<li><code>wwwroot-src/src/api/http.ts</code> — the helper that turns a success-flagged failure body into a thrown
|
||
error, which is how an out-of-range write would reach a panel.</li>
|
||
<li><code>wwwroot-src/src/components/widgets/NumericInput.vue</code> — the value and add fields: commit on blur or
|
||
Enter, the empty-text-to-null parse both panels forward, the infinity and NaN literals it also
|
||
accepts, and the bound rejection that shows a message and emits nothing.</li>
|
||
<li><code>wwwroot-src/src/components/controlTree/SoftNcEmptyState.vue</code> — the shared no-runner line both
|
||
panels open with.</li>
|
||
<li><code>wwwroot-src/src/composables/useSoftNcRunner.ts</code> — the shared snapshot the first empty layer reads,
|
||
and the events that re-read it.</li>
|
||
<li><code>wwwroot-src/src/i18n/en/softNc.ts</code> — the two node labels, the two hints, the two absent-table
|
||
bodies, the two add-field labels, the two invalid-id messages and the error contexts each panel
|
||
prefixes its toast with.</li>
|
||
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the shared <strong>Value</strong> column label and the <strong>Add / Set</strong> button
|
||
label.</li>
|
||
<li><code>Mech/SoftNcRunnerController.cs</code> — the REST surface: the two flag probes in the snapshot builder,
|
||
the two reads that order rows by ascending id and report presence from the table alone, the two
|
||
upsert writers with their range guards, the two removers, and the sweep of per-case tables the new
|
||
runner references through no proxy.</li>
|
||
</ul>
|
||
<h3 id="hiapi-engine">HiAPI Engine</h3>
|
||
<ul>
|
||
<li><code>HiMech/NcParsers/Dependencys/Fanuc/RetainedCommonVariableTable.cs</code> — the <code>#500</code>–<code>#999</code> store: the
|
||
range constants, the nullable dictionary that makes vacant a value, the writer that ignores an
|
||
out-of-range id, the variable lookup that answers only in range, and the serialization that keeps a
|
||
vacant entry as a valueless element.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/Fanuc/RetainedCommonVariableTableProxy.cs</code> — the seedless
|
||
get-or-create placeholder the three Fanuc-style presets carry, the bare table it installs into a
|
||
project holding none, and the legacy element name an older project file still deserializes through.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/Siemens/SiemensRParameterTable.cs</code> — the <code>R0</code>–<code>R999</code> store: the range
|
||
constants and the reason the upper one is 999, and the lookup that accepts an uppercase or lowercase
|
||
<code>R</code> key.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/Siemens/SiemensRParameterTableProxy.cs</code> — the matching seedless
|
||
placeholder carried by the Siemens preset alone.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/Heidenhain/HeidenhainQParameterTable.cs</code> — the third table of the same
|
||
shape: the free and permanent Q stores, the ranges each accepts, and the system and volatile ranges
|
||
it deliberately declines.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/Heidenhain/HeidenhainQParameterTableProxy.cs</code> — its placeholder in the
|
||
Heidenhain preset, seedless like the other two.</li>
|
||
<li><code>HiMech/NcParsers/SoftNcRunner.cs</code> — the five brand presets as literal dependency lists, which is
|
||
where the mutual exclusion of the two nodes is actually decided, and the proxy resolution every flag
|
||
probe and every read goes through.</li>
|
||
<li><code>HiMech/NcParsers/NcRunnerSuit.cs</code> — the per-case list these tables live in, and its inline
|
||
serialization beside the runner.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/INcDependencyProxy.cs</code> — the maker-and-taker contract, and why a
|
||
proxy's resolved table is never written into the runner file.</li>
|
||
<li><code>HiMech/NcParsers/ISessionResettable.cs</code> — the session-scoped contract neither table implements, and
|
||
its own statement of the boundary between session state and persistent state.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/IPowerResettable.cs</code> — the volatile-subset contract a power reset
|
||
sweeps, which no dependency of any brand preset declares.</li>
|
||
<li><code>HiMech/NcParsers/LogicSyntaxs/ProgramEndCleanSyntax.cs</code> — the program-end clear that empties the
|
||
block's volatile dictionary and names the retained range as untouched.</li>
|
||
<li><code>HiMech/NcParsers/EvaluationSyntaxs/VolatileVariableReadingSyntax.cs</code> — the <code>#100</code>–<code>#499</code> range that
|
||
has no node here: the per-block dictionary it carries forward, and the session that bounds it.</li>
|
||
<li><code>HiMech/NcParsers/Dependencys/Fanuc/FanucPositionVariableLookup.cs</code> and
|
||
<code>HiMech/NcParsers/EvaluationSyntaxs/Fanuc/FanucSystemControlVariableSyntax.cs</code> — the two <code>#1000</code>-and-up
|
||
groups no dependency answers: the position variables read from the previous block's record, and the
|
||
system-control writes recorded on the block rather than emulated.</li>
|
||
<li><code>HiMech/NcParsers/EvaluationSyntaxs/RetainedCommonVariableReadingSyntax.cs</code> — the run-time writer for
|
||
the retained range: the literal assignment it consumes and writes straight into the table, with no
|
||
mirror kept.</li>
|
||
<li><code>HiMech/NcParsers/EvaluationSyntaxs/Siemens/SiemensRParameterReadingSyntax.cs</code> — the same shape for
|
||
<code>Rn</code> assignments.</li>
|
||
<li><code>HiMech/NcParsers/EvaluationSyntaxs/Heidenhain/HeidenhainQParameterReadingSyntax.cs</code> — the same shape
|
||
for <code>Qn</code> and <code>QRn</code>, routing by id range into the free store, the permanent store, a read-only warning
|
||
or the volatile dataflow.</li>
|
||
<li><code>HiMech/NcParsers/EvaluationSyntaxs/VariableEvaluatorSyntax.cs</code> — the normaliser that resolves a
|
||
non-literal right-hand side to a literal before the reading syntaxes run, and the lookup chain these
|
||
tables join.</li>
|
||
<li><code>HiMech/NcParsers/EvaluationSyntaxs/Evaluation/IVariableLookup.cs</code> and
|
||
<code>HiMech/NcParsers/EvaluationSyntaxs/Evaluation/NcExpressionEvaluator.cs</code> — the lookup contract both
|
||
tables implement, and the vacant failure an expression raises instead of reading zero.</li>
|
||
<li><code>HiMech/NcParsers/Syntaxs/FanucSyntaxUtil.cs</code>,
|
||
<code>HiMech/NcParsers/Syntaxs/SyntecSyntaxUtil.cs</code>,
|
||
<code>HiMech/NcParsers/Syntaxs/MazakSyntaxUtil.cs</code>,
|
||
<code>HiMech/NcParsers/Syntaxs/SiemensSyntaxUtil.cs</code> and
|
||
<code>HiMech/NcParsers/Syntaxs/HeidenhainSyntaxUtil.cs</code> — the five syntax lists, each carrying the reading
|
||
syntax for its brand's persistent variable range.</li>
|
||
<li><code>HiNc/MachiningProcs/LocalProjectService.cs</code> — the facade setter every install and brand switch
|
||
assigns through, and the power reset that sweeps volatile subsets and then drops the session
|
||
dataflow.</li>
|
||
<li><code>HiNc/MachiningProcs/SessionShell.cs</code> — the scriptable power-reset entry point over that service
|
||
call.</li>
|
||
</ul>
|
||
<h2 id="see-also">See Also</h2>
|
||
<ul>
|
||
<li><a class="xref" href="index.html">Program Data Plane</a> — the plane both leaves sit on: where their tables are stored,
|
||
the seedless proxies that make them, and what a brand switch keeps or sweeps beside them</li>
|
||
</ul>
|
||
|
||
</article>
|
||
|
||
<div class="contribution d-print-none">
|
||
</div>
|
||
|
||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||
|
||
</div>
|
||
|
||
<div class="affix">
|
||
<nav id="affix"></nav>
|
||
</div>
|
||
</main>
|
||
|
||
<div class="container-xxl search-results" id="search-results"></div>
|
||
|
||
<footer class="border-top text-secondary">
|
||
<div class="container-xxl">
|
||
<div class="flex-fill">
|
||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
</html>
|