| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| :imagesdir: ../../images/ |
| :icons: font |
| |
| = Setup for testing |
| |
| As we have multiple scenarios regarding, variables, arrays, mutli-dimensional arrays, user-defined types etc. it's some times challenging to come up with a data-structure that can be used to test the various types of access. |
| |
| Therefore, we have started to develop a data-structure, that should cover most main and edge cases and should be a pretty good starting point for testing new drivers on new systems: |
| |
| This setup consists of seveal user-defined types and a main variable block alongside pre-defined reference values. |
| |
| == TSimpleStruct |
| |
| Contains a number of all supported PLC4X datatypes. |
| |
| ---- |
| TYPE "TSimpleStruct" |
| VERSION : 0.1 |
| STRUCT |
| s8 : SInt; |
| u8 : USInt; |
| s16 : Int; |
| u16 : UInt; |
| s32 : DInt; |
| u32 : UDInt; |
| s64 : LInt; |
| u64 : ULInt; |
| b1 : Bool; |
| b8 : Byte; |
| b16 : Word; |
| b32 : DWord; |
| b64 : LWord; |
| r32 : Real; |
| r64 : LReal; |
| tim : Time; |
| ltim : LTime; |
| dat : Date; |
| timoday : Time_Of_Day; |
| dattim {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; |
| str : String[32]; |
| wstr : WString[32]; |
| END_STRUCT; |
| |
| END_TYPE |
| ---- |
| |
| == TSignalPack |
| |
| ---- |
| TYPE "TSignalPack" |
| VERSION : 0.1 |
| STRUCT |
| flags : Array[0..7] of Bool; |
| words : Array[0..3] of Word; |
| payload : Array[0..15] of Byte; |
| END_STRUCT; |
| |
| END_TYPE |
| ---- |
| |
| == TMatrixI16 |
| |
| ---- |
| #TYPE "TMatrixI16" |
| VERSION : 0.1 |
| STRUCT |
| m : Array[1..2, 1..3] of Int; |
| END_STRUCT; |
| |
| END_TYPE |
| ---- |
| |
| == TChannel |
| |
| ---- |
| TYPE "TChannel" |
| VERSION : 0.1 |
| STRUCT |
| id : UDInt; |
| "name" : String[20]; |
| enabled : Bool; |
| setpoints : Array[1..4] of Real; |
| lut : Array[1..2, 1..2, 1..2] of Int; |
| END_STRUCT; |
| |
| END_TYPE |
| ---- |
| |
| == TPlantSnapshot |
| |
| ---- |
| TYPE "TPlantSnapshot" |
| VERSION : 0.1 |
| STRUCT |
| meta { S7_SetPoint := 'False'} : "TSimpleStruct"; |
| gridI16 : "TMatrixI16"; |
| signals : "TSignalPack"; |
| channels : Array[1..2] of "TChannel"; |
| stamps {InstructionName := 'DTL'; LibVersion := '1.0'; S7_SetPoint := 'True'} : Array[1..2] of DTL; |
| tags : Array[1..3] of String[24]; |
| wtags : Array[1..2] of WString[24]; |
| END_STRUCT; |
| |
| END_TYPE |
| ---- |
| |
| == DataBlock |
| |
| ---- |
| DATA_BLOCK "TestData" |
| { S7_Optimized_Access := 'FALSE' } |
| VERSION : 0.1 |
| NON_RETAIN |
| STRUCT |
| g_b1 : Bool; |
| g_b8 : Byte; |
| g_s8 : SInt; |
| g_u8 : USInt; |
| g_b16 : Word; |
| g_s16 : Int; |
| g_u16 : UInt; |
| g_b32 : DWord; |
| g_s32 : DInt; |
| g_u32 : UDInt; |
| g_b64 : LWord; |
| g_s64 : LInt; |
| g_u64 : ULInt; |
| g_r32 : Real; |
| g_r64 : LReal; |
| g_tim : Time; |
| g_dat : Date; |
| g_timoday : Time_Of_Day; |
| g_dattim {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; |
| g_str : String[40]; |
| g_wstr : WString[40]; |
| g_arrBool : Array[1..8] of Bool; |
| g_arrByte : Array[0..7] of Byte; |
| g_arrInt : Array[1..5] of Int; |
| g_arrUInt : Array[1..5] of UInt; |
| g_arrDInt : Array[1..4] of DInt; |
| g_arrUDInt : Array[1..4] of UDInt; |
| g_arrLReal : Array[1..3] of LReal; |
| g_arrTime : Array[1..3] of Time; |
| g_arrString : Array[1..3] of String[16]; |
| g_arrWString : Array[1..2] of WString[16]; |
| g_matI16_2x3 : Array[1..2, 1..3] of Int; |
| g_matR32_3x2 : Array[1..3, 1..2] of Real; |
| g_cubeU16_2x2x2 : Array[1..2, 1..2, 1..2] of UInt; |
| g_simple { S7_SetPoint := 'False'} : "TSimpleStruct"; |
| g_matrixI16 : "TMatrixI16"; |
| g_signals : "TSignalPack"; |
| g_plant : "TPlantSnapshot"; |
| g_chanGrid : Array[1..2, 1..2] of "TChannel"; |
| END_STRUCT; |
| |
| |
| BEGIN |
| g_b1 := true; |
| g_b8 := 16#AB; |
| g_s8 := -12; |
| g_u8 := 250; |
| g_b16 := 16#BEEF; |
| g_s16 := -1234; |
| g_u16 := 54321; |
| g_b32 := 16#DEADBEEF; |
| g_s32 := -12345678; |
| g_u32 := 305419896; |
| g_b64 := 16#0123_4567_89AB_CDEF; |
| g_s64 := -9223372036854770000; |
| g_u64 := 18446744073709551000; |
| g_r32 := 3.14159; |
| g_r64 := 2.71828182845905; |
| g_tim := T#2S500MS; |
| g_dat := D#2025-11-12; |
| g_timoday := TOD#14:33:21.250; |
| g_dattim.YEAR := 2025; |
| g_dattim.MONTH := 11; |
| g_dattim.DAY := 12; |
| g_dattim.WEEKDAY := 4; |
| g_dattim.HOUR := 14; |
| g_dattim.MINUTE := 33; |
| g_dattim.SECOND := 21; |
| g_dattim.NANOSECOND := 500000000; |
| g_dattim := DTL#2025-11-12-14:33:21.500; |
| g_str := 'Hello PLC4X'; |
| g_wstr := WSTRING#'Grüße von PLC4X'; |
| g_arrBool[1] := true; |
| g_arrBool[2] := false; |
| g_arrBool[3] := true; |
| g_arrBool[4] := true; |
| g_arrBool[5] := false; |
| g_arrBool[6] := false; |
| g_arrBool[7] := true; |
| g_arrBool[8] := false; |
| g_arrByte[0] := 16#DE; |
| g_arrByte[1] := 16#AD; |
| g_arrByte[2] := 16#BE; |
| g_arrByte[3] := 16#EF; |
| g_arrByte[4] := 16#12; |
| g_arrByte[5] := 16#34; |
| g_arrByte[6] := 16#56; |
| g_arrByte[7] := 16#78; |
| g_arrInt[1] := -3; |
| g_arrInt[2] := -1; |
| g_arrInt[3] := 0; |
| g_arrInt[4] := 1; |
| g_arrInt[5] := 3; |
| g_arrUInt[1] := 1; |
| g_arrUInt[2] := 10; |
| g_arrUInt[3] := 100; |
| g_arrUInt[4] := 1000; |
| g_arrUInt[5] := 10000; |
| g_arrDInt[1] := -1000; |
| g_arrDInt[2] := 0; |
| g_arrDInt[3] := 1000; |
| g_arrDInt[4] := 2000000; |
| g_arrUDInt[1] := 0; |
| g_arrUDInt[2] := 1; |
| g_arrUDInt[3] := 16#FFFF; |
| g_arrUDInt[4] := 16#12345678; |
| g_arrLReal[1] := 1.5; |
| g_arrLReal[2] := -2.0; |
| g_arrLReal[3] := 0.125; |
| g_arrTime[1] := T#10MS; |
| g_arrTime[2] := T#1S; |
| g_arrTime[3] := T#10S; |
| g_arrString[1] := 'alpha'; |
| g_arrString[2] := 'beta'; |
| g_arrString[3] := 'gamma'; |
| g_arrWString[1] := WSTRING#'Äpfel'; |
| g_arrWString[2] := WSTRING#'Öl'; |
| g_matI16_2x3[1,1] := 10; |
| g_matI16_2x3[1,2] := 11; |
| g_matI16_2x3[1,3] := 12; |
| g_matI16_2x3[2,1] := -10; |
| g_matI16_2x3[2,2] := -11; |
| g_matI16_2x3[2,3] := -12; |
| g_matR32_3x2[1,1] := 1.0; |
| g_matR32_3x2[1,2] := 1.5; |
| g_matR32_3x2[2,1] := 2.0; |
| g_matR32_3x2[2,2] := 2.5; |
| g_matR32_3x2[3,1] := 3.0; |
| g_matR32_3x2[3,2] := 3.5; |
| g_cubeU16_2x2x2[1,1,1] := 1; |
| g_cubeU16_2x2x2[1,1,2] := 2; |
| g_cubeU16_2x2x2[1,2,1] := 3; |
| g_cubeU16_2x2x2[1,2,2] := 4; |
| g_cubeU16_2x2x2[2,1,1] := 5; |
| g_cubeU16_2x2x2[2,1,2] := 6; |
| g_cubeU16_2x2x2[2,2,1] := 7; |
| g_cubeU16_2x2x2[2,2,2] := 8; |
| g_simple.s8 := -8; |
| g_simple.u8 := 200; |
| g_simple.s16 := -1600; |
| g_simple.u16 := 1600; |
| g_simple.s32 := -32000; |
| g_simple.u32 := 32000; |
| g_simple.s64 := -64000; |
| g_simple.u64 := 64000; |
| g_simple.b1 := true; |
| g_simple.b8 := 16#5A; |
| g_simple.b16 := 16#CAFE; |
| g_simple.b32 := 16#C0FFEE00; |
| g_simple.b64 := 16#DEAD_BEEF_F00D_CAFE; |
| g_simple.r32 := 0.5; |
| g_simple.r64 := -0.125; |
| g_simple.tim := T#123ms; |
| g_simple.ltim := LTIME#1S2MS3US; |
| g_simple.dat := D#2025-11-12; |
| g_simple.timoday := TOD#06:07:08.009; |
| g_simple.dattim.YEAR := 2025; |
| g_simple.dattim.MONTH := 11; |
| g_simple.dattim.DAY := 12; |
| g_simple.dattim.WEEKDAY := 4; |
| g_simple.dattim.HOUR := 6; |
| g_simple.dattim.MINUTE := 7; |
| g_simple.dattim.SECOND := 8; |
| g_simple.dattim.NANOSECOND := 9000000; |
| g_simple.dattim := DTL#2025-11-12-06:07:08.009; |
| g_simple.str := 'struct-string'; |
| g_simple.wstr := WSTRING#'Struktur-WSTRING'; |
| g_matrixI16.m[1,1] := 100; |
| g_matrixI16.m[1,2] := 101; |
| g_matrixI16.m[1,3] := 102; |
| g_matrixI16.m[2,1] := 200; |
| g_matrixI16.m[2,2] := 201; |
| g_matrixI16.m[2,3] := 202; |
| g_signals.flags[0] := true; |
| g_signals.flags[1] := false; |
| g_signals.flags[2] := true; |
| g_signals.flags[3] := false; |
| g_signals.flags[4] := true; |
| g_signals.flags[5] := false; |
| g_signals.flags[6] := true; |
| g_signals.flags[7] := false; |
| g_signals.words[0] := 16#1111; |
| g_signals.words[1] := 16#2222; |
| g_signals.words[2] := 16#3333; |
| g_signals.words[3] := 16#4444; |
| g_signals.payload[0] := 16#00; |
| g_signals.payload[1] := 16#11; |
| g_signals.payload[2] := 16#22; |
| g_signals.payload[3] := 16#33; |
| g_signals.payload[4] := 16#44; |
| g_signals.payload[5] := 16#55; |
| g_signals.payload[6] := 16#66; |
| g_signals.payload[7] := 16#77; |
| g_signals.payload[8] := 16#88; |
| g_signals.payload[9] := 16#99; |
| g_signals.payload[10] := 16#AA; |
| g_signals.payload[11] := 16#BB; |
| g_signals.payload[12] := 16#CC; |
| g_signals.payload[13] := 16#DD; |
| g_signals.payload[14] := 16#EE; |
| g_signals.payload[15] := 16#FF; |
| g_plant.meta.s8 := -1; |
| g_plant.meta.u8 := 255; |
| g_plant.meta.s16 := -2; |
| g_plant.meta.u16 := 2; |
| g_plant.meta.s32 := -3; |
| g_plant.meta.u32 := 3; |
| g_plant.meta.s64 := -4; |
| g_plant.meta.u64 := 4; |
| g_plant.meta.b1 := true; |
| g_plant.meta.b8 := 16#AA; |
| g_plant.meta.b16 := 16#ABCD; |
| g_plant.meta.b32 := 16#0102_0304; |
| g_plant.meta.b64 := 16#0A0B_0C0D_0E0F_1011; |
| g_plant.meta.r32 := 12.5; |
| g_plant.meta.r64 := -98.765; |
| g_plant.meta.tim := T#2S; |
| g_plant.meta.ltim := LTIME#2S100MS; |
| g_plant.meta.dat := D#2025-01-01; |
| g_plant.meta.timoday := TOD#12:34:56.789; |
| g_plant.meta.dattim.YEAR := 2025; |
| g_plant.meta.dattim.MONTH := 2; |
| g_plant.meta.dattim.DAY := 3; |
| g_plant.meta.dattim.WEEKDAY := 2; |
| g_plant.meta.dattim.HOUR := 4; |
| g_plant.meta.dattim.MINUTE := 5; |
| g_plant.meta.dattim.SECOND := 6; |
| g_plant.meta.dattim.NANOSECOND := 7000000; |
| g_plant.meta.dattim := DTL#2025-02-03-04:05:06.007; |
| g_plant.meta.str := 'meta-ok'; |
| g_plant.meta.wstr := WSTRING#'Meta-OK'; |
| g_plant.gridI16.m[1,1] := 10; |
| g_plant.gridI16.m[1,2] := 11; |
| g_plant.gridI16.m[1,3] := 12; |
| g_plant.gridI16.m[2,1] := -10; |
| g_plant.gridI16.m[2,2] := -11; |
| g_plant.gridI16.m[2,3] := -12; |
| g_plant.signals.flags[0] := false; |
| g_plant.signals.flags[1] := false; |
| g_plant.signals.flags[2] := true; |
| g_plant.signals.flags[3] := true; |
| g_plant.signals.flags[4] := false; |
| g_plant.signals.flags[5] := true; |
| g_plant.signals.flags[6] := false; |
| g_plant.signals.flags[7] := true; |
| g_plant.signals.words[0] := 16#DEAD; |
| g_plant.signals.words[1] := 16#BEEF; |
| g_plant.signals.words[2] := 16#FEED; |
| g_plant.signals.words[3] := 16#C0DE; |
| g_plant.signals.payload[0] := 16#10; |
| g_plant.signals.payload[1] := 16#20; |
| g_plant.signals.payload[2] := 16#30; |
| g_plant.signals.payload[3] := 16#40; |
| g_plant.signals.payload[4] := 16#50; |
| g_plant.signals.payload[5] := 16#60; |
| g_plant.signals.payload[6] := 16#70; |
| g_plant.signals.payload[7] := 16#80; |
| g_plant.signals.payload[8] := 16#90; |
| g_plant.signals.payload[9] := 16#A0; |
| g_plant.signals.payload[10] := 16#B0; |
| g_plant.signals.payload[11] := 16#C0; |
| g_plant.signals.payload[12] := 16#D0; |
| g_plant.signals.payload[13] := 16#E0; |
| g_plant.signals.payload[14] := 16#F0; |
| g_plant.signals.payload[15] := 16#00; |
| g_plant.channels[1].id := 1; |
| g_plant.channels[1]."name" := 'CH-A'; |
| g_plant.channels[1].enabled := true; |
| g_plant.channels[1].setpoints[1] := 0.0; |
| g_plant.channels[1].setpoints[2] := 10.0; |
| g_plant.channels[1].setpoints[3] := 20.0; |
| g_plant.channels[1].setpoints[4] := 30.0; |
| g_plant.channels[1].lut[1,1,1] := 1; |
| g_plant.channels[1].lut[1,1,2] := 2; |
| g_plant.channels[1].lut[1,2,1] := 3; |
| g_plant.channels[1].lut[1,2,2] := 4; |
| g_plant.channels[1].lut[2,1,1] := -1; |
| g_plant.channels[1].lut[2,1,2] := -2; |
| g_plant.channels[1].lut[2,2,1] := -3; |
| g_plant.channels[1].lut[2,2,2] := -4; |
| g_plant.channels[2].id := 2; |
| g_plant.channels[2]."name" := 'CH-B'; |
| g_plant.channels[2].enabled := false; |
| g_plant.channels[2].setpoints[1] := 5.5; |
| g_plant.channels[2].setpoints[2] := 6.5; |
| g_plant.channels[2].setpoints[3] := 7.5; |
| g_plant.channels[2].setpoints[4] := 8.5; |
| g_plant.channels[2].lut[1,1,1] := 100; |
| g_plant.channels[2].lut[1,1,2] := 101; |
| g_plant.channels[2].lut[1,2,1] := 102; |
| g_plant.channels[2].lut[1,2,2] := 103; |
| g_plant.channels[2].lut[2,1,1] := 200; |
| g_plant.channels[2].lut[2,1,2] := 201; |
| g_plant.channels[2].lut[2,2,1] := 202; |
| g_plant.channels[2].lut[2,2,2] := 203; |
| g_plant.stamps[1] := DTL#2025-06-01-00:00:00; |
| g_plant.stamps[2] := DTL#2025-06-01-12:00:00; |
| g_plant.tags[1] := 'MAIN.speed'; |
| g_plant.tags[2] := 'MAIN.temp'; |
| g_plant.tags[3] := 'MAIN.pressure'; |
| g_plant.wtags[1] := WSTRING#'Δv'; |
| g_plant.wtags[2] := WSTRING#'Ölstand'; |
| g_chanGrid[1,1].id := 10; |
| g_chanGrid[1,1]."name" := 'A1'; |
| g_chanGrid[1,1].enabled := true; |
| g_chanGrid[1,1].setpoints[1] := 11.1; |
| g_chanGrid[1,1].setpoints[2] := 11.2; |
| g_chanGrid[1,1].setpoints[3] := 11.3; |
| g_chanGrid[1,1].setpoints[4] := 11.4; |
| g_chanGrid[1,1].lut[1,1,1] := 1; |
| g_chanGrid[1,1].lut[1,1,2] := 2; |
| g_chanGrid[1,1].lut[1,2,1] := 3; |
| g_chanGrid[1,1].lut[1,2,2] := 4; |
| g_chanGrid[1,1].lut[2,1,1] := 5; |
| g_chanGrid[1,1].lut[2,1,2] := 6; |
| g_chanGrid[1,1].lut[2,2,1] := 7; |
| g_chanGrid[1,1].lut[2,2,2] := 8; |
| g_chanGrid[1,2].id := 11; |
| g_chanGrid[1,2]."name" := 'A2'; |
| g_chanGrid[1,2].enabled := false; |
| g_chanGrid[1,2].setpoints[1] := 12.1; |
| g_chanGrid[1,2].setpoints[2] := 12.2; |
| g_chanGrid[1,2].setpoints[3] := 12.3; |
| g_chanGrid[1,2].setpoints[4] := 12.4; |
| g_chanGrid[1,2].lut[1,1,1] := 10; |
| g_chanGrid[1,2].lut[1,1,2] := 11; |
| g_chanGrid[1,2].lut[1,2,1] := 12; |
| g_chanGrid[1,2].lut[1,2,2] := 13; |
| g_chanGrid[1,2].lut[2,1,1] := 14; |
| g_chanGrid[1,2].lut[2,1,2] := 15; |
| g_chanGrid[1,2].lut[2,2,1] := 16; |
| g_chanGrid[1,2].lut[2,2,2] := 17; |
| g_chanGrid[2,1].id := 20; |
| g_chanGrid[2,1]."name" := 'B1'; |
| g_chanGrid[2,1].enabled := true; |
| g_chanGrid[2,1].setpoints[1] := 21.1; |
| g_chanGrid[2,1].setpoints[2] := 21.2; |
| g_chanGrid[2,1].setpoints[3] := 21.3; |
| g_chanGrid[2,1].setpoints[4] := 21.4; |
| g_chanGrid[2,1].lut[1,1,1] := 21; |
| g_chanGrid[2,1].lut[1,1,2] := 22; |
| g_chanGrid[2,1].lut[1,2,1] := 23; |
| g_chanGrid[2,1].lut[1,2,2] := 24; |
| g_chanGrid[2,1].lut[2,1,1] := 25; |
| g_chanGrid[2,1].lut[2,1,2] := 26; |
| g_chanGrid[2,1].lut[2,2,1] := 27; |
| g_chanGrid[2,1].lut[2,2,2] := 28; |
| g_chanGrid[2,2].id := 21; |
| g_chanGrid[2,2]."name" := 'B2'; |
| g_chanGrid[2,2].enabled := true; |
| g_chanGrid[2,2].setpoints[1] := 22.1; |
| g_chanGrid[2,2].setpoints[2] := 22.2; |
| g_chanGrid[2,2].setpoints[3] := 22.3; |
| g_chanGrid[2,2].setpoints[4] := 22.4; |
| g_chanGrid[2,2].lut[1,1,1] := 31; |
| g_chanGrid[2,2].lut[1,1,2] := 32; |
| g_chanGrid[2,2].lut[1,2,1] := 33; |
| g_chanGrid[2,2].lut[1,2,2] := 34; |
| g_chanGrid[2,2].lut[2,1,1] := 35; |
| g_chanGrid[2,2].lut[2,1,2] := 36; |
| g_chanGrid[2,2].lut[2,2,1] := 37; |
| g_chanGrid[2,2].lut[2,2,2] := 38; |
| |
| END_DATA_BLOCK |
| ---- |
| |
| |