@aryacode/dsh-engineering 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -1
  3. package/cordis.patch.yml +1 -1
  4. package/package.json +1 -1
  5. package/vendor/resources/LICENSE-CONTENT.md +17 -0
  6. package/vendor/resources/SOURCE.json +6 -0
  7. package/vendor/resources/corpus/craft/craft-comments-and-intent.md +29 -0
  8. package/vendor/resources/corpus/craft/craft-debounce-and-filtering.md +29 -0
  9. package/vendor/resources/corpus/craft/craft-fault-handling.md +32 -0
  10. package/vendor/resources/corpus/craft/craft-naming.md +30 -0
  11. package/vendor/resources/corpus/craft/craft-review-checklist.md +29 -0
  12. package/vendor/resources/corpus/craft/craft-units-and-ranges.md +32 -0
  13. package/vendor/resources/corpus/iec/iec-ld-fbd-equivalence.md +31 -0
  14. package/vendor/resources/corpus/iec/iec-sequences-and-sfc.md +32 -0
  15. package/vendor/resources/corpus/iec/iec-st-structure.md +33 -0
  16. package/vendor/resources/corpus/iec/iec-state-machines.md +33 -0
  17. package/vendor/resources/corpus/iec/iec-task-model.md +31 -0
  18. package/vendor/resources/corpus/iec/iec-types-and-scaling.md +32 -0
  19. package/vendor/resources/corpus/optix/optix-alarms-and-trends.md +30 -0
  20. package/vendor/resources/corpus/optix/optix-bindings-and-expressions.md +30 -0
  21. package/vendor/resources/corpus/optix/optix-netlogic-usage.md +29 -0
  22. package/vendor/resources/corpus/optix/optix-ui-structure.md +29 -0
  23. package/vendor/resources/corpus/rockwell/rockwell-aoi-and-udt.md +32 -0
  24. package/vendor/resources/corpus/rockwell/rockwell-fault-and-alarm-words.md +31 -0
  25. package/vendor/resources/corpus/rockwell/rockwell-hmi-handshake.md +33 -0
  26. package/vendor/resources/corpus/rockwell/rockwell-program-structure.md +32 -0
  27. package/vendor/resources/corpus/rockwell/rockwell-safety-boundaries.md +31 -0
  28. package/vendor/resources/corpus/rockwell/rockwell-tag-naming.md +33 -0
  29. package/vendor/resources/corpus/view/view-alarm-presentation.md +32 -0
  30. package/vendor/resources/corpus/view/view-colour-and-contrast.md +31 -0
  31. package/vendor/resources/corpus/view/view-faceplates.md +32 -0
  32. package/vendor/resources/corpus/view/view-hpm-01.md +33 -0
  33. package/vendor/resources/corpus/view/view-navigation.md +31 -0
  34. package/vendor/resources/corpus/view/view-popup-patterns.md +31 -0
  35. package/vendor/resources/corpus/view/view-screen-hierarchy.md +31 -0
  36. package/vendor/resources/corpus/yaskawa/yaskawa-cam-and-gear.md +31 -0
  37. package/vendor/resources/corpus/yaskawa/yaskawa-error-handling.md +31 -0
  38. package/vendor/resources/corpus/yaskawa/yaskawa-motion-function-blocks.md +32 -0
  39. package/vendor/resources/corpus/yaskawa/yaskawa-pou-organisation.md +29 -0
  40. package/vendor/resources/corpus/yaskawa/yaskawa-task-rates.md +30 -0
  41. package/vendor/resources/index.json +873 -0
  42. package/vendor/resources/lib/index.d.ts +15 -17
  43. package/vendor/resources/lib/index.js +29 -42
  44. package/vendor/resources/lib/skill.d.ts +46 -0
  45. package/vendor/resources/lib/skill.js +74 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.2] - 2026-10-27
