91 lines
3.9 KiB
Markdown
91 lines
3.9 KiB
Markdown
---
|
||
task: Write a Traditional class with prompts, signals built from the object name, and items created from a template
|
||
version: R1.03
|
||
source: IM 36K10P10-01EN §1–§5, §8, §10, §11.2.8; IM 36K10L10-01EN; practiced with CI-Eng-Sample class CIENG_TANK 2026-09-30
|
||
status: verified
|
||
---
|
||
|
||
# Traditional class: prompts, signals, created items
|
||
|
||
Worked example: class `CIENG_TANK` and object `CI-Eng-Sample.TANK1.CALC`
|
||
(`examples/CI-Eng-Sample/06_class_df.qli`, `07_object_df.qli`). Loading and removing: task
|
||
`load-class-object.md`. Language reference: `knowledge/manuals/IM36K10P10-01EN.md`.
|
||
|
||
## 1. Design
|
||
|
||
One class = one kind of equipment; one object per piece of equipment. Put the variable parts
|
||
(which items, which settings) in the **class prolog** so they are fixed when each object is
|
||
created:
|
||
|
||
| Need | Use |
|
||
|---|---|
|
||
| Setting per object, asked at creation | `ATTRIBUTE x OBJECT FLOAT;` + `PROMPT x QUERY "…";` → `ATTR_VALUE_n` in `OBJECT_DF` |
|
||
| Setting shared by all objects | `ATTRIBUTE x CLASS …;` |
|
||
| Existing item next to the object | `SIGNAL s := SECTION || ".<TAG>" TRIGGER VALUE;` |
|
||
| New item per object | `SIGNAL s := FROM "<template item>" MAKE "FIELD" EQUAL value …;` |
|
||
| Refuse bad input | `IF … THEN ERROR "text"; ENDIF;` in the class prolog |
|
||
| Periodic run | trigger group on the class (`TRIGGER_1`) or object |
|
||
| Run on a change | `TRIGGER VALUE` (or STATUS, UPDATE …) on the signal |
|
||
|
||
Template items: keep them in their own section (sample: `CI-Eng-Sample.TEMPLATES.TPL_REAL`)
|
||
and load them before the class.
|
||
|
||
## 2. Example
|
||
|
||
```
|
||
CLASS CIENG_TANK;
|
||
PROLOG
|
||
ATTRIBUTE CAPACITY OBJECT FLOAT;
|
||
PROMPT CAPACITY QUERY "Tank capacity (m3)";
|
||
SIGNAL LEVEL := SECTION || ".LEVEL" TRIGGER VALUE;
|
||
SIGNAL VOLUME := FROM "CI-Eng-Sample.TEMPLATES.TPL_REAL" MAKE
|
||
"DESCRIPTION" EQUAL "Tank volume (m3), class CIENG_TANK";
|
||
IF CAPACITY <= 0 THEN
|
||
ERROR "CIENG_TANK: capacity must be > 0";
|
||
ENDIF;
|
||
BODY
|
||
METHOD CALC;
|
||
BODY
|
||
VOLUME := LEVEL * CAPACITY / 100.0;
|
||
IF LEVEL >=: 80.0 THEN
|
||
PRINT "CIENG_TANK ", SECTION, ": level reached 80 pct, volume ", VOLUME;
|
||
ENDIF;
|
||
ENDMETHOD CALC;
|
||
ENDCLASS CIENG_TANK;
|
||
```
|
||
|
||
Object `CI-Eng-Sample.TANK1.CALC` with `ATTR_VALUE_1` = `"200"`:
|
||
|
||
- `SECTION` = `CI-Eng-Sample.TANK1`, so `LEVEL` → `CI-Eng-Sample.TANK1.LEVEL`.
|
||
- `VOLUME` has no `"NAME"`, so the item is `CI-Eng-Sample.TANK1.CALC.VOLUME`; the section
|
||
`TANK1.CALC` is created too. Both are deleted with the object.
|
||
- `LEVEL` 50 → `VOLUME` 100; 82 → 164.
|
||
- `>=:` prints once when the level **crosses** 80 (message in `umhlog.log`, sender `OPCEXE1`).
|
||
|
||
Rules learned on the test system:
|
||
- Do not put `%` in `PRINT` text: the message is cut at that point (ISS-025).
|
||
- An object at root level has an empty `SECTION`; build names with an `IF` then (release notes).
|
||
- Item names in `SIGNAL` strings must match exactly; an item that does not exist makes the
|
||
object creation fail.
|
||
|
||
## 3. Check and operate
|
||
|
||
- Signals → items: export `OBJECT_SIGNAL_DF` with filter `'OBJECT = "<object>"'`
|
||
(sample: `…CALC:LEVEL` → `CI-Eng-Sample.TANK1.LEVEL`, `…CALC:VOLUME` → `…CALC.VOLUME`).
|
||
- Attribute values: export `OBJECT_ATTR_VAL` (same filter); record name
|
||
`<object>:<attribute>`, field `ATTR_VALUE`.
|
||
- **Change an attribute of a running object** (verified): `dssqld -m` on `OBJECT_ATTR_VAL`:
|
||
```
|
||
@FIELDS
|
||
NAME,ATTR_VALUE
|
||
|
||
@OBJECT_ATTR_VAL
|
||
"CI-Eng-Sample.TANK1.CALC:CAPACITY","400"
|
||
```
|
||
The new value is used from the next run (level 50 → volume 200). Do not change attributes
|
||
that were used to build signal names: the signal keeps its old item (P10 §8.3).
|
||
- Class-wide attributes: `CLASS_ATTR_VAL` (`<class>:<attribute>`), not practiced.
|
||
- Refused object: loading `ATTR_VALUE_1` = `"0"` gave `Errors 1` with
|
||
`OPC-E-INFO, CIENG_TANK: capacity must be > 0` in the `.qlo`; nothing was created.
|
||
|
||
Changing the class source later: task `change-reset-class.md`.
|