Introduction
The Control Center service supports the use of centrally managed resources. A resource is something that is either used when configuring modules in flows, such as OPC UA tag lists or Modbus register mappings, or files that need to be downloaded into the Nodes when deploying flows. File resources can then be accessed from within modules when they run on a Node, for example Python or C# scripts that are imported in the respective code modules, machine learning models that are used inside a code module or a CSV file with static data that is accessed with the CsvReader module. The Resources page in the Control Center web UI is used to manage resources. The main page shows all currently available resources and new resources can be uploaded from here. A resource can be created by uploading a file from local storage, or by entering the information directly in the UI. Some general things to note about resources:
All resources have a name. This name is used when referring to the resource in the UI, e.g. on the main resource page and when selecting the resource for use in a flow. Resources that are downloaded into the Nodes, such as file and script resources, also have a local name. This is the local filename used to refer to the file from inside a module. See below for more details on how this is used for the different resource types.
Once successfully created a resource cannot be changed or removed, it can however be archived. The reason is that an uploaded resource may be used in a flow and changing or removing the resource may have undesirable effects on the running flows.
An archived resource cannot be used when configuring a new flow version. Existing flows that use the resource will still get access though.
Resources can be downloaded to your local computer, e.g. to modify it and upload a new version. There is however a size limitation and files larger than 10MB cannot be downloaded.
Small resources (<1MB) can be viewed in the UI and the content can be copied into a new resource, which is useful for small changes.
Note: You must have permission to manage Resources to be allowed to add resources. However, all users can use the resources when creating flows.
There are two places where resources can be added: In the Flow Studio and on the Resources page.
To add a new resource in the Flow Studio, open the Resources panel using the menu bar along the right side of the screen:
Then click on “ADD RESOURCE” and then on the ‘+’ button. This will open up the Create Resource modal:
When adding a resource inside the Flow Studio it is automatically added to the current Flow.
Alternatively you can add resources on the Resources page by clicking on . This will open the same modal as above.
Fill in the required information and either enter the data in the UI (‘Code’) or upload an existing file.
Resources added on the Resources page must be added to Flows that need them in the Flow Studio, using the Resources panel.
The following sections describe how to create and use the different types of resources.
A file resource is any type of file that is needed locally on a Node, by the flow running on that Node. Examples are machine learning models that are loaded into some ML framework in a PythonBridge module or a CSV file accessed by the CSV Reader module. The system makes no assumptions on format or content of these files, it will just make sure that these files are downloaded to any Node that runs flows that reference these resources. File resources must have a local filename, which can contain a path. A local name can only include alphanumeric characters plus ‘.’, ‘_’, ‘-’ and ‘/’, ie ‘a/b/c/test.csv’ is a valid name, while ‘a/b/c/test 2.csv’ is not. When accessing a file from within a module in a flow, e.g. the CSV Reader, it should be referenced using a base path of ‘data/flowresources/’, ie the file above will be available as ‘data/flowresources/a/b/c/test.csv’.
Python/C# script resources are very similar to file resources, ie they will be downloaded to the Nodes where they are referenced. The Control Center will not validate the content. The difference is that these resources are intended for use in a specific module, namely the PythonBridge and Csharp modules respectively. These modules will find the resources in the predefined location. For example, if a Python resource is uploaded with a local filename/path of ‘mylib.py’, it can be used in the PythonBridge module with a standard ‘import mylib’ statement.
OPC resources are tag lists that can be used when configuring the OPC UA Subscriber and Reader modules, instead of typing each tag in the module UI. When using an OPC resource all the tags in the resource will be used by the OPC UA modules. Any tags entered manually in the UI, or loaded dynamically from a flow message, will be added to the list of tags in the resource file. The format of OPC resources is a JSON array with an object per tag:
[
{
"NodeId": "ns=4;i=1244",
"path": "/4:Boilers/4:Boiler #1/4:PipeX001/4:FTX001/4:Output",
"customType": "tempSensor",
"customScale": 1.5
},
{
...
}
]
The NodeId property is mandatory and should follow the OPC UA syntax for Node IDs.
Any other properties added will be included in the output message for the tag. Custom properties can for example be used to add metadata to allow filtering/grouping of tags in other modules in the flow, or apply per tag specific scaling/conversion parameters that can be used in other modules to change the values.
This format is also used when loading tags dynamically from flow messages and matches the output produced by the OPC UA Browser module. Note though that the output of the OPC UA Browser contains several properties in addition to NodeId and these will be treated as custom properties by the Subscriber and Reader modules. If you don’t want to have these properties in the output they must be removed with a Property Mapper module between the Browser and Subscriber/Reader module.
Modbus resources are used to specify the register mappings for different PLCs. When the resource is used in the Modbus Reader module, all of the listed tags will be retrieved. Additional tags can be added in the module UI. A JSON file is used to define these mappings. Any properties in addition to the default tag properties described below, will be treated as custom metadata and will be added to the messages.
Example Modbus resource:
{
"name": "PLC1",
"unitId": "1",
"tags": [
{
"id": "tag1",
"modbusDataType": "Int",
"modbusFunction": "ReadHoldingRegisters",
"address": "0001"
},
{
"id": "tag2",
"unitId": "2",
"modbusDataType": "Byte",
"modbusFunction": "ReadDiscreteInputs",
"address": "0101"
}
],
"byteOrder": {
"twoByte": "01",
"fourByte": "0123",
"eightByte": "01234567",
"string": "01"
}
}
A Modbus device (PLC) is specified as a JSON object which must have at least a name and at least one tag in the tags list. Optionally the unitId can be specified if something other than the default value of 1 is needed. A tag (register) is defined by the following parameters:
id - Unique name of the tag, will be included in the message.
name - Optional name of the tag, will be included in the message.
modbusDataType - The type of data to read, could be one of Byte, Int, UInt, String, Short, UShort, Float and Double. This setting will affect the number of bytes to read and how they should be interpreted by the module.
modbusFunction - Defines what function code to use (address space), could be one of ReadDiscreteInputs, ReadHoldingRegisters, ReadCoils and ReadInputRegisters.
address - The starting address of the data.
length - Integer (>=1), only used with String types to specify the number of characters to read.
unitId - (optional) Will override the global unitId for this tag/register.
In addition the byteOrder object specifies how to deal with multi-byte data types, such as Short and UShort (twoByte), Int and Float (fourByte), Double (eightByte) and String. Accesses to Modbus registers are always 16 bits/2 bytes, but the byte ordering is not specified (little or big endian). With data types that combine data from multiple registers, e.g. Int, the word ordering also needs to be defined. The byteOrder object is used to add the information needed to convert data from a specific PLC into the corresponding data types by specifying in which order the bytes/words shall be used. The following settings are available:
twoByte - [Default: “01”] How to interpret the two bytes of a single 16-bit register, used by data types such as Short and UShort. Set to "01" for little-endian (LSB stored in bits 0-7) or "10" for big-endian (MSB stored in bits 0-7). For example, the hex value 4F52 is stored as 52 4F in the register if little-endian is used and as 4F 52 if big-endian is used.
fourByte - [Default: “0123”] How to interpret the four bytes of two 16-bit registers, used by data types such as Int and Float. Set to "0123" for little-endian (LSB stored in bits 0-7 of the first 16-bit register) or "3210" for big-endian (MSB stored in bits 0-7 of the first 16-bit register). For example, the hex value 4F5235AB is stored as AB35 524F in the registers if little-endian is used and as 4F52 35AB if big-endian is used.
eightByte - [Default: “01234567”] How to interpret the eight bytes of four 16-bit registers, used by the 64-bit float data type. Set to "01234567" for little-endian (LSB stored in bits 0-7 of the first 16-bit register) or "76543210" for big-endian (MSB stored in bits 0-7 of the first 16-bit register).
string - [Default: “01”] Strings can be of ‘any’ length and hence span several 16-bit registers. This setting specifies how to order the two bytes of a register into two characters. Set to "01" if the PLC uses big-endian ordering and "10" if little-endian is used.
S7 resources are used to specify the register mappings for different Siemens S7 PLCs. When the resource is used in the S7 Reader module, all of the listed tags will be retrieved. Additional tags can be added in the module UI. A JSON file is used to define these mappings. Any properties in addition to the default tag properties described below, will be treated as custom metadata and will be added to the messages.
Example S7 resource:
{
"name": "Conveyor belt controller",
"tags": [
{
"id": "tag1",
"name": "ValveTemp",
"s7DataArea": "Input",
"s7DbAddress": 0,
"s7StartAddress": 0,
"s7Type": "Int",
},
{
"id": "tag2",
"name": "ValveOpen",
"s7DataArea": "Input",
"s7DbAddress": 0,
"s7StartAddress": 2,
"s7BitAddress": 5,
"s7Type": "Bool",
"tagCount": 1,
},
{
"id": "tag3",
"name": "Machine",
"s7DataArea": "DataBlock",
"s7DbAddress": 0,
"s7StartAddress": 10,
"s7Type": "String",
"length": 25,
}
]
A S7 device (PLC) is specified as a JSON object which must have at least a name and at least one tag in the tags list.
A tag (register) is defined by the following parameters:
id - Unique name of the tag, will be included in the message.
name - Optional name of the tag, will be included in the message.
s7DataArea - One of Input, Output, Memory or DataBlock.
s7DbAddress - Integer selecting the Db (only used when s7DataArea is DataBlock).
s7StartAddress - Integer setting the start address within the selected data area
s7BitAddress - Integer (0-7), only used with Bool types to specify the bit to use within the selected byte.
s7Type - The type of data to read, could be one of Bool, Byte, Word, DWord, Char, SInt, Int, DInt, USInt, UInt, UDInt, Real or String. This setting will affect the number of bytes to read and how they should be interpreted by the module.
length - Integer (>=1), only used with String types to specify the number of characters to read.
Rockwell resources are used to specify the register mappings for different Rockwell/Allen Bradley PLCs. When the resource is used in the Rockwell Reader module, all of the listed tags will be retrieved. Additional tags can be added in the module UI. A JSON file is used to define these mappings. Any properties in addition to the default tag properties described below, will be treated as custom metadata and will be added to the messages.
Example Rockwell resource:
{
"name": "Conveyor belt controller",
"tags": [
{
"RockwellTagName": "xyz123",
"RockwellType": "real"
},
{
"RockwellTagName": "xyz123",
"RockwellType": "real",
"name": "ValveTemp",
"scaleFactor": 1.5
}
]
A Rockwell device (PLC) is specified as an object which must have at least one tag in the tags list.
A tag (register) is defined by the following mandatory parameters:
RockwellTagName - The name of the tag, as defined in the PLC, will be included in the message.
RockwellType - Data type of the tag, as defined in the PLC. One of sint, int, dint, lint, real, lreal, bool, string. Will be included in the message.