4
+
5
+ ### Fixed
6
+
7
+ - **The `engineering-standards` skill was missing from the catalog.** 0.9.1 mounted it by calling the skills
8
+ service from inside the resources row's `apply()`, which only works if that service already exists at that
9
+ row's turn — it mounts before the Optix row, so the skill was silently skipped (the tools still loaded).
10
+ The skill is now its own plugin with `inject: ['skills']`, the same pattern the product skills use, so the
11
+ host activates it when the service is up regardless of row order. A test asserts the injection list and
12
+ registration.
13
+ ## [0.9.1] - 2026-10-27
14
+
15
+ ### Fixed
16
+
17
+ - **0.9.0 could stop AryaCode from booting.** The new row was inserted with `id: resources`, and `resources`
18
+ is the name of a harness service other entries wait for; inserting a row under that id displaced the
19
+ provider, so the boot reported `44 entries did not activate` and the application had to start with plugins
20
+ disabled. The row is now `engineering-resources` (namespaced like every other non-product row), and a test
21
+ rejects any future row id that matches a harness service name.
22
+ - **The resources row can no longer break a boot even if it fails.** Its `apply()` wraps registration and
23
+ skill mounting in a guard that reports and continues; a reference surface must never be load-bearing.
24
+ - **The corpus is now actually shipped.** The assembler copied only `lib/` and `SKILL.md`, so the vendored
25
+ package had no `corpus/`, `index.json` or `SOURCE.json` and `engineering_reference` would have failed at
26
+ the first call. `scripts/assemble.mjs` now copies those files, and the packed artifact is checked for them.
3
27
  ## [0.9.0] - 2026-10-27
4
28
 
5
29
  ### Added
package/README.md CHANGED
@@ -69,7 +69,7 @@ down:
69
69
  | `ftview` | FactoryTalk View ME read, guidance and edits; optionally the Studio handoff | `edit` (on), `studio` (on) |
70
70
  | `mwi` | MotionWorks IEC session, reads, verify, guidance and the edits | `workspace` (empty), `edit` (on) |
71
71
  | `viewers` | ladder + ME display previews | — |
72
- | `resources` | the engineering corpus, the house-style profile and the `engineering-standards` skill; no project of its own | `reference` (on) |
72
+ | `engineering-resources` | the engineering corpus, the house-style profile and the `engineering-standards` skill; no project of its own | `reference` (on) |
73
73
  | `optix` | FactoryTalk Optix Studio authoring and the NetLogic reader | `bridgeUrls` (8768), `bridgeToken` (empty), `allowWrites` (on), `allowDestructive` (on), `allowInvoke` (on), `preview` (on), `allowPreviewInput` (on), `cdpUrl`, `previewUrl`, `ocrExecutable` (empty), `ocrLanguage` (`eng`), `ocrTessdataDirectory` (empty), `netlogic` (on) |
74
74
 
75
75
  **Why the row list collapsed.** The Plugins page lists a bundle's rows flat and skips `cordis:group`
package/cordis.patch.yml CHANGED
@@ -42,7 +42,7 @@
42
42
  # Rockwell, Yaskawa, HMI and craft rules), a house-style profile read from the
43
43
  # open project, and the engineering-standards skill that says to read both
44
44
  # before authoring. Disable it in a lean profile; it adds no product row.
45
- - id: resources
45
+ - id: engineering-resources
46
46
  name: '@aryacode/dsh-engineering/resources'
47
47
 
