String support in SiteManager DCM collector for S7, Modbus and Rockwell
Problem
Some protocols in the DCM suite does not support the datatype String. This have created problems for customers who use S7, Rockwell and Modbus. Most noticably are the customers who use the S7 protocol.
Solution
The proposed workaround aims at keeping the dataflow from SiteManager to DCC as similar to the original flow and still have a valid DCM-configuration. This approach raises additional requirements for the customer to receive strings from protocols where strings is not supported.
Requirements:
Additional DCM-collector
Additional sample points for the ASCII-representation of the string
Notify Inuatek, when such implementation occur.
Step-by-step solution
Ensure that the string can be represented as ASCII and that the DCM can collect the ASCII representation with the following datatypes: byte, uint16, uint32, uint64.
- If the string exceed 8 characters (1 character = 1 byte), additional sample points must be used.
Create the needed sample points in order to represent the string.
NumberOfUint64Samples = ceil(NumberOfCharacters/8)
The (ASCII) sample points must have the same SampleFrequency
Create a new DCM and disable the agent
- Ip-addr. Can be localhost (127.0.0.1)
Setup the collector in the DCM-configuration. The used protocol must be OPC-UA or http/rest.
Setup the sample point based on the chosen protocol.
Ensure that the used datatype is String.
In the description-field input the following: \$string = [\<Collector1>.\<ASCII-Sample1>,\<Collector2>.\<ASCII-Sample2,...,\<CollectorX>.\<ASCII-SampleX>]
Click save configuration.
Example
A user wants to send the MachineID and SW-version to the DCC. Both values are represented as strings on the Siemens PLC, that utilize the S7-protocol.
The format for the strings is as follows:
MachineID: 8 characters in length, first 6 is numbers (0-9), last 2 is capitalized letters (A-Z)
- Example: "123456AB"
SW-version: 8-10 characters in length, first 4 is numbers (0-9), 5 is always a hyphen (-), last is capitalized letters (A-Z)
- Example: "1234-ABC", "4321-ABCD", "2134-ABCDE".
Based on the step-by-step solution:
The user implements in his PLC-program the required methods to divide the MachineID and SW-version, in ASCII-blocks.
MachineID: Two uint32 blocks => 4 chars pr. Uint32.
SW-version: Two uint32 blocks and one uint16 => 4 chars pr. Uint32, 2 chars pr. uint16.
Note: It can be of any sizes (byte or uint16-64), the importance is that the maximum characters in the string can be supported by the blocks.
The user creates the DCM-configuration with the added ASCII-blocks (see DCM-configuration -- ASCII-blocks)
- The user ensures that the Sample interval is the same for the ASCII-blocks representing the machineID and SW-version.
The user creates a new DCM (new agent) and Disables it. The IP-addr for the new agent is localhost (127.0.0.1).
The user adds the new (disabled) collector to the DCM-configuration and adds the MachineID and SW-version strings as sample points (see DCM-configurations -- fake collector).
- In the description-field of the sample points the user adds which sample points (ASCII-blocks) from the dataCollector shall be used. Furthermore, the order in which the ASCII-blocks shall be read are also added correctly.
The user click save configuration
For strings that can change in length (SW-version), is it important to "resets" the values.
Example: If the last sent SW-version is 4321-ABCD -> the last value (D) is used in the uint16 sample point. If the SW-version changes to 1234-ABC, the uint16 sample point needs to be reset to all NULLs, otherwise the value *1234-ABCD* will be read.
What happens behind the lines:
The DCC-backend sees that the DCM-configuration containing the special prefixes ($string...). The backend then knows based on that information, what sample points are used and in what order.
When there is incoming data for that specific machine, the data for the specific ASCII-values are then concatenated + converted into a string-value and written to the string-samplePoint. The ASCII-values are discarded and will therefore not reach the DCC, only the string-samplePoint(s) are saved. But the ASCII values will still be visible on the DCC, since they are a part of the dcm-configuration.
Note: All ASCII values of NULL are removed from the string.
The full DCM-configuration can be seen in DCM-configuration - Full
DCM-configuration -- ASCII blocks
The actual data collector that collects data from a PLC.
{
"CollectorName":"dataCollector",
"ConnectRetryMax":240,
"ConnectRetryMin":2,
"Protocol":"S7/TCP",
"S7Access":{
"S7Model":"S7-1200"
},
"SamplePoints":[
{
"SampleName":"ASCII_MachineID_1",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D1",
"S7SampleInterval":10
}
},
{
"SampleName":"ASCII_MachineID2",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D3",
"S7SampleInterval":10
}
},
{
"SampleName":"ASCII_SWVersion1",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D5",
"S7SampleInterval":5
}
},
{
"SampleName":"ASCII_SWVersion2",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D7",
"S7SampleInterval":5
}
},
{
"SampleName":"ASCII_SWVersion3",
"SampleDataType":"uint16",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500W9",
"S7SampleInterval":5
}
}
]
}
DCM-configuration - fake collector
{
"CollectorDescription":"This collector holds the string sample",
"CollectorName":"stringCollector",
"ConnectRetryMax":240,
"ConnectRetryMin":10,
"OPCUAAccess":{
},
"Protocol":"OPC-UA/TCP",
"SamplePoints":[
{
"OPCUAObject":{
"NodeIdNameSpaceIndex":1,
"NodeIdString":"someIDString",
"NodeIdType":"string",
"OPCUASampleInterval":0
},
"SampleDataType":"string",
"SampleDescription":"$string = [dataCollector.ASCII_machineID1, dataCollector.ASCII_machineID2]",
"SampleName":"MachineID",
"SamplesSaved":0
},
{
"OPCUAObject":{
"NodeIdNameSpaceIndex":1,
"NodeIdString":"someIDString",
"NodeIdType":"string",
"OPCUASampleInterval":0
},
"SampleDataType":"string",
"SampleDescription":"$string = [dataCollector.ASCII_SWVersion1, dataCollector.ASCII_SWVersion2, dataCollector.ASCII_SWVersion3]",
"SampleName":"SW_version",
"SamplesSaved":0
}
]
}
DCM-configuration full
The following example is done with the S7 protocol as the main collector (dataColelctor) and OPC-UA as the collector who holds the string sample:
{
"CollectorName":"dataCollector",
"ConnectRetryMax":240,
"ConnectRetryMin":2,
"Protocol":"S7/TCP",
"S7Access":{
"S7Model":"S7-1200"
},
"SamplePoints":[
{
"SampleName":"ASCII_MachineID_1",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D1",
"S7SampleInterval":10
}
},
{
"SampleName":"ASCII_MachineID2",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D3",
"S7SampleInterval":10
}
},
{
"SampleName":"ASCII_SWVersion1",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D5",
"S7SampleInterval":10
}
},
{
"SampleName":"ASCII_SWVersion2",
"SampleDataType":"uint32",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500D7",
"S7SampleInterval":10
}
},
{
"SampleName":"ASCII_SWVersion3",
"SampleDataType":"uint16",
"SampleUnit":"ASCII",
"SamplesSaved":0,
"S7Var":{
"S7PLCVar":"DB1500W9",
"S7SampleInterval":10
}
}
]
},
{
"CollectorDescription":"This collector holds the string sample",
"CollectorName":"stringCollector",
"ConnectRetryMax":240,
"ConnectRetryMin":10,
"OPCUAAccess":{
},
"Protocol":"OPC-UA/TCP",
"SamplePoints":[
{
"OPCUAObject":{
"NodeIdNameSpaceIndex":1,
"NodeIdString":"someIDString",
"NodeIdType":"string",
"OPCUASampleInterval":0
},
"SampleDataType":"string",
"SampleDescription":"$string = [dataCollector.ASCII_machineID1, dataCollector.ASCII_machineID2]",
"SampleName":"MachineID",
"SamplesSaved":0
},
{
"OPCUAObject":{
"NodeIdNameSpaceIndex":1,
"NodeIdString":"someIDString",
"NodeIdType":"string",
"OPCUASampleInterval":0
},
"SampleDataType":"string",
"SampleDescription":"$string = [dataCollector.ASCII_SWVersion1, dataCollector.ASCII_SWVersion2, dataCollector.ASCII_SWVersion3]",
"SampleName":"SW_version",
"SamplesSaved":0
}
]
}