diff --git a/examples/CI-Eng-Sample/01_section_df.qli b/examples/CI-Eng-Sample/01_section_df.qli index bd48bdd..b8a5ad1 100644 --- a/examples/CI-Eng-Sample/01_section_df.qli +++ b/examples/CI-Eng-Sample/01_section_df.qli @@ -10,6 +10,7 @@ NAME,SECTION_PATH,SECTION_NAME,DESCRIPTION @SECTION_DF "CI-Eng-Sample","","CI-Eng-Sample","CI-Eng-Sample project" +"CI-Eng-Sample.TEMPLATES","CI-Eng-Sample","TEMPLATES","Template items for classes" "CI-Eng-Sample.TANK1","CI-Eng-Sample","TANK1","Sample tank 1" "CI-Eng-Sample.PUMP1","CI-Eng-Sample","PUMP1","Sample pump 1" "CI-Eng-Sample.SYSTEM","CI-Eng-Sample","SYSTEM","Sample system monitoring" diff --git a/examples/CI-Eng-Sample/02_item_df.qli b/examples/CI-Eng-Sample/02_item_df.qli index 8ff1a91..6f78b41 100644 --- a/examples/CI-Eng-Sample/02_item_df.qli +++ b/examples/CI-Eng-Sample/02_item_df.qli @@ -10,6 +10,7 @@ NAME,DESCRIPTION,ITEM_REP,VALUE_FORMAT LOW_LOW_LIMIT,LOW_LIMIT,HIGH_LIMIT,HIGH_HIGH_LIMIT,SCALE_LOW_LIMIT,SCALE_HIGH_LIMIT @ITEM_DF +"CI-Eng-Sample.TEMPLATES.TPL_REAL","Template: internal real item","Real","9999.9",0,0,0,0,0,1000 "CI-Eng-Sample.TANK1.LEVEL","Tank 1 level (%)","Real","999.9",10,20,80,90,0,100 "CI-Eng-Sample.TANK1.INFLOW","Tank 1 inflow (m3/h)","Real","9999.9",0,0,0,0,0,500 "CI-Eng-Sample.PUMP1.RUNNING","Pump 1 running","Boolean","",0,0,0,0,0,0 diff --git a/examples/CI-Eng-Sample/06_class_df.qli b/examples/CI-Eng-Sample/06_class_df.qli index 950b67b..fd08f11 100644 --- a/examples/CI-Eng-Sample/06_class_df.qli +++ b/examples/CI-Eng-Sample/06_class_df.qli @@ -4,8 +4,12 @@ ENGLISH @VERSION 1.03.00 -! CI-Eng-Sample class (traditional language), compiled on load (COMPILE = 1) -! Based on the INCREMENT example in the CI Server Tutorial (IM 36K10G10-01EN 5.2) +! CI-Eng-Sample classes, compiled on load (COMPILE = 1), CI Server R1.03.00 +! CIENG_INCR : traditional, based on the INCREMENT example of the Tutorial (IM 36K10G10-01EN 5.2) +! CIENG_TANK : traditional; prompt/attribute, signal to .LEVEL, item created from +! the template TEMPLATES.TPL_REAL (automatic name .VOLUME), ERROR in the prolog +! CIENG_JFLOW: Java; attaches .INFLOW, creates .sPerMin (automatic name) +! Changing a class that has objects: compile, then reset the class (see skill class-object-engineering). @FIELDS NAME,DESCRIPTION,PF_LANGUAGE,TRIGGER_1,COMPILE,LISTING_WANTED,METHOD @@ -24,3 +28,45 @@ CLASS CIENG_INCR; ENDMETHOD UP_AND_DOWN; ENDCLASS CIENG_INCR; "@ +"CIENG_TANK","Tank volume from level x capacity","Traditional","",1,1,@" +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; +"@ +"CIENG_JFLOW","Inflow per minute (Java)","Java","",1,0,@" +import fasttools.processfast.*; + +public class CIENG_JFLOW extends ProcessClass { + + Signal sInflow = defineDoubleSignal(Signal.Trigger.VALUE); + Signal sPerMin = defineDoubleSignal(); + + public void create() { + attachItemToSignal(sInflow, getSectionsPath() + ".INFLOW"); + createItemForSignal(sPerMin, "CI-Eng-Sample.TEMPLATES.TPL_REAL", + "DESCRIPTION", "Tank inflow (m3/min), class CIENG_JFLOW"); + } + + public void signalEvent(Signal signal) { + double mInflow = sInflow.getValueAsDouble(); + sPerMin.setValue(mInflow / 60.0); + systemMessage("CIENG_JFLOW " + getTag() + ": inflow " + mInflow); + } +} +"@ diff --git a/examples/CI-Eng-Sample/07_object_df.qli b/examples/CI-Eng-Sample/07_object_df.qli index f6d407c..7d7e19a 100644 --- a/examples/CI-Eng-Sample/07_object_df.qli +++ b/examples/CI-Eng-Sample/07_object_df.qli @@ -4,9 +4,12 @@ ENGLISH @VERSION 1.03.00 -! CI-Eng-Sample object created from class CIENG_INCR +! CI-Eng-Sample objects, CI Server R1.03.00 +! ATTR_VALUE_n answers the class's n-th PROMPT (CIENG_TANK: capacity in m3). @FIELDS -NAME,DESCRIPTION,CLASS +NAME,DESCRIPTION,CLASS,ATTR_VALUE_1 @OBJECT_DF -"CI-Eng-Sample.DEMO.INCR1","Counts DEMO.COUNTER every second","CIENG_INCR" +"CI-Eng-Sample.DEMO.INCR1","Counts DEMO.COUNTER every second","CIENG_INCR","" +"CI-Eng-Sample.TANK1.CALC","Tank 1 volume (capacity 200 m3)","CIENG_TANK","200" +"CI-Eng-Sample.TANK1.JFLOW","Tank 1 inflow per minute (Java)","CIENG_JFLOW","" diff --git a/examples/CI-Eng-Sample/86_remove_object_df.qli b/examples/CI-Eng-Sample/86_remove_object_df.qli index cb77b92..34f70e2 100644 --- a/examples/CI-Eng-Sample/86_remove_object_df.qli +++ b/examples/CI-Eng-Sample/86_remove_object_df.qli @@ -10,3 +10,5 @@ NAME @OBJECT_DF "CI-Eng-Sample.DEMO.INCR1" +"CI-Eng-Sample.TANK1.CALC" +"CI-Eng-Sample.TANK1.JFLOW" diff --git a/examples/CI-Eng-Sample/87_remove_class_df.qli b/examples/CI-Eng-Sample/87_remove_class_df.qli index 8ee27d5..0229de9 100644 --- a/examples/CI-Eng-Sample/87_remove_class_df.qli +++ b/examples/CI-Eng-Sample/87_remove_class_df.qli @@ -10,3 +10,5 @@ NAME @CLASS_DF "CIENG_INCR" +"CIENG_TANK" +"CIENG_JFLOW" diff --git a/examples/CI-Eng-Sample/91_remove_item_df.qli b/examples/CI-Eng-Sample/91_remove_item_df.qli index f67e82b..5c33008 100644 --- a/examples/CI-Eng-Sample/91_remove_item_df.qli +++ b/examples/CI-Eng-Sample/91_remove_item_df.qli @@ -19,3 +19,4 @@ NAME "CI-Eng-Sample.SYSTEM.PROC_ALM" "CI-Eng-Sample.DEMO.COUNTER" "CI-Eng-Sample.PLC1.COMM_OK" +"CI-Eng-Sample.TEMPLATES.TPL_REAL" diff --git a/examples/CI-Eng-Sample/92_remove_section_df.qli b/examples/CI-Eng-Sample/92_remove_section_df.qli index 62fed29..7070088 100644 --- a/examples/CI-Eng-Sample/92_remove_section_df.qli +++ b/examples/CI-Eng-Sample/92_remove_section_df.qli @@ -14,4 +14,5 @@ NAME "CI-Eng-Sample.SYSTEM" "CI-Eng-Sample.PLC1" "CI-Eng-Sample.DEMO" +"CI-Eng-Sample.TEMPLATES" "CI-Eng-Sample" diff --git a/examples/CI-Eng-Sample/README.md b/examples/CI-Eng-Sample/README.md index 5212346..dab3942 100644 --- a/examples/CI-Eng-Sample/README.md +++ b/examples/CI-Eng-Sample/README.md @@ -46,6 +46,12 @@ cmd /c "\examples\CI-Eng-Sample\remove.cmd" | `CIENG_1S` | Trigger group | Every second | | `CIENG_INCR` | Class (traditional) | Increments `DEMO.COUNTER`, wraps at 100; compiled on load | | `CI-Eng-Sample.DEMO.INCR1` | Object | Instance of `CIENG_INCR` | +| `CI-Eng-Sample.TEMPLATES` | Section | Template items for classes | +| `CI-Eng-Sample.TEMPLATES.TPL_REAL` | Item, Real | Template for items that objects create (format `9999.9`, scale 0–1000) | +| `CIENG_TANK` | Class (traditional) | Prompt *Tank capacity (m3)*; signal `LEVEL` = `.LEVEL` (trigger on value); creates `.VOLUME` from `TPL_REAL`; volume = level × capacity / 100; logs when the level crosses 80; refuses capacity ≤ 0 | +| `CI-Eng-Sample.TANK1.CALC` | Object | `CIENG_TANK`, capacity 200; creates section `TANK1.CALC` and item `TANK1.CALC.VOLUME` | +| `CIENG_JFLOW` | Class (Java) | Attaches `.INFLOW`; creates `.sPerMin` = inflow / 60; logs each change | +| `CI-Eng-Sample.TANK1.JFLOW` | Object | `CIENG_JFLOW`; creates item `TANK1.JFLOW.sPerMin` (mixed case, as the Java identifier) | | `CIENG_EVENT` | Item storage group | Event/Item, lifetime 1 week, rollover 1 day | | `CI-Eng-Sample.PLC1` | Section | Modbus loopback station | | `CI-Eng-Sample.PLC1.COMM_OK` | Item, Boolean | Status item of station `CIENG_PLC` (1 = communicating, status 22 when off-scan) | @@ -56,6 +62,9 @@ cmd /c "\examples\CI-Eng-Sample\remove.cmd" | `CIENG_SCAN1S` | Modbus scan type | 1000 ms | | `CIENG_VIEWER` | Authorization group | Read-only: `ITEM_READ`, `SECTION_READ`, `ALARM_CURRENT_READ`, `ALARM_CHRONO_READ`. No users are created by the sample. | +Items created by objects (`TANK1.CALC.VOLUME`, `TANK1.JFLOW.sPerMin`) and their sections are +deleted with the objects; they are not in `02_item_df.qli`. + All items except `PLC1.*` are internal (no station). The `PLC1` station talks to CI Server's own Modbus slave mirror (see below), so no PLC is needed either. New items start with status 13 (`NOT INIT`) until a value is written. @@ -68,7 +77,7 @@ New items start with status 13 (`NOT INIT`) until a value is written. | `02b_sub_item_df.qli` | Sub-items (`SUB_ITEM_DF`) | | `03_his_group_df.qli` | Item storage group (`HIS_GROUP_DF`) | | `04_item_his_df.qli` | Items in the storage group (`ITEM_HIS_DF`, name `:`) | -| `05_trigger_df.qli`, `06_class_df.qli`, `07_object_df.qli` | Trigger group, class (source in the `METHOD` memo, `@"` … `"@`, `COMPILE` 1), object | +| `05_trigger_df.qli`, `06_class_df.qli`, `07_object_df.qli` | Trigger group; classes (source in the `METHOD` memo, `@"` … `"@`, `COMPILE` 1; Traditional and Java); objects (`ATTR_VALUE_1` = prompt answer) | | `08_auth_group_df.qli` | Authorization group (`AUTH_GROUP_DF`) | | `09_modbus_line_df.qli`, `10_modbus_station_df.qli`, `11_item_eqp_df.qli` | Modbus line; station, scan type, points; items connected to points | | `equipment/eqpciengslv_start.cmd`, `_stop.cmd` | Start/stop the Modbus slave mirror (copy to `tls\com`) | @@ -103,7 +112,6 @@ testing. See the `system-management` skill, task `monitoring-processes.md`. | Phase | Adds | |---|---| -| 6 | Template items, a class with attributes/prompts, objects that create items | | 8 | Alarm settings on sample items | | 9 | More storage groups (scan/time, aggregation) | | 10 | A display and symbol |