48
48
  # FactoryTalk Optix: vendored like the other three products, so one install
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aryacode/dsh-engineering",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "AryaCode engineering bundle: one install surface for the Studio 5000 L5X, FactoryTalk View ME, MotionWorks IEC and FactoryTalk Optix surfaces, one row per product, with the ladder and display previews.",
5
5
  "keywords": [
6
6
  "dsh",
@@ -0,0 +1,17 @@
1
+ # Content licence
2
+
3
+ The pages under `corpus/` are written for this bundle. They summarise engineering practice and
4
+ implementation rules; they do **not** reproduce the text of any standard or vendor manual.
5
+
6
+ Each page names its basis in front matter (`basis:`). Those names are attribution, not endorsement:
7
+
8
+ - **IEC 61131-3** — the programmable-controller languages the pages describe (ST, LD, FBD, SFC).
9
+ - **ISA-101** — human-machine interface design, especially the high-performance HMI model.
10
+ - **ISA-18.2** — alarm management lifecycle and presentation.
11
+ - **Rockwell / Yaskawa / FactoryTalk** — vendor documentation and field practice for those products.
12
+
13
+ Rule IDs (`CRAFT-NAME-01`, `VIEW-HPM-02`, …) identify this bundle's own rules. They are not the
14
+ standards' clause numbers, and a finding that cites one is this bundle's opinion about your code, not a
15
+ certification.
16
+
17
+ Standards documents are copyrighted. If you need the normative text, obtain it from the issuing body.
@@ -0,0 +1,6 @@
1
+ {
2
+ "corpus": 1,
3
+ "built": "2026-10-27T16:39:24.478Z",
4
+ "digest": "49ea7864020a72c7affc8f13bbc353a21226e63c1d973111e05898a525dd91de",
5
+ "pages": 34
6
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: craft-comments-and-intent
3
+ title: Comments that explain why
4
+ domain: craft
5
+ level: intro
6
+ basis: [field practice]
7
+ tags: [comments, intent]
8
+ applies_to: [l5x, ftview, mwi, optix]
9
+ rules: [CRAFT-COMMENT-01, CRAFT-COMMENT-02, CRAFT-COMMENT-03]
10
+ ---
11
+ ## Principle
12
+
13
+ A comment that repeats the code is noise; a comment that explains the decision is maintenance.
14
+
15
+ ## Rules
16
+
17
+ - **CRAFT-COMMENT-01** Comment the intent and the constraint (`// 250 ms: debounce for a bouncing
18
+ proximity switch`), not the instruction.
19
+ - **CRAFT-COMMENT-02** Every non-obvious rung gets a rung comment; every routine gets one line of purpose.
20
+ - **CRAFT-COMMENT-03** Record the change reason and date where the project does that, and never leave
21
+ commented-out logic as the only record.
22
+
23
+ ## Apply
24
+
25
+ Write the comment as if the reader has the drawing but not the meeting.
26
+
27
+ ## Anti-patterns
28
+
29
+ `// set bit`; a wall of comments at the top that no one updates; TODOs without an owner.
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: craft-debounce-and-filtering
3
+ title: Debounce, hysteresis and filtering
4
+ domain: craft
5
+ level: practitioner
6
+ basis: [field practice]
7
+ tags: [filter, debounce, hysteresis]
8
+ applies_to: [l5x, mwi]
9
+ rules: [CRAFT-FILTER-01, CRAFT-FILTER-02]
10
+ ---
11
+ ## Principle
12
+
13
+ Real sensors are noisy and real processes overshoot. Filter in the PLC with a stated time, not in the
14
+ operator's head.
15
+
16
+ ## Rules
17
+
18
+ - **CRAFT-FILTER-01** Debounce discrete inputs with a timer sized from the sensor's bounce, and document
19
+ the time next to the timer.
20
+ - **CRAFT-FILTER-02** Use hysteresis for thresholds that would otherwise chatter, and keep the band in one
21
+ place per signal.
22
+
23
+ ## Apply
24
+
25
+ When a value "flickers" on the HMI, find the filter time before adding another one downstream.
26
+
27
+ ## Anti-patterns
28
+
29
+ Filters stacked three deep with no owner; a debounce so long it hides a real trip.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: craft-fault-handling
3
+ title: Faults: detect, latch, annunciate, reset
4
+ domain: craft
5
+ level: practitioner
6
+ basis: [field practice]
7
+ tags: [faults, reset, diagnostics]
8
+ applies_to: [l5x, mwi, optix]
9
+ rules: [CRAFT-FAULT-01, CRAFT-FAULT-02, CRAFT-FAULT-03]
10
+ ---
11
+ ## Principle
12
+
13
+ A fault is a fact about the machine, not a message. The logic must detect it, remember it, tell someone,
14
+ and define recovery.
15
+
16
+ ## Rules
17
+
18
+ - **CRAFT-FAULT-01** Detect at the source and set one bit for one cause; do not infer a fault from a
19
+ downstream symptom.
20
+ - **CRAFT-FAULT-02** Latch with a reset that only succeeds when the cause is gone; a reset that always
21
+ clears is a way to run a broken machine.
22
+ - **CRAFT-FAULT-03** Record first-out and the time, and surface it where the operator acts.
23
+
24
+ ## Apply
25
+
26
+ For each fault, write the four sentences: what detects it, what it stops, how it is shown, how it is
27
+ cleared.
28
+
29
+ ## Anti-patterns
30
+
31
+ Faults that clear themselves on the next scan; one reset for unrelated faults; a fault with no operator
32
+ message.
@@ -0,0 +1,30 @@
1
+ ---
2
+ id: craft-naming
3
+ title: Naming that survives the project
4
+ domain: craft
5
+ level: intro
6
+ basis: [field practice]
7
+ tags: [naming, readability]
8
+ applies_to: [l5x, ftview, mwi, optix]
9
+ rules: [CRAFT-NAME-01, CRAFT-NAME-02, CRAFT-NAME-03]
10
+ ---
11
+ ## Principle
12
+
13
+ Names are the interface between the code and everyone who will read it after you.
14
+
15
+ ## Rules
16
+
17
+ - **CRAFT-NAME-01** One case convention per project (PascalCase for tags is common; follow the project).
18
+ Consistency matters more than the choice.
19
+ - **CRAFT-NAME-02** Booleans read as assertions (`MotorRunning`, `DoorClosed`), not as questions or
20
+ negatives (`NotStopped`).
21
+ - **CRAFT-NAME-03** Put units and ranges in the description, not hidden in the name (`Temp_C`, `Speed_mps`).
22
+
23
+ ## Apply
24
+
25
+ When a name does not fit the project's scheme, prefer the project's scheme; when adding a new concept, add
26
+ it to the scheme and document the prefix.
27
+
28
+ ## Anti-patterns
29
+
30
+ `tmp`, `data`, `flag`; names that encode the wiring (`DI_3`); renaming a published tag without a migration.
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: craft-review-checklist
3
+ title: Pre-handover review checklist
4
+ domain: craft
5
+ level: practitioner
6
+ basis: [field practice]
7
+ tags: [review, handover, checklist]
8
+ applies_to: [l5x, ftview, mwi, optix]
9
+ rules: [CRAFT-REVIEW-01, CRAFT-REVIEW-02]
10
+ ---
11
+ ## Principle
12
+
13
+ Handover is a review, not a save. Walk the same list every time, and record what was not checked.
14
+
15
+ ## Rules
16
+
17
+ - **CRAFT-REVIEW-01** Before handover: every fault has a message and a reset, every screen has a way back,
18
+ every changed tag is documented, and the backup is taken and named.
19
+ - **CRAFT-REVIEW-02** Distinguish "checked" from "not checked" in the handover note; an unchecked item is
20
+ not a pass.
21
+
22
+ ## Apply
23
+
24
+ Run the product's own checks first, then `engineering_review`, then the human walkthrough with the
25
+ operator.
26
+
27
+ ## Anti-patterns
28
+
29
+ A handover that lists only what changed; signing off a screen nobody navigated.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: craft-units-and-ranges
3
+ title: Units, ranges and engineering values
4
+ domain: craft
5
+ level: intro
6
+ basis: [field practice]
7
+ tags: [units, range, scaling]
8
+ applies_to: [l5x, mwi, optix]
9
+ rules: [CRAFT-UNIT-01, CRAFT-UNIT-02, CRAFT-UNIT-03]
10
+ ---
11
+ ## Principle
12
+
13
+ Every number the operator sees should have a unit, a range and a resolution. A number without those is a
14
+ guess.
15
+
16
+ ## Rules
17
+
18
+ - **CRAFT-UNIT-01** Carry raw counts and engineering units as separate values with one documented
19
+ conversion.
20
+ - **CRAFT-UNIT-02** State the valid range and what happens outside it (clamp, fault, ignore) at the
21
+ conversion point.
22
+ - **CRAFT-UNIT-03** Display the unit next to the value and keep the decimal places consistent with the
23
+ resolution.
24
+
25
+ ## Apply
26
+
27
+ When a value moves to a new screen, move its unit and range with it.
28
+
29
+ ## Anti-patterns
30
+
31
+ Two conversions for one signal; a percentage displayed as a fraction; more decimal places than the sensor
32
+ has.
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: iec-ld-fbd-equivalence
3
+ title: Ladder, FBD and ST: same logic, different reading
4
+ domain: iec
5
+ level: intro
6
+ basis: [IEC 61131-3]
7
+ tags: [ladder, fbd, st, translation]
8
+ applies_to: [l5x, mwi]
9
+ rules: [IEC-LANG-01, IEC-LANG-02]
10
+ ---
11
+ ## Principle
12
+
13
+ The languages are notations, not designs. Choose the one that makes the intent obvious and keep one
14
+ implementation of each behaviour.
15
+
16
+ ## Rules
17
+
18
+ - **IEC-LANG-01** Ladder for permissives, interlocks and outputs an electrician will trace; ST for
19
+ arithmetic, loops and state machines; FBD for signal flow. Do not translate a whole routine because you
20
+ prefer another language.
21
+ - **IEC-LANG-02** One behaviour, one implementation. A seal-in duplicated in LD and ST will diverge; if a
22
+ block is reused, make it an FB/AOI and call it.
23
+
24
+ ## Apply
25
+
26
+ When reviewing inherited code, read it in its own language before proposing a rewrite. A "modernisation"
27
+ that changes scan-order semantics is a behaviour change.
28
+
29
+ ## Anti-patterns
30
+
31
+ ST one-liners that hide three outputs; ladder with arithmetic chains no one can trace.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: iec-sequences-and-sfc
3
+ title: Sequences, steps and timeouts
4
+ domain: iec
5
+ level: practitioner
6
+ basis: [IEC 61131-3]
7
+ tags: [sequence, sfc, step]
8
+ applies_to: [mwi, l5x]
9
+ rules: [IEC-SEQ-01, IEC-SEQ-02, IEC-SEQ-03]
10
+ ---
11
+ ## Principle
12
+
13
+ A sequence is a state machine whose states are process steps. The difference is that each step has a
14
+ completion condition and a timeout.
15
+
16
+ ## Rules
17
+
18
+ - **IEC-SEQ-01** Give every step a timeout and a defined action on expiry. A sequence that can wait forever
19
+ is a fault waiting for an operator.
20
+ - **IEC-SEQ-02** Separate the step advance from the step action: advance on `done OR timeout`, act on the
21
+ current step.
22
+ - **IEC-SEQ-03** Make hold, abort and reset explicit transitions to named states, not flags that freeze
23
+ the sequence wherever it was.
24
+
25
+ ## Apply
26
+
27
+ Draw the sequence (states and transitions) before coding it, and keep the drawing with the project. SFC is
28
+ appropriate when the drawing is the specification; a `CASE` machine is simpler when steps share actions.
29
+
30
+ ## Anti-patterns
31
+
32
+ Advancing on a timer alone; a reset that clears outputs without leaving the step.
@@ -0,0 +1,33 @@
1
+ ---
2
+ id: iec-st-structure
3
+ title: Structured Text that reads like a specification
4
+ domain: iec
5
+ level: practitioner
6
+ basis: [IEC 61131-3]
7
+ tags: [st, structure, declarations]
8
+ applies_to: [mwi, optix, l5x]
9
+ rules: [IEC-ST-01, IEC-ST-02, IEC-ST-03]
10
+ ---
11
+ ## Principle
12
+
13
+ A POU should be readable top to bottom without scrolling sideways: declarations grouped, one intent per
14
+ block, no hidden state. The reader is a maintenance technician at 2 a.m., not the author.
15
+
16
+ ## Rules
17
+
18
+ - **IEC-ST-01** Group declarations by role (`VAR_INPUT`, `VAR_OUTPUT`, `VAR`), then by purpose, with a
19
+ comment above each group. Do not interleave.
20
+ - **IEC-ST-02** One POU, one responsibility. A POU that sequences, scales, filters and writes HMI data has
21
+ four reasons to change; split it.
22
+ - **IEC-ST-03** No side effects in conditions. A call inside an `IF` that changes state makes the scan
23
+ order part of the logic; call it explicitly, one statement per line.
24
+
25
+ ## Apply
26
+
27
+ Order the body: input conditioning, permissives, sequence or control, outputs, diagnostics. A reader can
28
+ then stop at the block they need.
29
+
30
+ ## Anti-patterns
31
+
32
+ Deeply nested `IF` (three levels or more) hiding permissives; magic numbers instead of named constants;
33
+ declarations added wherever there was space.
@@ -0,0 +1,33 @@
1
+ ---
2
+ id: iec-state-machines
3
+ title: State machines that fail predictably
4
+ domain: iec
5
+ level: practitioner
6
+ basis: [IEC 61131-3]
7
+ tags: [state-machine, case, sequence]
8
+ applies_to: [mwi, l5x]
9
+ rules: [IEC-SM-01, IEC-SM-02, IEC-SM-03]
10
+ ---
11
+ ## Principle
12
+
13
+ A state machine is a contract: exactly one state is active, every transition has a cause, and an
14
+ unexpected state is handled rather than ignored.
15
+
16
+ ## Rules
17
+
18
+ - **IEC-SM-01** Use one integer or enumeration `step` for the active state and a `CASE` (ST) or
19
+ integer-compare chain (LD) to act on it. Do not scatter `IF step =` tests through the program.
20
+ - **IEC-SM-02** Every `CASE` has an `ELSE` (or a default branch) that forces a known safe state and raises
21
+ a diagnostic. An out-of-range step must never leave outputs energised.
22
+ - **IEC-SM-03** Entry actions run once on the transition; continuous actions live in the state body. Mixing
23
+ them makes a re-entry repeat motion.
24
+
25
+ ## Apply
26
+
27
+ Name states after the machine condition (`Idle`, `Homing`, `Ready`, `Cutting`, `Faulted`), not after
28
+ numbers in the HMI. Keep a parallel `stepTime` for timeouts.
29
+
30
+ ## Anti-patterns
31
+
32
+ Two variables claiming to be the state; timers inside the transition condition; a `GOTO` around the
33
+ `CASE`.
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: iec-task-model
3
+ title: Tasks, scan time and determinism
4
+ domain: iec
5
+ level: specialist
6
+ basis: [IEC 61131-3]
7
+ tags: [task, scan, watchdog]
8
+ applies_to: [mwi, l5x]
9
+ rules: [IEC-TASK-01, IEC-TASK-02, IEC-TASK-03]
10
+ ---
11
+ ## Principle
12
+
13
+ The task schedule is part of the program. A control loop that moved to a slower task is a behaviour
14
+ change even when the code is untouched.
15
+
16
+ ## Rules
17
+
18
+ - **IEC-TASK-01** Put motion and fast interlocks in a fixed-rate task; put HMI handshakes and diagnostics in
19
+ a slower one. Document the rate next to the POU.
20
+ - **IEC-TASK-02** No unbounded work in a cyclic task: no file I/O, no waiting loops, no long string
21
+ handling. Bound every loop.
22
+ - **IEC-TASK-03** Size the watchdog from the measured worst case, not the average. A watchdog that fires
23
+ only under load is doing its job.
24
+
25
+ ## Apply
26
+
27
+ Record for each task: period, priority, watchdog, worst measured scan, and what happens when it overruns.
28
+
29
+ ## Anti-patterns
30
+
31
+ Copying a fast task into a slow one and accepting the jitter; hiding a blocking call behind a one-shot.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: iec-types-and-scaling
3
+ title: Types, ranges and scaling without surprises
4
+ domain: iec
5
+ level: practitioner
6
+ basis: [IEC 61131-3]
7
+ tags: [types, scaling, real]
8
+ applies_to: [mwi, l5x, optix]
9
+ rules: [IEC-TYPE-01, IEC-TYPE-02, IEC-TYPE-03]
10
+ ---
11
+ ## Principle
12
+
13
+ Most field faults blamed on "the PLC" are a divide by zero, an overflow, or a REAL compared with `=`.
14
+
15
+ ## Rules
16
+
17
+ - **IEC-TYPE-01** Declare the narrowest type that holds the range, and say the range in the comment
18
+ (`INT 0..1000 mm`). Never rely on the default type.
19
+ - **IEC-TYPE-02** Guard every division and scale: check the divisor, clamp the result, and handle the
20
+ out-of-range case explicitly.
21
+ - **IEC-TYPE-03** Compare REALs with a tolerance, never with equality. For counters and positions, use
22
+ integers where the resolution allows.
23
+
24
+ ## Apply
25
+
26
+ Keep one scale/offset pair per signal, in one place. If two blocks scale the same input, they will
27
+ disagree.
28
+
29
+ ## Anti-patterns
30
+
31
+ `INT` for a millisecond timer that can exceed 32 s; scaling in the HMI and again in the PLC; a REAL used
32
+ as a state number.
@@ -0,0 +1,30 @@
1
+ ---
2
+ id: optix-alarms-and-trends
3
+ title: Alarms and trends in Optix
4
+ domain: optix
5
+ level: practitioner
6
+ basis: [FactoryTalk Optix, ISA-18.2]
7
+ tags: [alarms, trends]
8
+ applies_to: [optix]
9
+ rules: [OPTIX-ALM-01, OPTIX-ALM-02]
10
+ ---
11
+ ## Principle
12
+
13
+ Alarms and trends are process evidence. Their configuration is part of the design, not a runtime
14
+ afterthought.
15
+
16
+ ## Rules
17
+
18
+ - **OPTIX-ALM-01** Configure alarm limits and priorities in the model (type or instance), so every
19
+ instance inherits a reviewed definition.
20
+ - **OPTIX-ALM-02** Choose trend sampling from the process dynamics, and keep the same time base across
21
+ pens that will be compared.
22
+
23
+ ## Apply
24
+
25
+ Review the alarm list as a document: condition, limit, priority, message, action. Trends should answer a
26
+ specific question the operator or engineer has.
27
+
28
+ ## Anti-patterns
29
+
30
+ Alarms enabled per instance with different limits; trend pens on unrelated time bases.
@@ -0,0 +1,30 @@
1
+ ---
2
+ id: optix-bindings-and-expressions
3
+ title: Bindings and expressions
4
+ domain: optix
5
+ level: practitioner
6
+ basis: [FactoryTalk Optix]
7
+ tags: [bindings, expressions, converters]
8
+ applies_to: [optix]
9
+ rules: [OPTIX-BIND-01, OPTIX-BIND-02, OPTIX-BIND-03]
10
+ ---
11
+ ## Principle
12
+
13
+ A binding moves a value; an expression computes one. Mixing them hides where a number comes from.
14
+
15
+ ## Rules
16
+
17
+ - **OPTIX-BIND-01** Bind raw values point to point; put formatting and unit conversion in a formatter or a
18
+ converter with a name, not inline in the binding.
19
+ - **OPTIX-BIND-02** Validate expressions with the expression tool before attaching them, and handle the
20
+ null/empty case explicitly.
21
+ - **OPTIX-BIND-03** Keep one source of truth per value: do not bind and also write the same property from
22
+ NetLogic.
23
+
24
+ ## Apply
25
+
26
+ When a value looks wrong, trace binding → converter → source before editing any of them.
27
+
28
+ ## Anti-patterns
29
+
30
+ Long inline expressions in a property; two writers for one property; conversions that silently round.
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: optix-netlogic-usage
3
+ title: When to use NetLogic
4
+ domain: optix
5
+ level: specialist
6
+ basis: [FactoryTalk Optix]
7
+ tags: [netlogic, csharp]
8
+ applies_to: [optix]
9
+ rules: [OPTIX-NL-01, OPTIX-NL-02]
10
+ ---
11
+ ## Principle
12
+
13
+ NetLogic is C# inside the HMI. Use it for what bindings cannot express, and keep it small enough to test.
14
+
15
+ ## Rules
16
+
17
+ - **OPTIX-NL-01** Prefer bindings and expressions for display logic; use NetLogic for calculations, state
18
+ and integration that must run regardless of the visible screen.
19
+ - **OPTIX-NL-02** Keep NetLogic free of UI lookups where possible: pass values in, return values out, so it
20
+ can be reasoned about without the screen.
21
+
22
+ ## Apply
23
+
24
+ Check the NetLogic cheat-sheet snapshot for the lifecycle and API before writing a new script; the API is
25
+ version-specific.
26
+
27
+ ## Anti-patterns
28
+
29
+ NetLogic that duplicates PLC logic; scripts that block; UI code that reaches into other screens.
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: optix-ui-structure
3
+ title: Optix screens and reusable types
4
+ domain: optix
5
+ level: practitioner
6
+ basis: [FactoryTalk Optix]
7
+ tags: [screens, types, objects]
8
+ applies_to: [optix]
9
+ rules: [OPTIX-UI-01, OPTIX-UI-02]
10
+ ---
11
+ ## Principle
12
+
13
+ Optix is object-oriented: types and instances, not copied panels. The screen is a composition of typed
14
+ objects.
15
+
16
+ ## Rules
17
+
18
+ - **OPTIX-UI-01** Model repeated equipment as a type with instances; screens reference the instance, never
19
+ a copy of its internals.
20
+ - **OPTIX-UI-02** Keep screen composition (layout) separate from behaviour (bindings, NetLogic); a screen
21
+ that computes is harder to reuse.
22
+
23
+ ## Apply
24
+
25
+ Read the type schema before creating objects; the object model decides what a binding can reference.
26
+
27
+ ## Anti-patterns
28
+
29
+ Copy-pasted panels for each device; logic hidden in a display event; a type per device instance.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: rockwell-aoi-and-udt
3
+ title: AOIs and UDTs: reuse without hidden coupling
4
+ domain: rockwell
5
+ level: specialist
6
+ basis: [Rockwell]
7
+ tags: [aoi, udt, reuse]
8
+ applies_to: [l5x]
9
+ rules: [ROCK-AOI-01, ROCK-AOI-02, ROCK-AOI-03]
10
+ ---
11
+ ## Principle
12
+
13
+ An AOI is a contract with every instance of it. Changing one changes the plant; that is the price of reuse
14
+ and it must be deliberate.
15
+
16
+ ## Rules
17
+
18
+ - **ROCK-AOI-01** Use an AOI when the logic repeats three or more times and the interface is stable. Two
19
+ copies are cheaper than a premature abstraction.
20
+ - **ROCK-AOI-02** Put instance state in a UDT member, never in controller-scope globals. Two motors sharing
21
+ a global fault bit is a latent fault.
22
+ - **ROCK-AOI-03** Version behaviour by adding parameters with defaults, not by editing existing pin
23
+ semantics; state the change in the AOI description.
24
+
25
+ ## Apply
26
+
27
+ Document the AOI's states and timing in its description, and keep an instance list. When reviewing, check
28
+ for AOIs with unused pins and for UDTs used as generic bags of tags.
29
+
30
+ ## Anti-patterns
31
+
32
+ AOI with 40 pins; UDT reused for unrelated equipment; logic that depends on the AOI's internal scan order.
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: rockwell-fault-and-alarm-words
3
+ title: Fault and alarm words
4
+ domain: rockwell
5
+ level: practitioner
6
+ basis: [Rockwell]
7
+ tags: [alarms, faults, words]
8
+ applies_to: [l5x, ftview]
9
+ rules: [ROCK-ALM-01, ROCK-ALM-02, ROCK-ALM-03]
10
+ ---
11
+ ## Principle
12
+
13
+ An alarm is an operator decision, not a log entry. Grouping alarms into words is fine; hiding their cause
14
+ is not.
15
+
16
+ ## Rules
17
+
18
+ - **ROCK-ALM-01** One bit per cause, bit numbers fixed and documented; never renumber a published word.
19
+ - **ROCK-ALM-02** Latch the first-out cause and keep it after the condition clears until the operator
20
+ acknowledges. A cleared bit teaches nothing.
21
+ - **ROCK-ALM-03** Separate trip causes from warnings: trips stop equipment, warnings do not. Do not make
22
+ every bit a trip.
23
+
24
+ ## Apply
25
+
26
+ Map each alarm bit to one HMI message and one severity. Check the mapping when an AOI is added.
27
+
28
+ ## Anti-patterns
29
+
30
+ A word where bit 0 means "any fault"; alarms that reset themselves before the scan writes them; alarm text
31
+ that names the block instead of the cause.