ci-server-engineer/knowledge/manuals/IM36K10P11-01EN.md
cliu bf7d88a027 R1.05 re-check batch 3: alarms, audit, authorization, classes, HAC, reporting, pyTOOLS
Full manual diffs (L15, C20, E30, L25, J40, C10 §2, L10, P10, P11, J20,
C30, P20, R40, E10) and read-only checks on the shared R1.05 test server.
Skills and summaries moved to R1.05; new skill pytools (IM 36K10P40) from
docs (no Python on the test server). Issues ISS-132..181; corrections to
version-differences (E10, E30, P11, dss_ath_grp_u0104); C10 summary lists
the 3 new authorization actions; r105-verification V10-V17.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:21:36 +11:00

11 KiB


manual: IM 36K10P11-01EN title: Class Description Language - Java edition: 4th Edition, Feb. 2026 (first summarized from the 3rd Edition, Sep. 2023) version: R1.05 (first written for R1.03) status: R1.05 re-check 2026-10-09: full word diff (only §10.2 reworded, see below); public API of fasttools.processfast compared with javap (identical to R1.03); JDK version read; CIENG_JFLOW compiled and ran on the R1.05 test server 2026-10-08. From docs; a Java class (attachItemToSignal, createItemForSignal with automatic name, Signal.Trigger.VALUE, signalEvent, systemMessage) compiled on quick load and run on the test system with CI-Eng-Sample class CIENG_JFLOW on 2026-09-30; everything else from docs

Java PROCESS Service language (R1.05)

R1.05 (4th Edition, Feb. 2026): the revision table lists only contact information. The word diff shows that §10.2 (Methods) was rewritten in plainer English with one real correction: createSection() is now described with description, block setting and OPC visibility, without the process areas of the R1.03 text. The examples in §8 (valve, boiler, §8.6 Create Names) still pass five arguments (ISS-154). No other change; section numbers unchanged.

Installed API (checked 2026-10-09, javap -public on tls\exe\jopcsrv.jar): the classes and public methods of fasttools.processfast are identical on R1.03 and R1.05. Facts the manual does not state:

  • createSection(String path, String description, boolean blocked, boolean opcVisible): four arguments on both versions, so the manual's five-argument calls do not match the API (not compile-tested).
  • Methods not described in P11 (ISS-159): getHistory(item, from, to, …) returning ValueSample[] (five overloads), defineIntegerAttributeForPrompt() and defineDoubleAttributeForPrompt() (the manual names only the String version), sendAndReceiveMessage(ServerAddress, Request, Reply, timeout) (BUS messages, package fasttools.processfast.communication), getDssSession() (named in the release notes). Untested.
  • Java runtime: Eclipse Temurin JDK 11.0.28 on R1.05 (11.0.18 on R1.03) in tls\jre; the Java compiler OPCJCOM and the executor run on it (Java 11). Class path of the Java processes: jopcsrv.jar, jtoolsclt.jar, jtoolslibclt.jar, tls\exe\* and, on R1.05, tls\exe\lib\*.
  • New preinstalled Java classes (R1.04+): UAC_MTD_JBASE and UAS_MTD_JBASE, samples for OPC UA method objects (attribute MTD_KEY, signals MTD_TRG, MTD_RET, MTD_IN_ARG_n, MTD_OUT_ARG_n). Described in IM 36K10L45 §10.6 and §11.4, not in P11: see IM36K10L45-01EN.md and skill class-object-engineering, task java-class.md §4.

Summary in own words; section numbers refer to the manual. Engineering: IM36K10L10-01EN.md, skill class-object-engineering. The full API reference is only in the Engineering Module class editor (F1).

1. What Java adds (§1)

Arrays of signals/attributes, loops, inheritance (extends another PROCESS class), any Java library (TCP/IP, files, web services), and signals that need not be attached. Java and Traditional classes cannot contain each other. Compiled by OPCJCOM, created by OPCJACT, run by OPCJEXE (see L10 summary).

2. Class layout (§1.1, §3)

import fasttools.processfast.*;          // the framework; import other packages as usual
public class CIENG_JFLOW extends ProcessClass {   // name = class name in CLASS_DF, exactly
    // definitions: class level only, no public/protected modifiers
    Signal sInflow = defineDoubleSignal(Signal.Trigger.VALUE);
    Signal sPerMin = defineDoubleSignal();
    Attribute aCapacity = defineDoubleAttribute(Attribute.Scope.OBJECT);
    Timer tCheck = defineTimer();

    public void create()  { /* object created: attach or create items */ }
    public void destroy() { /* object deleted (items are detached automatically) */ }
    public void start()   { /* object starts: after create and at every CI Server start */ }
    public void stop()    { /* CI Server stops (not guaranteed, e.g. HA switch) */ }
    public void signalEvent(Signal signal) { }
    public void timerEvent(Timer timer) { }
    public void triggerGroupEvent(TriggerGroup triggerGroup) { }
}

Naming advice: s… signals, a… attributes, t… timers, c… containments, m… locals; identifiers max 15 characters. Omit methods you do not need.

Two environments (§3.4, important): create()/destroy() run in the creation environment (OPCJACT), everything else in the runtime environment (OPCJEXE). Signals have items only at runtime; timers only at runtime; plain Java fields and objects set in create() are gone at runtime — only attributes carry values across. Static fields are not shared between objects of different priorities. Share data through class-scope attributes or items.

3. Signals (§4)

  • defineIntegerSignal(), defineDoubleSignal(), defineStringSignal() (string max 79 characters); …SignalArray(n) or …SignalArray(trigger, n); max 4095 signals per class.
  • Triggers: Signal.Trigger.VALUE | STATUS | OPTION | UPDATE | FIRST | PIT | LIMIT | QUALITY as argument of define…Signal(). Without it the signal never triggers.
  • In create():
    • attachItemToSignal(sig, "<item>") — the item must exist, else creation is cancelled and rolled back.
    • createItemForSignal(sig, "<template>[;<station>:<template point>]", "FIELD", value, …) — any ITEM_DF field; "STORAGE_GROUP", "<group>" followed by ITEM_HIS_DF fields (order matters, max 4 groups); with a point, prefix shared names: "ITEM'DESCRIPTION", "POINT'DESCRIPTION", and use the station's point dataset fields (STATION, IO_ADDRESS …). Sub-items: template must be a sub-item, main item must exist, name required.
    • Without "NAME" the framework names the item <object>.<signal identifier> and creates the sections; the identifier's case is kept (verified: CI-Eng-Sample.TANK1.JFLOW.sPerMin; item names are case-sensitive for itmval). Framework-created items and sections are deleted with the object (verified) unless Leave items is set.
    • createSection(path, description, blocked, opcVisible) creates sections you name yourself (R1.03 manual text and the §8 examples add a process-area argument that the installed API does not have, ISS-154); the framework cannot always undo these — prefer automatic names.
    • Name helpers: getTag(), getSectionsPath(), getSections(), getFullIdentifierPath(x), getContainerIdentifierName(), getContainerIdentifierPath(), getNode().
  • Unattached signals: sig.isAttached(); most methods throw on an unattached signal.
  • Handling: override signalEvent(Signal signal) and compare with ==, or add a named inner class implementing SignalListener in start() (addSignalListener); anonymous listeners compile but fail at start (NoClassDefFoundError in the log).
  • The signal passed to the handler holds the attribute values of the moment of the trigger.
  • Common methods: getValueAsDouble/Integer/String(), getOldValueAs…(), setValue(x), setValueAndStatus(x, Signal.Status.MANUAL), setStatusNumber(Signal.Status.FAILED), limits get/setHighLimit() … (throw when the item has no such limit — catch it), isOffline(), setOffline(), isBlocked(), getQuality(), getUpdateTime(), getValueAsDoubleAndReset() (sub-items), setValueAndTime().
  • Control item: hasControlSignal(), getControlSignal(); blocked control item = triggers ignored.

4. Attributes (§5)

defineIntegerAttribute(scope), defineDoubleAttribute(scope), defineStringAttribute(scope) (string max 255), …AttributeArray(scope, n); scope Attribute.Scope.OBJECT or .CLASS. Prompts: defineStringAttributeForPrompt("Question:") (always OBJECT scope; max 100 prompts); read it in create() and call cancel("message") to refuse the object (rolls back). Attributes survive restarts and are visible in the Engineering Module, but writing them is heavy (disk, and for CLASS scope every runtime) — use them for settings, not process values.

5. Timers and trigger groups (§6, §7)

  • defineTimer() (no arrays; not usable in create()/destroy()); t.start(10) or setTime(10) + start(); setRepeat(true); cancel(); resolution 1 s. Handle in timerEvent() or with a named TimerListener.
  • Trigger groups are assigned in engineering (class or object), not in code; handled in triggerGroupEvent(tg) (tg.getName(), tg.getInterval(), TriggerGroup.Interval.…). Use a trigger group for periodic work, a timer for "check again after a while". ONCE groups are unnecessary: use start().

6. Containment and inheritance (§8, §9)

  • VALVE cGas = (VALVE)defineContainment("VALVE"); — never new VALVE(). Prompts of a contained class become normal attributes: set them in the container's create() (cGas.aStation.setValue(…)).
  • create()/destroy() of contained classes are called automatically after the container's (call(cX).create() to force order); start()/stop() and the …Event() methods are not — call or forward them yourself, or use listeners in the contained class.
  • Inheritance: public class BOILER_MIXER extends BOILER; call super.create(), super.signalEvent(signal) etc.; prompts of the super class are kept. A shared base class (e.g. BASE_CLASS extends ProcessClass) holds helper methods; each subclass loads its own copy (no shared statics). Plain Java code can go in a jar in %TLS_ROOT_PATH%\tls\exe; its classes must have a package name. R1.05 also puts tls\exe\lib\* on the class path of the Java processes (bundled libraries).

7. Runtime behaviour (§10)

  • Keep trigger methods short, never sleep: one object holds up all objects of the same priority (one thread per priority). Give slow objects their own priority, or extra executors per priority range.
  • Exceptions in create() cancel the creation; in a trigger method they abort that trigger and are logged. Use try/catch.
  • systemMessage("text") writes to the message log (umhlog.log, sender OPCJEXE, prefixed with the object name — verified); cancel("text") also stops the current trigger.
  • getStatistics() → processed/lost/queued events, execution times.
  • The manual says a changed class must be compiled and reset, and a new class reset before its first object. On the test system a new class compiled by quick load ran its first object without a reset (ISS-029); after changing a class with objects, reset it (skill task change-reset-class.md).
  • Release notes (IM 36K01A50): Java classes that use datasets must get the session with getDssSession() and never close it.

8. Examples in the manual (Appendix 1)

Valve, boiler (containment), twin boiler, mixer boiler (inheritance), city temperature.