diff --git a/CHANGELOG.md b/CHANGELOG.md
index 449f8ea..ade7e4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,13 +2,4 @@
All notable changes to this project will be documented in this file.
## Release 0.1.0
-- Initial commit
-
-### New features
-- ...
-
-### Improvements
-- ...
-
-### Bugfix
-- ...
\ No newline at end of file
+- Initial commit
\ No newline at end of file
diff --git a/CSK_Module_Fieldbus/pages/assets/legacy/settings.json b/CSK_Module_Fieldbus/pages/assets/legacy/settings.json
index 939ec2a..a845df1 100644
--- a/CSK_Module_Fieldbus/pages/assets/legacy/settings.json
+++ b/CSK_Module_Fieldbus/pages/assets/legacy/settings.json
@@ -1,3 +1,9 @@
{
-"showLoginButton": false
+ "canChangeLanguage": true,
+ "showLoginButton": false,
+ "defaultLanguage": "en",
+ "disableEditMode": true,
+ "showPageHistory": true,
+ "compactMode": false,
+ "canChangeCompactMode": false
}
\ No newline at end of file
diff --git a/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.css b/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.css
index d215c48..ec7cdb7 100644
--- a/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.css
+++ b/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.css
@@ -5,5 +5,14 @@
margin: 6px;
}
-.myCustomCssClass_CSK_Module_Fieldbus {
+.myCustomMinHeight100p_CSK_Module_Fieldbus {
+ min-height: 100%;
}
+
+.myCustomMarginBottom4px_CSK_Module_Fieldbus {
+ margin-bottom: 4px;
+}
+
+.myCustomRedText_CSK_Module_Fieldbus {
+ color: crimson;
+}
\ No newline at end of file
diff --git a/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.html b/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.html
index 46565ab..b810ed9 100644
--- a/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.html
+++ b/CSK_Module_Fieldbus/pages/pages/CSK_Module_Fieldbus/CSK_Module_Fieldbus.html
@@ -2,85 +2,1728 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Load Config
-
-
-
-
-
-
-
-
- Save Config
-
-
-
-
-
-
-
-
+
+
+
Fieldbus
+
+
+
+
+
+
+ DISABLED
+
+
+ ProfinetIO
+
+
+ EtherNet/IP
+
+
+
+
+
+
+
+
+
+ Set / Restart
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AUTOMATIC_OPEN
+
+
+ EXPLICIT_OPEN
+
+
+
+
+
+
+
+
+
+ Open
+
+
+
+
+
+
+
+
+
+ CONFIRMED_MESSAGING
+
+
+ RAW
+
+
+
+
+
+
+
+
+
+ Close
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ STATIC
+
+
+ BOOTP
+
+
+ DHCP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Get config
+
+
+
+
+
+
+
+
+ Set config
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Remanent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Get DAP IM Data
+
+
+
+
+ Set DAP IM data
+
+
+
+
+ Store DAP I&M data
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Load Config
+
+
+
+
+
+
+
+
+ Save Config
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh ControlBit Status
+
+
+
+
+ WriteCtrlBits
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Data types
+
+ PLC <-> AppSpace
+
+
+ BYTE - U_BYTE / U_INT1 (0 ... 255)
+
+ WORD - U_INT2 (0 ... 65535)
+
+ DWORD - U_INT4 (0 ... 4294967295)
+
+ LWord - U_INT8 (0 ... 18446744073709551615)
+
+
+ SINT - S_INT1 (-128 ... +127)
+
+ INT - S_INT2 (-32768 ... +32767)
+
+ DINT - S_INT4 (-2147483648 ... +2147483647)
+
+ LINT - S_INT8 (-9223372036854775808 ... +9223372036854775807)
+
+
+ USINT - U_BYTE / U_INT1 (0 ... 255)
+
+ UINT - U_INT2 (0 ... 65535)
+
+ UDINT - U_INT4 (0 ... 4294967295)
+
+ ULINT - U_INT8 (0 ... 18446744073709551615)
+
+
+ REAL - FLOAT (-3.402823e+38 ... -1.175495e-38 / +1.175495e-38 ... +3.402823e+38)
+
+ LREAL - DOUBLE (-1.7976931348623158e+308 ... -2.2250738585072014e-308 / +2.2250738585072014e-308 ... +1.7976931348623158e+308)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Convert data
+
+
+
+
+
+
+
+
+ Big Endian
+
+
+
+
+
+
+
+
+
+ CHAR
+
+
+ DOUBLE
+
+
+ FLOAT
+
+
+ S_BYTE
+
+
+ S_INT1
+
+
+ S_INT2
+
+
+ S_INT4
+
+
+ S_INT8
+
+
+ S_LONG
+
+
+ S_SHORT
+
+
+ U_BYTE
+
+
+ U_INT1
+
+
+ U_INT2
+
+
+ U_INT4
+
+
+ U_INT8
+
+
+ U_LONG
+
+
+ U_SHORT
+
+
+
+
+
+
+
+
+
+ Add / Edit
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Up
+
+
+
+
+
+
+ Down
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Set value
+
+
+
+
+
+
+ Reset All
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Data types
+
+ PLC <-> AppSpace
+
+
+ BYTE - U_BYTE / U_INT1 (0 ... 255)
+
+ WORD - U_INT2 (0 ... 65535)
+
+ DWORD - U_INT4 (0 ... 4294967295)
+
+ LWord - U_INT8 (0 ... 18446744073709551615)
+
+
+ SINT - S_INT1 (-128 ... +127)
+
+ INT - S_INT2 (-32768 ... +32767)
+
+ DINT - S_INT4 (-2147483648 ... +2147483647)
+
+ LINT - S_INT8 (-9223372036854775808 ... +9223372036854775807)
+
+
+ USINT - U_BYTE / U_INT1 (0 ... 255)
+
+ UINT - U_INT2 (0 ... 65535)
+
+ UDINT - U_INT4 (0 ... 4294967295)
+
+ ULINT - U_INT8 (0 ... 18446744073709551615)
+
+
+ REAL - FLOAT (-3.402823e+38 ... -1.175495e-38 / +1.175495e-38 ... +3.402823e+38)
+
+ LREAL - DOUBLE (-1.7976931348623158e+308 ... -2.2250738585072014e-308 / +2.2250738585072014e-308 ... +1.7976931348623158e+308)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Convert data
+
+
+
+
+
+
+
+
+ Big Endian
+
+
+
+
+
+
+
+
+
+ CHAR
+
+
+ DOUBLE
+
+
+ FLOAT
+
+
+ S_BYTE
+
+
+ S_INT1
+
+
+ S_INT2
+
+
+ S_INT4
+
+
+ S_INT8
+
+
+ S_LONG
+
+
+ S_SHORT
+
+
+ U_BYTE
+
+
+ U_INT1
+
+
+ U_INT2
+
+
+ U_INT4
+
+
+ U_INT8
+
+
+ U_LONG
+
+
+ U_SHORT
+
+
+
+
+
+
+
+
+
+ Add / Edit
+
+
+
+
+
+
+ Delete
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Up
+
+
+
+
+
+
+ Down
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Each data will be forwarded by a dynamically created event identified by its name like 'CSK_Fieldbus.OnNewData_[NAME]'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -100,7 +1743,5 @@
-
-
diff --git a/CSK_Module_Fieldbus/project.mf.xml b/CSK_Module_Fieldbus/project.mf.xml
index 8c5cdf2..d8fc150 100644
--- a/CSK_Module_Fieldbus/project.mf.xml
+++ b/CSK_Module_Fieldbus/project.mf.xml
@@ -1,79 +1,563 @@
-
-
-
-
- This is an automatically generated CROWN (description not necessary).
-
-
- released
- Please fill in information regarding: What is the idea of this module and its features? +
-How to use this module in general.... like: +
-{empty} +
-Typically the features of this module are used like this (check also main script of this module): +
-**1) Setup** +
-ToDo +
-{empty} +
-**2) Something else...** +
-
-
-
- Notify status if parameters should be loaded on app/device boot up.
-
-
-
- Notify status if features of CSK_PersistendData module are available.
-
-
-
- Event to call if module tried to load parameters and should be ready.
-
-
- Notify name of persistent data parameter.
-
-
-
- Status of Operator userlevel. Used internally in combination with the CSK_UserManagement module if available.
-
-
-
- Status of Maintenance userlevel. Used internally in combination with the CSK_UserManagement module if available.
-
-
-
- Status of Service userlevel. Used internally in combination with the CSK_UserManagement module if available.
-
-
-
- Status of Admin userlevel. Used internally in combination with the CSK_UserManagement module if available.
-
-
-
- Function to set the name of the parameters if saved/loaded via the CSK_PersistentData module.
-
-
-
- Send parameters to CSK_PersistentData module if possible to save them.
-
-
- Load parameters for this module from the CSK_PersistentData module if possible and use them.
-
-
- Configure if this module should load its saved parameters at app/device boot up.
-
-
-
- Function to register "OnResume" of the module UI (only as helper function).
-
-
-
-
- SICK AG
- 0.1.0
- low
- false
- false
- false
- true
-
-
-
+
+
+
+
+ This is an automatically generated CROWN (description not necessary).
+
+
+ released
+ Module to provide fieldbus (Profinet / EtherNet/IP) functionality. +
+This module is helpful to forward data to/from other modules to communicate to a connected PLC. +
+{empty} +
+Typically the features of this module are used like this (check also main script of this module): +
+{empty} +
+**1) Selecte protocol** +
+Select a fieldbus protocol to use via 'setProtocol' and trigger a device reboot to activate the protocol via 'submitProtocol'. +
+After the reboot open the connection via 'openCommunication'. +
+{empty} +
+**2) ControlBits** +
+To read the currently active ControlBits use 'refreshControlBits' and the events 'OnNewStatusControlBitsIn', 'OnNewStatusControlBitsInTable', 'OnNewStatusControlBitsOut', 'OnNewStatusControlBitsOut'. +
+It is possible to set the ControlBitsIn by presetting them via 'setControlBitsIn'/'setSpecificControlBit' and to send them via 'writeControlBitsInViaUI'. +
+To set a bitmask for the ControlBitsIn make use of 'setBitMask' or 'setSpecificBitMaskBit'. +
+{empty} +
+**3) Data to transmit** +
+It is possible to define the data structure and source of the transmitted data. +
+To do this preconfigure the data entry via 'setDataNameTransmit', 'setRegisteredEventTransmit', 'setConvertDataTransmit', 'setBigEndianTransmit', 'setDataTypeTransmit' and after that add this data via 'addDataToTransmitViaUI'. +
+Based on the data received by the configured event (see 'setRegisteredEventTransmit') it will forward this data via fieldbus communication. +
+{empty} +
+**4) Data to receive** +
+It is possible to define the data structure of the data to receive from the PLC. +
+To do this preconfigure the data entry via 'setDataNameReceive', 'setConvertDataReceive', 'setBigEndianReceive', 'setDataTypeReceive' and after that add this data via 'addDataToReceiveViaUI'. +
+The received data values will be provided via dynamically created events (see 'CSK_Fieldbus.OnNewData_DATANAME') and the full data via event 'CSK_Fieldbus.OnNewStatusReceivedData'. +
+
+ Fieldbus protocol.
+ PROFINET
+ EtherNet_IP
+ EtherCAT
+
+
+ Mode for calling Fieldbus 'create' function.
+ EXPLICIT_OPEN
+ AUTOMATIC_OPEN
+
+
+ Fieldbus TransmissionMode
+ RAW
+ CONFIRMED_MESSAGING
+
+
+ Addressing mode for the IP address assignment.
+ DHCP
+ BOOTP
+ STATIC
+
+
+ Types of data to transmit
+ S_INT2
+ S_BYTE
+ U_INT2
+ U_BYTE
+ S_SHORT
+ U_SHORT
+ U_INT1
+ U_INT8
+ U_INT4
+ S_INT1
+ S_INT4
+ U_LONG
+ S_INT8
+ DOUBLE
+ FLOAT
+ S_LONG
+ CHAR
+
+
+
+ Notify status if parameters should be loaded on app/device boot up.
+
+
+
+ Notify status if features of CSK_PersistendData module are available.
+
+
+
+ Event to call if module tried to load parameters and should be ready.
+
+
+ Notify name of persistent data parameter.
+
+
+
+ Status of Operator userlevel. Used internally in combination with the CSK_UserManagement module if available.
+
+
+
+ Status of Maintenance userlevel. Used internally in combination with the CSK_UserManagement module if available.
+
+
+
+ Status of Service userlevel. Used internally in combination with the CSK_UserManagement module if available.
+
+
+
+ Status of Admin userlevel. Used internally in combination with the CSK_UserManagement module if available.
+
+
+
+ Notify current selected fieldbus protocol.
+
+
+
+ Notify if Fieldbus features should be used.
+
+
+
+ Notify fieldbus create mode.
+
+
+
+ Notify fieldbus transmission mode.
+
+
+
+ Notify preset data to be transmitted.
+
+
+
+ Notify preset ControlBitsIn to write.
+
+
+
+ Notify bit mask to use for preset control bits to write.
+
+
+
+ Notify latest ControlBitsOut received from the PLC.
+
+
+
+ Notify status of the fieldbus communication.
+
+
+
+ Notify if fieldbus communication is currently 'OPENED' or 'ONLINE'.
+
+
+
+ Notify info of fieldbus communication.
+
+
+
+ Notify current value of the control bits transmitted to the PLC.
+
+
+
+ Notify addressing mode for EtherNet/IP IP assignment.
+
+
+
+ Notify IP address of EtherNet/IP network.
+
+
+
+ Notfify subnet mask of EtherNet/IP network.
+
+
+
+ Notfify gateway of EtherNet/IP network.
+
+
+
+ Notfify primary name server of EtherNet/IP network.
+
+
+
+ Notfify secondary name server of EtherNet/IP network.
+
+
+
+ Notfify domain name of EtherNet/IP network.
+
+
+
+ Notfify MAC address of specified interface of EtherNet/IP network.
+
+
+
+ Notify name of the device in the Profinet network.
+
+
+
+ Notify IP address of ProfinetIO network.
+
+
+
+ Notfify subnet mask of ProfinetIO network.
+
+
+
+ Notfify gateway of ProfinetIO network.
+
+
+
+ Notfify if the ProfinetIO network configuration tool set the IP address settings permanently.
+
+
+
+ Notfify MAC address of specified interface of ProfinetIO network.
+
+
+
+ Notify descriptor as used for the ProfinetIO DAP’s I&M3 data.
+
+
+
+ Notify hardware revision as used for the DAP used in the I&M0 data.
+
+
+
+ Notify installation date as used for the DAP’s I&M2 data.
+
+
+
+ Notify software revision for the DAP (device access point) used in the I&M0 data.
+
+
+
+ Notify function tag as used for the DAP’s I&M1 data.
+
+
+
+ Notify location tag as used for the DAP’s I&M1 data.
+
+
+
+ Notify currently active fieldbus protocol.
+
+
+
+ Notify if explicit mode is selected.
+
+
+
+ Notify name of event to receive data to transmit.
+
+
+
+ Notify name of preconfigured transmit data.
+
+
+
+ Notify preconfigured status if data needs to be converted to binary before transmission.
+
+
+
+ Notify if big endian should be used to convert data to transmit (otherwise little endian will be used).
+
+
+
+ Notify preconfigured data type of data to transmit.
+
+
+
+ Notify list of data entires to use for data transmission.
+
+
+
+ Notify temporarily set data to transmit on selected data position.
+
+
+
+ Notify fieldbus relevant log message.
+
+
+
+ Notify ControlBitsOut as boolean table.
+
+
+
+ Notify control bits IN as boolean table.
+
+
+
+ Notify bitmask of control bits IN as boolean table.
+
+
+
+ Notfiy received data.
+
+
+
+ Notify name of preconfigured data to receive.
+
+
+
+ Notify list of data entires to use for data receiving.
+
+
+
+ Notify preconfigured status if data needs to be converted to binary after receiving.
+
+
+
+ Notify if big endian should be used to convert received data (otherwise little endian will be used).
+
+
+
+ Notify preconfigured data type of data to receive.
+
+
+
+ Dynamically created event to provide received data from PLC via event. +
+NAME will be replaced by data identifier (e.g. 'CSK_Fieldbus.OnNewData_Data1').
+
+
+
+ Notify info text to restart device.
+
+
+
+ Function to set the name of the parameters if saved/loaded via the CSK_PersistentData module.
+
+
+
+ Send parameters to CSK_PersistentData module if possible to save them.
+
+
+ Load parameters for this module from the CSK_PersistentData module if possible and use them.
+
+
+
+ Configure if this module should load its saved parameters at app/device boot up.
+
+
+
+ Function to register "OnResume" of the module UI (only as helper function).
+
+
+
+ Function to set fiedlbus protocol to use.
+
+
+
+ Function to open fieldbus communication.
+
+
+
+ Function to close fieldbus communication.
+
+
+ Function to refresh data of ControlBitsIn/Out
+
+
+ Function to preset data to transmit.
+
+
+
+ Function to transmit preset data (see 'setDataToTransmit').
+
+
+ Function to preset controlBitsIn to write/transmit to PLC.
+
+
+
+ Function to preset bitmask to use for preset ControlBitsIn to write.
+
+
+
+ Function to write preset ControlBitsIn to the PLC.
+
+
+ Function to set create mode of fieldbus communication.
+
+
+
+ Function to set transmission mode.
+
+
+
+ Function to set preset fieldbus protocol (see 'setProtocol') and restart device.
+
+
+ Function to get EtherNetIP configuration.
+
+
+ Function to setup preconfigured EtherNet/IP config.
+
+
+ Function to set addressing mode of EtherNetIP communication.
+
+
+
+ Function to preset IP for EtherNet/IP communication.
+
+
+
+ Function to preset subnet mask for EtherNet/IP communication.
+
+
+
+ Function to preset gateway for EtherNet/IP communication.
+
+
+
+ Function to preset primary name server for EtherNet/IP communication.
+
+
+
+ Function to preset secondary name server for EtherNet/IP communication.
+
+
+
+ Function to preset domain name for EtherNet/IP communication.
+
+
+
+ Function to preset ProfinetIO device name.
+
+
+
+ Function to preset IP for ProfinetIO communication.
+
+
+
+ Function to preset subnet mask for ProfinetIO communication.
+
+
+
+ Function to preset gateway for ProfinetIO communication.
+
+
+
+ Function to get ProfinetIO configuration.
+
+
+ Function apply ProfinetIO configuration.
+
+
+ Function to store ProfinetIO configuration.
+
+
+ Function to set ProfinetIO DAP IM configuration.
+
+
+ Function to get ProfinetIO DAP IM data.
+
+
+ Function to store ProfinetIO DAP I&M data.
+
+
+ Function to set descriptor for the DAPs I&M3 data.
+
+
+
+ Function to set the installation date for the DAPs I&M2 data.
+
+
+
+ Function to set the function tag for the DAPs I&M1 data.
+
+
+
+ Function to set location tag for the DAPs I&M1 data.
+
+
+
+ Function to set event to receive data to transmit via fieldbus for new/selected data entry.
+
+
+
+ Function to add preconfigured data to transmit.
+
+
+ Function to preconfigure name of data entry to transmit.
+
+
+
+ Function to preconfigure if internally received data (via event) needs to be converted before transmission.
+
+
+
+ Function to preconfigure if data to transmit uses big endianness. Will use little endian per default.
+
+
+
+ Function to preconfigure type of data to convert data before transmission.
+
+
+
+ Function to select transmit data entry in UI.
+
+
+
+ Function to delete preselected data entry.
+
+
+ Function to move the position of the transmit data about one position higher.
+
+
+ Function to move the position of the selected transmit data about one position lower.
+
+
+ Function to set temporarily data of in UI selected data postion to transmit.
+
+
+
+ Function to set preconfigured data to in UI selected data position (see 'setTempTransmitData'). +
+After that it will transmit the full data to the fieldbus.
+
+
+ Function to set specific ControlBitIn (bit range from 0-15).
+
+
+
+ Function to set specific bit of bitmask (bit range from 0-15).
+
+
+
+ Function to preconfigure name of data entry to receive.
+
+
+
+ Function to preconfigure if received data form PLC needs to be converted before transmission.
+
+
+
+ Function to preconfigure if received data uses big endianness. Will use little endian per default.
+
+
+
+ Function to preconfigure type of data to convert received data.
+
+
+
+ Function to add preconfigured data to receive.
+
+
+ Function to delete preselected data entry.
+
+
+ Function to move the position of the selected data to receive about one position lower.
+
+
+ Function to move the position of the data to receive about one position higher.
+
+
+ Function to select data entry in UI.
+
+
+
+ Function to reset all data to transmit.
+
+
+
+ SICK AG
+ 1.0.1
+ low
+ false
+ false
+ false
+ false
+
+
+
diff --git a/CSK_Module_Fieldbus/scripts/CSK_Module_Fieldbus.lua b/CSK_Module_Fieldbus/scripts/CSK_Module_Fieldbus.lua
index ff8b407..97d9e01 100644
--- a/CSK_Module_Fieldbus/scripts/CSK_Module_Fieldbus.lua
+++ b/CSK_Module_Fieldbus/scripts/CSK_Module_Fieldbus.lua
@@ -29,13 +29,13 @@
-- If app property "LuaLoadAllEngineAPI" is FALSE, use this to load and check for required APIs
-- This can improve performance of garbage collection
---_G.availableAPIs = require('Communication/Fieldbus/helper/checkAPIs') -- can be used to adjust function scope of the module related on available APIs of the device
+_G.availableAPIs = require('Communication/Fieldbus/helper/checkAPIs') -- can be used to adjust function scope of the module related on available APIs of the device
-----------------------------------------------------------
-- Logger
_G.logger = Log.SharedLogger.create('ModuleLogger')
_G.logHandle = Log.Handler.create()
_G.logHandle:attachToSharedLogger('ModuleLogger')
-_G.logHandle:setConsoleSinkEnabled(false) --> Set to TRUE if CSK_Logger module is not used
+_G.logHandle:setConsoleSinkEnabled(true) --> Set to TRUE if CSK_Logger module is not used
_G.logHandle:setLevel("ALL")
_G.logHandle:applyConfig()
-----------------------------------------------------------
@@ -62,17 +62,51 @@ local function main()
-- Can be used e.g. like this
----------------------------------------------------------------------------------------
- -- _G.fieldbus_Model.doSomething() -- if you want to start a function
-- ...
CSK_Fieldbus.pageCalled() -- Update UI
-end
-Script.register("Engine.OnStarted", main)
+ --[[
+ CSK_Fieldbus.setDataNameReceive('Data1')
+ CSK_Fieldbus.setDataTypeReceive('U_INT2')
+ CSK_Fieldbus.addDataToReceiveViaUI()
+
+ CSK_Fieldbus.setDataNameReceive('Data2')
+ CSK_Fieldbus.setDataTypeReceive('U_INT4')
+ CSK_Fieldbus.addDataToReceiveViaUI()
+
+ CSK_Fieldbus.setDataTypeTransmit('U_BYTE')
+ for i=1, 6 do
+ CSK_Fieldbus.setDataNameTransmit('Data' ..tostring(i))
+ CSK_Fieldbus.addDataToTransmitViaUI()
+ end
+
+ CSK_Fieldbus.setDataTypeTransmit('S_INT2')
+ for i=7, 10 do
+ CSK_Fieldbus.setDataNameTransmit('Data' ..tostring(i))
+ CSK_Fieldbus.addDataToTransmitViaUI()
+ end
---OR
+ CSK_Fieldbus.setDataTypeTransmit('U_BYTE')
+ for i=11, 18 do
+ CSK_Fieldbus.setDataNameTransmit('Data' ..tostring(i))
+ CSK_Fieldbus.addDataToTransmitViaUI()
+ end
--- Call function after persistent data was loaded
---Script.register("CSK_Fieldbus.OnDataLoadedOnReboot", main)
+ CSK_Fieldbus.setDataTypeTransmit('U_INT8')
+ for i=19, 31 do
+ CSK_Fieldbus.setDataNameTransmit('Data' ..tostring(i))
+ CSK_Fieldbus.addDataToTransmitViaUI()
+ end
+
+ CSK_Fieldbus.setDataTypeTransmit('U_BYTE')
+ for i=32, 33 do
+ CSK_Fieldbus.setDataNameTransmit('Data' ..tostring(i))
+ CSK_Fieldbus.addDataToTransmitViaUI()
+ end
+]]
+
+end
+Script.register("Engine.OnStarted", main)
--**************************************************************************
--**********************End Function Scope *********************************
diff --git a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Controller.lua b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Controller.lua
index 4092e0e..3776f01 100644
--- a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Controller.lua
+++ b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Controller.lua
@@ -15,12 +15,89 @@ local tmrFieldbus = Timer.create()
tmrFieldbus:setExpirationTime(300)
tmrFieldbus:setPeriodic(false)
+-- Timer to wait for other modules to be ready to register to their events
+local tmrWaitForSetupOfOtherModules = Timer.create()
+tmrWaitForSetupOfOtherModules:setExpirationTime(1000)
+tmrWaitForSetupOfOtherModules:setPeriodic(false)
+
-- Reference to global handle
local fieldbus_Model
-- ************************ UI Events Start ********************************
+-- Only to prevent WARNING messages, but these are only examples/placeholders for dynamically created events/functions
+----------------------------------------------------------------
+Script.serveEvent('CSK_Fieldbus.OnNewData_NAME', 'Fieldbus_OnNewData_NAME')
+----------------------------------------------------------------
+
+-- Real events
+--------------------------------------------------
+Script.serveEvent('CSK_Fieldbus.OnNewStatusLogMessage', 'Fieldbus_OnNewStatusLogMessage')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusRestartInfo', 'Fieldbus_OnNewStatusRestartInfo')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusReceivedData', 'Fieldbus_OnNewStatusReceivedData')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusFieldbusActive', 'Fieldbus_OnNewStatusFieldbusActive')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusFieldbusStatus', 'Fieldbus_OnNewStatusFieldbusStatus')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusActiveProtocol', 'Fieldbus_OnNewStatusActiveProtocol')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProtocol', 'Fieldbus_OnNewStatusProtocol')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusFieldbusFeatureActive', 'Fieldbus_OnNewStatusFieldbusFeatureActive')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusFieldbusInfo', 'Fieldbus_OnNewStatusFieldbusInfo')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusCreateMode', 'Fieldbus_OnNewStatusCreateMode')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusExplicitModeActive', 'Fieldbus_OnNewStatusExplicitModeActive')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusTransmissionMode', 'Fieldbus_OnNewStatusTransmissionMode')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusControlBitsIn', 'Fieldbus_OnNewStatusControlBitsIn')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusControlBitsOut', 'Fieldbus_OnNewStatusControlBitsOut')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusControlBitsOutTable', 'Fieldbus_OnNewStatusControlBitsOutTable')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusControlBitsInToWrite', 'Fieldbus_OnNewStatusControlBitsInToWrite')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusControlBitsInTable', 'Fieldbus_OnNewStatusControlBitsInTable')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusBitMask', 'Fieldbus_OnNewStatusBitMask')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusControlBitsInBitMaskTable', 'Fieldbus_OnNewStatusControlBitsInBitMaskTable')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataTransmissionList', 'Fieldbus_OnNewStatusDataTransmissionList')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusRegisteredEventTransmit', 'Fieldbus_OnNewStatusRegisteredEventTransmit')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataNameTransmit', 'Fieldbus_OnNewStatusDataNameTransmit')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusConvertDataTransmit', 'Fieldbus_OnNewStatusConvertDataTransmit')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusBigEndianTransmit', 'Fieldbus_OnNewStatusBigEndianTransmit')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataTypeTransmit', 'Fieldbus_OnNewStatusDataTypeTransmit')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusTempDataTransmit', 'Fieldbus_OnNewStatusTempDataTransmit')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataToTransmit', 'Fieldbus_OnNewStatusDataToTransmit')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataReceivingList', 'Fieldbus_OnNewStatusDataReceivingList')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataNameReceive', 'Fieldbus_OnNewStatusDataNameReceive')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusConvertDataReceive', 'Fieldbus_OnNewStatusConvertDataReceive')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusBigEndianReceive', 'Fieldbus_OnNewStatusBigEndianReceive')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDataTypeReceive', 'Fieldbus_OnNewStatusDataTypeReceive')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPAddressingMode', 'Fieldbus_OnNewStatusEtherNetIPAddressingMode')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPIPAddress', 'Fieldbus_OnNewStatusEtherNetIPIPAddress')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPSubnetMask', 'Fieldbus_OnNewStatusEtherNetIPSubnetMask')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPGateway', 'Fieldbus_OnNewStatusEtherNetIPGateway')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPNameServer', 'Fieldbus_OnNewStatusEtherNetIPNameServer')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPNameServer2', 'Fieldbus_OnNewStatusEtherNetIPNameServer2')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPDomainName', 'Fieldbus_OnNewStatusEtherNetIPDomainName')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusEtherNetIPMACAddress', 'Fieldbus_OnNewStatusEtherNetIPMACAddress')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProfinetIODeviceName', 'Fieldbus_OnNewStatusProfinetIODeviceName')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProfinetIOIPAddress', 'Fieldbus_OnNewStatusProfinetIOIPAddress')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProfinetIOSubnetMask', 'Fieldbus_OnNewStatusProfinetIOSubnetMask')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProfinetIOGateway', 'Fieldbus_OnNewStatusProfinetIOGateway')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProfinetIORemanent', 'Fieldbus_OnNewStatusProfinetIORemanent')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusProfinetIOMACAddress', 'Fieldbus_OnNewStatusProfinetIOMACAddress')
+
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDAPIMDescriptor', 'Fieldbus_OnNewStatusDAPIMDescriptor')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDAPIMHardwareRev', 'Fieldbus_OnNewStatusDAPIMHardwareRev')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDAPIMInstallationDate', 'Fieldbus_OnNewStatusDAPIMInstallationDate')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDAPIMSoftwareRev', 'Fieldbus_OnNewStatusDAPIMSoftwareRev')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDAPIMTagFunction', 'Fieldbus_OnNewStatusDAPIMTagFunction')
+Script.serveEvent('CSK_Fieldbus.OnNewStatusDAPIMTagLocation', 'Fieldbus_OnNewStatusDAPIMTagLocation')
--- Script.serveEvent("CSK_Fieldbus.OnNewEvent", "Fieldbus_OnNewEvent")
Script.serveEvent("CSK_Fieldbus.OnNewStatusLoadParameterOnReboot", "Fieldbus_OnNewStatusLoadParameterOnReboot")
Script.serveEvent("CSK_Fieldbus.OnPersistentDataModuleAvailable", "Fieldbus_OnPersistentDataModuleAvailable")
Script.serveEvent("CSK_Fieldbus.OnNewParameterName", "Fieldbus_OnNewParameterName")
@@ -31,18 +108,7 @@ Script.serveEvent('CSK_Fieldbus.OnUserLevelMaintenanceActive', 'Fieldbus_OnUserL
Script.serveEvent('CSK_Fieldbus.OnUserLevelServiceActive', 'Fieldbus_OnUserLevelServiceActive')
Script.serveEvent('CSK_Fieldbus.OnUserLevelAdminActive', 'Fieldbus_OnUserLevelAdminActive')
--- ...
-
-- ************************ UI Events End **********************************
-
---[[
---- Some internal code docu for local used function
-local function functionName()
- -- Do something
-
-end
-]]
-
--**************************************************************************
--********************** End Global Scope **********************************
--**************************************************************************
@@ -103,17 +169,97 @@ local function updateUserLevel()
end
end
+--TODO not needed?
+--[[
+local function checkExplicitMode()
+ if fieldbus_Model.parameters.createMode == 'EXPLICIT_OPEN' then
+ Script.notifyEvent("Fieldbus_OnNewStatusExplicitModeActive", true)
+ else
+ Script.notifyEvent("Fieldbus_OnNewStatusExplicitModeActive", false)
+ end
+end
+]]
+
--- Function to send all relevant values to UI on resume
local function handleOnExpiredTmrFieldbus()
updateUserLevel()
- -- Script.notifyEvent("Fieldbus_OnNewEvent", false)
+ fieldbus_Model.boolControlBitsToWrite = fieldbus_Model.boolControlBitsOut
+
+ Script.notifyEvent("Fieldbus_OnNewStatusActiveProtocol", fieldbus_Model.fbMode)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusStatus", fieldbus_Model.currentStatus)
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusActive", fieldbus_Model.opened)
+ Script.notifyEvent("Fieldbus_OnNewStatusRestartInfo", '')
+
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.helperFuncs.jsonLine2Table(fieldbus_Model.info))
+ Script.notifyEvent("Fieldbus_OnNewStatusProtocol", fieldbus_Model.parameters.protocol)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusDataTransmissionList", fieldbus_Model.helperFuncs.createJsonListTransmissionData(fieldbus_Model.parameters.dataNamesTransmit, fieldbus_Model.parameters.registeredEventsTransmit, fieldbus_Model.parameters.dataTypesTransmit, fieldbus_Model.parameters.convertDataTypesTransmit, fieldbus_Model.parameters.bigEndiansTransmit, fieldbus_Model.readableDataToTransmit, fieldbus_Model.selectedDataTransmit))
+ Script.notifyEvent("Fieldbus_OnNewStatusDataNameTransmit", fieldbus_Model.dataNameTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusRegisteredEventTransmit", fieldbus_Model.registerEventTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusConvertDataTransmit", fieldbus_Model.convertDataTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusBigEndianTransmit", fieldbus_Model.bigEndianTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusDataTypeTransmit", fieldbus_Model.dataTypeTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusTempDataTransmit", tostring(fieldbus_Model.tempDataTransmit))
+
+ Script.notifyEvent("Fieldbus_OnNewStatusDataReceivingList", fieldbus_Model.helperFuncs.createJsonListReceiveData(fieldbus_Model.parameters.dataNamesReceive, fieldbus_Model.parameters.dataTypesReceive, fieldbus_Model.parameters.convertDataTypesReceive, fieldbus_Model.parameters.bigEndiansReceive, fieldbus_Model.dataReceived, fieldbus_Model.selectedDataReceive))
+ Script.notifyEvent("Fieldbus_OnNewStatusDataNameReceive", fieldbus_Model.dataNameReceive)
+ Script.notifyEvent("Fieldbus_OnNewStatusConvertDataReceive", fieldbus_Model.convertDataReceive)
+ Script.notifyEvent("Fieldbus_OnNewStatusBigEndianReceive", fieldbus_Model.bigEndianReceive)
+ Script.notifyEvent("Fieldbus_OnNewStatusDataTypeReceive", fieldbus_Model.dataTypeReceive)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsIn", fieldbus_Model.controlBitsIn)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsOut", fieldbus_Model.controlBitsOut)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsOutTable", fieldbus_Model.boolControlBitsOut)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInTable", fieldbus_Model.boolControlBitsIn)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInBitMaskTable", fieldbus_Model.boolBitMask)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInToWrite", fieldbus_Model.controlBitsToWrite)
+ Script.notifyEvent("Fieldbus_OnNewStatusBitMask", fieldbus_Model.bitMask)
+
+ if fieldbus_Model.fbMode == 'DISABLED' then
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusFeatureActive", false)
+ else
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusFeatureActive", true)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusCreateMode", fieldbus_Model.parameters.createMode)
+ --checkExplicitMode()
+
+ Script.notifyEvent("Fieldbus_OnNewStatusTransmissionMode", fieldbus_Model.parameters.transmissionMode)
+
+ if fieldbus_Model.fbMode == 'EtherNetIP' then
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPAddressingMode", fieldbus_Model.parameters.etherNetIP.addressingMode)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPIPAddress", fieldbus_Model.parameters.etherNetIP.ipAddress)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPSubnetMask", fieldbus_Model.parameters.etherNetIP.netmask)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPGateway", fieldbus_Model.parameters.etherNetIP.gateway)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPNameServer", fieldbus_Model.parameters.etherNetIP.nameServer)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPNameServer2", fieldbus_Model.parameters.etherNetIP.nameServer2)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPDomainName", fieldbus_Model.parameters.etherNetIP.domainName)
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPMACAddress", fieldbus_Model.parameters.etherNetIP.macAddress)
+
+ elseif fieldbus_Model.fbMode == 'ProfinetIO' then
+ Script.notifyEvent("Fieldbus_OnNewStatusProfinetIODeviceName", fieldbus_Model.parameters.profinetIO.deviceName)
+ Script.notifyEvent("Fieldbus_OnNewStatusProfinetIOIPAddress", fieldbus_Model.parameters.profinetIO.ipAddress)
+ Script.notifyEvent("Fieldbus_OnNewStatusProfinetIOSubnetMask", fieldbus_Model.parameters.profinetIO.netmask)
+ Script.notifyEvent("Fieldbus_OnNewStatusProfinetIOGateway", fieldbus_Model.parameters.profinetIO.gateway)
+ Script.notifyEvent("Fieldbus_OnNewStatusProfinetIORemanent", fieldbus_Model.parameters.profinetIO.remanent)
+ Script.notifyEvent("Fieldbus_OnNewStatusProfinetIOMACAddress", fieldbus_Model.parameters.profinetIO.macAddress)
+
+ Script.notifyEvent("Fieldbus_OnNewStatusDAPIMDescriptor", fieldbus_Model.parameters.profinetIO.dapImDescriptor)
+ Script.notifyEvent("Fieldbus_OnNewStatusDAPIMHardwareRev", fieldbus_Model.parameters.profinetIO.dapImHardwareRev)
+ Script.notifyEvent("Fieldbus_OnNewStatusDAPIMInstallationDate", fieldbus_Model.parameters.profinetIO.dapImInstallDate)
+ Script.notifyEvent("Fieldbus_OnNewStatusDAPIMSoftwareRev", fieldbus_Model.parameters.profinetIO.dapImSoftwareRevPrefix .. '.' .. tostring(fieldbus_Model.parameters.profinetIO.dapImSoftwareRevFuncEnhancement) .. '.' .. tostring(fieldbus_Model.parameters.profinetIO.dapImSoftwareRevBugFix) .. '.' .. tostring(fieldbus_Model.parameters.profinetIO.dapImSoftwareRevInternalChange))
+ Script.notifyEvent("Fieldbus_OnNewStatusDAPIMTagFunction", fieldbus_Model.parameters.profinetIO.dapImTagFunction)
+ Script.notifyEvent("Fieldbus_OnNewStatusDAPIMTagLocation", fieldbus_Model.parameters.profinetIO.dapImTagLocation)
+ end
+ end
Script.notifyEvent("Fieldbus_OnNewStatusLoadParameterOnReboot", fieldbus_Model.parameterLoadOnReboot)
Script.notifyEvent("Fieldbus_OnPersistentDataModuleAvailable", fieldbus_Model.persistentModuleAvailable)
Script.notifyEvent("Fieldbus_OnNewParameterName", fieldbus_Model.parametersName)
- -- ...
end
Timer.register(tmrFieldbus, "OnExpired", handleOnExpiredTmrFieldbus)
@@ -126,20 +272,684 @@ local function pageCalled()
end
Script.serveFunction("CSK_Fieldbus.pageCalled", pageCalled)
---[[
-local function setSomething(value)
- _G.logger:info(nameOfModule .. ": Set new value = " .. value)
- fieldbus_Model.varA = value
+local function setProtocol(protocol)
+ _G.logger:fine(nameOfModule .. ": Set protocol to: " .. tostring(protocol))
+ fieldbus_Model.parameters.protocol = protocol
+ handleOnExpiredTmrFieldbus()
+
+ if (fieldbus_Model.parameters.protocol == 'ProfinetIO' and Parameters.get('FBmode') ~= 1) or (fieldbus_Model.parameters.protocol == 'EtherNetIP' and Parameters.get('FBmode') ~= 2) or (fieldbus_Model.parameters.protocol == 'DISABLED' and Parameters.get('FBmode') ~= 0) then
+ Script.notifyEvent("Fieldbus_OnNewStatusRestartInfo", 'Device restart needed to activate new protocol!')
+ else
+ Script.notifyEvent("Fieldbus_OnNewStatusRestartInfo", '')
+ end
end
-Script.serveFunction("CSK_Fieldbus.setSomething", setSomething)
-]]
+Script.serveFunction('CSK_Fieldbus.setProtocol', setProtocol)
+
+local function restartDevice()
+ Parameters.savePermanent()
+ if CSK_PersistentData then
+ CSK_Fieldbus.sendParameters()
+ end
+ fieldbus_Model.info = "Rebooting the device NOW! Reason: 'Change fieldbus protocol.'"
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ Engine.reboot('Change fieldbus protocol.')
+end
+
+local function submitProtocol()
+ if fieldbus_Model.parameters.protocol == 'ProfinetIO' and Parameters.get('FBmode') ~= 1 then
+ Parameters.set('FBmode', 1)
+ restartDevice()
+ elseif fieldbus_Model.parameters.protocol == 'EtherNetIP' and Parameters.get('FBmode') ~= 2 then
+ Parameters.set('FBmode', 2)
+ restartDevice()
+ elseif fieldbus_Model.parameters.protocol == 'DISABLED' and Parameters.get('FBmode') ~= 0 then
+ Parameters.set('FBmode', 0)
+ restartDevice()
+ end
+end
+Script.serveFunction('CSK_Fieldbus.submitProtocol', submitProtocol)
+
+local function setCreateMode(mode)
+ if fieldbus_Model.currentStatus == 'CLOSED' then
+ fieldbus_Model.parameters.createMode = mode
+ if mode == 'AUTOMATIC_OPEN' then
+ fieldbus_Model.parameters.transmissionMode = 'CONFIRMED_MESSAGING'
+ Script.notifyEvent("Fieldbus_OnNewStatusTransmissionMode", fieldbus_Model.parameters.transmissionMode)
+ end
+ else
+ _G.logger:info("Connection needs to be closed to configure the create mode.")
+ Script.notifyEvent("Fieldbus_OnNewStatusCreateMode", fieldbus_Model.parameters.createMode)
+ end
+ --checkExplicitMode()
+end
+Script.serveFunction('CSK_Fieldbus.setCreateMode', setCreateMode)
+
+local function setTransmissionMode(mode)
+ if fieldbus_Model.parameters.createMode == 'EXPLICIT_OPEN' then
+ fieldbus_Model.setTransmissionMode(mode)
+ else
+ _G.logger:info("Transmission mode only configurable if 'create mode' is 'EXPLICIT_OPEN'.")
+ Script.notifyEvent("Fieldbus_OnNewStatusTransmissionMode", fieldbus_Model.parameters.transmissionMode)
+ fieldbus_Model.info = "Transmission mode only configurable if 'create mode' is 'EXPLICIT_OPEN'."
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ end
+end
+Script.serveFunction('CSK_Fieldbus.setTransmissionMode', setTransmissionMode)
+
+local function openCommunication()
+ local success = false
+ if fieldbus_Model.currentStatus == 'CLOSED' then
+ _G.logger:info(nameOfModule .. ": Open communciation.")
+ success = fieldbus_Model.openCommunication()
+ else
+ _G.logger:fine("Connection already active.")
+ end
+ return success
+end
+Script.serveFunction('CSK_Fieldbus.openCommunication', openCommunication)
+
+local function closeCommunication()
+ _G.logger:info(nameOfModule .. ": Close communication.")
+ fieldbus_Model.closeCommunication()
+
+ fieldbus_Model.info = 'No info available.'
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+end
+Script.serveFunction('CSK_Fieldbus.closeCommunication', closeCommunication)
+
+local function refreshControlBits()
+ fieldbus_Model.readControlBitsIn()
+ fieldbus_Model.readControlBitsOut()
+end
+Script.serveFunction('CSK_Fieldbus.refreshControlBits', refreshControlBits)
+
+local function setDataToTransmit(data)
+ _G.logger:fine(nameOfModule .. ": Set data to transmit to: " .. tostring(data))
+ fieldbus_Model.dataToTransmit = data
+end
+Script.serveFunction('CSK_Fieldbus.setDataToTransmit', setDataToTransmit)
+
+local function transmitViaUI()
+ fieldbus_Model.transmit(fieldbus_Model.dataToTransmit)
+end
+Script.serveFunction('CSK_Fieldbus.transmitViaUI', transmitViaUI)
+
+local function setControlBitsIn(controlBits)
+ _G.logger:fine(nameOfModule .. ": Set controlBits to: " .. tostring(controlBits))
+ fieldbus_Model.controlBitsToWrite = controlBits
+ fieldbus_Model.boolControlBitsToWrite = fieldbus_Model.helperFuncs.toBits(fieldbus_Model.controlBitsToWrite)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInTable", fieldbus_Model.boolControlBitsToWrite)
+end
+Script.serveFunction('CSK_Fieldbus.setControlBitsIn', setControlBitsIn)
+
+local function setSpecificControlBitIn(values)
+ local value = false
+ local pos = tonumber(values[2])
+ if values[1] == 'true' then
+ value = true
+ end
+ if pos then
+ fieldbus_Model.boolControlBitsToWrite[pos+1] = value
+ fieldbus_Model.controlBitsToWrite = fieldbus_Model.helperFuncs.toNumber(fieldbus_Model.boolControlBitsToWrite)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInToWrite", fieldbus_Model.controlBitsToWrite)
+ --print(fieldbus_Model.controlBitsToWrite)
+ end
+end
+Script.serveFunction('CSK_Fieldbus.setSpecificControlBitIn', setSpecificControlBitIn)
+
+local function setBitMask(bitMask)
+ _G.logger:fine(nameOfModule .. ": Set bitMask to: " .. tostring(bitMask))
+ fieldbus_Model.bitMask = bitMask
+ fieldbus_Model.boolBitMask = fieldbus_Model.helperFuncs.toBits(fieldbus_Model.bitMask)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInBitMaskTable", fieldbus_Model.boolBitMask)
+end
+Script.serveFunction('CSK_Fieldbus.setBitMask', setBitMask)
+
+local function setSpecificBitMaskBit(values)
+ local value = false
+ local pos = tonumber(values[2])
+ if values[1] == 'true' then
+ value = true
+ end
+ if pos then
+ fieldbus_Model.boolBitMask[pos+1] = value
+ fieldbus_Model.bitMask = fieldbus_Model.helperFuncs.toNumber(fieldbus_Model.boolBitMask)
+ Script.notifyEvent("Fieldbus_OnNewStatusBitMask", fieldbus_Model.bitMask)
+ --print(fieldbus_Model.bitMask)
+ end
+end
+Script.serveFunction('CSK_Fieldbus.setSpecificBitMaskBit', setSpecificBitMaskBit)
+
+local function writeControlBitsInViaUI()
+ fieldbus_Model.writeControlBitsIn(fieldbus_Model.controlBitsToWrite, fieldbus_Model.bitMask)
+end
+Script.serveFunction('CSK_Fieldbus.writeControlBitsInViaUI', writeControlBitsInViaUI)
+
+local function setAddressingMode(mode)
+ if FieldBus.Config.EtherNetIP.setAddressingMode(mode) then
+ _G.logger:fine(string.format("ENIP: Setting addressing mode to '%s' succeeded", mode))
+ else
+ _G.logger:severe(string.format("ENIP: Setting addressing mode to '%s' failed", mode))
+ end
+ fieldbus_Model.parameters.etherNetIP.addressingMode = mode
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPAddressingMode", fieldbus_Model.parameters.etherNetIP.addressingMode)
+ fieldbus_Model.getInfo()
+end
+Script.serveFunction('CSK_Fieldbus.setAddressingMode', setAddressingMode)
+
+local function setEtherNetIPIP(ip)
+ if ip ~= "0.0.0.0" then
+ -- Convert IPs and netmask to numbers
+ local a, b, c, d = ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local ipNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.netmask:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local nmNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.gateway:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local gwNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+
+ -- Perform bitwise AND between IP address and netmask to get the network address
+ local networkAddress = ipNum & nmNum
+ local gwNetworkAddress = gwNum & nmNum
+
+ -- Check if IP address and gateway are in the same network
+ if networkAddress == gwNetworkAddress then
+ _G.logger:fine(nameOfModule .. ": Preset EtherNet/IP IP to: " .. tostring(ip))
+ else
+ _G.logger:fine(nameOfModule .. ": Store old valid EtherNet/IP IP address since current preset IP address is out of range with Gw address.")
+ fieldbus_Model.parameters.etherNetIP.ipAddress2 = fieldbus_Model.parameters.etherNetIP.ipAddress
+ end
+ fieldbus_Model.parameters.etherNetIP.ipAddress = ip
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPIPAddress", fieldbus_Model.parameters.etherNetIP.ipAddress)
+else
+ _G.logger:warning(nameOfModule .. ": Can't set EtherNet/IP IP address to '0.0.0.0'")
+ fieldbus_Model.info ="Can't set EtherNet/IP IP to '0.0.0.0'"
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ end
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPIPAddress", fieldbus_Model.parameters.etherNetIP.ipAddress)
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPIP', setEtherNetIPIP)
+
+local function setEtherNetIPSubnetMask(netmask)
+ if netmask ~= "0.0.0.0" then
+ -- Convert IPs and netmask to numbers
+ local a, b, c, d = fieldbus_Model.parameters.etherNetIP.ipAddress:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local ipNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = netmask:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local nmNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.gateway:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local gwNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+
+ -- Perform bitwise AND between IP address and netmask to get the network address
+ local networkAddress = ipNum & nmNum
+ local gwNetworkAddress = gwNum & nmNum
+
+ -- Check if IP address and gateway are in the same network
+ if networkAddress == gwNetworkAddress then
+ _G.logger:fine(nameOfModule .. ": Preset EtherNet/IP Netmask: " .. tostring(netmask))
+ else
+ _G.logger:fine(nameOfModule .. ": Store old valid EtherNet/IP Netmask since current preset IP address is out of range with Gw address.")
+ fieldbus_Model.parameters.etherNetIP.netmask2 = fieldbus_Model.parameters.etherNetIP.netmask
+ end
+ fieldbus_Model.parameters.etherNetIP.netmask = netmask
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPSubnetMask", fieldbus_Model.parameters.etherNetIP.netmask)
+ else
+ _G.logger:warning(nameOfModule .. ": Can't set EtherNet/IP Netmask to '0.0.0.0'")
+ fieldbus_Model.info ="Can't set EtherNet/IP Netmask to '0.0.0.0'"
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ end
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPSubnetMask", fieldbus_Model.parameters.etherNetIP.netmask)
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPSubnetMask', setEtherNetIPSubnetMask)
+
+local function setEtherNetIPGateway(gateway)
+ -- Convert IPs and netmask to numbers
+ local a, b, c, d = fieldbus_Model.parameters.etherNetIP.ipAddress:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local ipNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.netmask:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local nmNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = gateway:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local gwNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+
+ -- Perform bitwise AND between IP address and netmask to get the network address
+ local networkAddress = ipNum & nmNum
+ local gwNetworkAddress = gwNum & nmNum
+
+ -- Check if IP address and gateway are in the same network
+ if networkAddress == gwNetworkAddress then
+ _G.logger:fine(nameOfModule .. ": Preset EtherNet/IP GW address: " .. tostring(gateway))
+ else
+ _G.logger:fine(nameOfModule .. ": Store old valid EtherNet/IP GW address since current preset IP address is out of range with Gw address.")
+ fieldbus_Model.parameters.etherNetIP.gateway2 = fieldbus_Model.parameters.etherNetIP.gateway
+ end
+ fieldbus_Model.parameters.etherNetIP.gateway = gateway
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPGateway", fieldbus_Model.parameters.etherNetIP.gateway)
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPGateway', setEtherNetIPGateway)
+
+local function setEtherNetIPNameServer(nameServer)
+ _G.logger:fine(nameOfModule .. ": Preset EtherNet/IP Primary name server: " .. tostring(nameServer))
+ fieldbus_Model.parameters.etherNetIP.nameServer = nameServer
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPNameServer", fieldbus_Model.parameters.etherNetIP.nameServer)
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPNameServer', setEtherNetIPNameServer)
+
+local function setEtherNetIPNameServer2(nameServer2)
+ _G.logger:fine(nameOfModule .. ": Preset EtherNet/IP Secondary name server: " .. tostring(nameServer2))
+ fieldbus_Model.parameters.etherNetIP.nameServer2 = nameServer2
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPNameServer2", fieldbus_Model.parameters.etherNetIP.nameServer2)
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPNameServer2', setEtherNetIPNameServer2)
+
+local function setEtherNetIPDomainName(domainName)
+ _G.logger:fine(nameOfModule .. ": Preset EtherNet/IP domain name: " .. tostring(domainName))
+ fieldbus_Model.parameters.etherNetIP.domainName = domainName
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPDomainName", fieldbus_Model.parameters.etherNetIP.domainName)
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPDomainName', setEtherNetIPDomainName)
+
+local function getEtherNetIPConfig()
+ _G.logger:fine(nameOfModule .. ": Get EtherNet/IP configuration.")
+ fieldbus_Model.getEtherNetIPConfig()
+end
+Script.serveFunction('CSK_Fieldbus.getEtherNetIPConfig', getEtherNetIPConfig)
+
+local function setEtherNetIPConfig()
+ _G.logger:fine(nameOfModule .. ": Activate preset EtherNet/IP configuration.")
+ fieldbus_Model.setEtherNetIPConfig()
+end
+Script.serveFunction('CSK_Fieldbus.setEtherNetIPConfig', setEtherNetIPConfig)
+
+-- ProfinetIO
+
+local function setProfinetIODeviceName(name)
+ _G.logger:fine(nameOfModule .. ": Preset device name to: " .. tostring(name))
+ fieldbus_Model.parameters.profinetIO.deviceName = name
+end
+Script.serveFunction('CSK_Fieldbus.setProfinetIODeviceName', setProfinetIODeviceName)
+
+local function setProfinetIOIP(ip)
+ _G.logger:fine(nameOfModule .. ": Preset ProfinetIO IP to: " .. tostring(ip))
+ fieldbus_Model.parameters.profinetIO.ipAddress = ip
+end
+Script.serveFunction('CSK_Fieldbus.setProfinetIOIP', setProfinetIOIP)
+
+local function setProfinetIOSubnetMask(netmask)
+ _G.logger:fine(nameOfModule .. ": Preset ProfinetIO subnet mask: " .. tostring(netmask))
+ fieldbus_Model.parameters.profinetIO.netmask = netmask
+end
+Script.serveFunction('CSK_Fieldbus.setProfinetIOSubnetMask', setProfinetIOSubnetMask)
+
+local function setProfinetIOGateway(gateway)
+ _G.logger:fine(nameOfModule .. ": Preset ProfinetIO gateway: " .. tostring(gateway))
+ fieldbus_Model.parameters.profinetIO.gateway = gateway
+end
+Script.serveFunction('CSK_Fieldbus.setProfinetIOGateway', setProfinetIOGateway)
+
+local function getProfinetIOConfig()
+ _G.logger:fine(nameOfModule .. ": Get ProfinetIO configuration.")
+ fieldbus_Model.getProfinetIOConfigInfo()
+end
+Script.serveFunction('CSK_Fieldbus.getProfinetIOConfig', getProfinetIOConfig)
+
+local function applyProfinetIOConfig()
+ _G.logger:fine(nameOfModule .. ": Activate preset ProfinetIO configuration.")
+ fieldbus_Model.applyProfinetIOConfig()
+end
+Script.serveFunction('CSK_Fieldbus.applyProfinetIOConfig', applyProfinetIOConfig)
+
+local function storeProfinetIOConfig()
+ _G.logger:fine(nameOfModule .. ": Store ProfinetIO configuration.")
+ fieldbus_Model.storeProfinetIOConfig()
+end
+Script.serveFunction('CSK_Fieldbus.storeProfinetIOConfig', storeProfinetIOConfig)
+
+local function setDAPIMDescriptor(descriptor)
+ _G.logger:fine(nameOfModule .. ": Preset DAP IM descriptoer to: " .. tostring(descriptor))
+ fieldbus_Model.parameters.profinetIO.dapImDescriptor = descriptor
+end
+Script.serveFunction('CSK_Fieldbus.setDAPIMDescriptor', setDAPIMDescriptor)
+
+local function setDAPIMInstallationDate(date)
+ _G.logger:fine(nameOfModule .. ": Preset DAP IM installation date to: " .. tostring(date))
+ fieldbus_Model.parameters.profinetIO.dapImInstallDate = date
+end
+Script.serveFunction('CSK_Fieldbus.setDAPIMInstallationDate', setDAPIMInstallationDate)
+
+local function setDAPIMTagFunction(tag)
+ _G.logger:fine(nameOfModule .. ": Preset DAP IM function tag to: " .. tostring(tag))
+ fieldbus_Model.parameters.profinetIO.tagFunction = tag
+end
+Script.serveFunction('CSK_Fieldbus.setDAPIMTagFunction', setDAPIMTagFunction)
+
+local function setDAPIMTagLocation(location)
+ _G.logger:fine(nameOfModule .. ": Preset DAP IM location tag to: " .. tostring(location))
+ fieldbus_Model.parameters.profinetIO.tagLocation = location
+end
+Script.serveFunction('CSK_Fieldbus.setDAPIMTagLocation', setDAPIMTagLocation)
+
+local function getDAPIMConfig()
+ _G.logger:fine(nameOfModule .. ": Get ProfinetIO DAP I&M data.")
+ fieldbus_Model.getDapImConfigInfo()
+end
+Script.serveFunction('CSK_Fieldbus.getDAPIMConfig', getDAPIMConfig)
+
+local function setDAPIMConfig()
+ _G.logger:fine(nameOfModule .. ": Set ProfinetIO DAP I&M data.")
+ fieldbus_Model.setDapImConfig()
+end
+Script.serveFunction('CSK_Fieldbus.setDAPIMConfig', setDAPIMConfig)
+
+local function storeDAPIMData()
+ _G.logger:fine(nameOfModule .. ": Store DAP I&M data.")
+ fieldbus_Model.storeDapImData()
+end
+Script.serveFunction('CSK_Fieldbus.storeDAPIMData', storeDAPIMData)
+
+local function setDataNameTransmit(name)
+ _G.logger:fine(nameOfModule .. ": Preset DataName to transmit: " .. tostring(name))
+ fieldbus_Model.dataNameTransmit = name
+end
+Script.serveFunction('CSK_Fieldbus.setDataNameTransmit', setDataNameTransmit)
+
+local function setDataNameReceive(name)
+ _G.logger:fine(nameOfModule .. ": Preset DataName to receive: " .. tostring(name))
+ fieldbus_Model.dataNameReceive = name
+end
+Script.serveFunction('CSK_Fieldbus.setDataNameReceive', setDataNameReceive)
+
+local function setRegisteredEventTransmit(eventName)
+ _G.logger:fine(nameOfModule .. ": Preset event to register for transmit data to: " .. tostring(eventName))
+ fieldbus_Model.registerEventTransmit = eventName
+end
+Script.serveFunction('CSK_Fieldbus.setRegisteredEventTransmit', setRegisteredEventTransmit)
+
+local function setConvertDataTransmit(status)
+ _G.logger:fine(nameOfModule .. ": Preset status to convert transmit data to: " .. tostring(status))
+ fieldbus_Model.convertDataTransmit = status
+end
+Script.serveFunction('CSK_Fieldbus.setConvertDataTransmit', setConvertDataTransmit)
+
+local function setConvertDataReceive(status)
+ _G.logger:fine(nameOfModule .. ": Preset status to convert received data to: " .. tostring(status))
+ fieldbus_Model.convertDataReceive = status
+end
+Script.serveFunction('CSK_Fieldbus.setConvertDataReceive', setConvertDataReceive)
+
+local function setBigEndianTransmit(status)
+ _G.logger:fine(nameOfModule .. ": Preset status of big endian of transmit data to: " .. tostring(status))
+ fieldbus_Model.bigEndianTransmit = status
+end
+Script.serveFunction('CSK_Fieldbus.setBigEndianTransmit', setBigEndianTransmit)
+
+local function setBigEndianReceive(status)
+ _G.logger:fine(nameOfModule .. ": Preset status of big endian of received data to: " .. tostring(status))
+ fieldbus_Model.bigEndianReceive = status
+end
+Script.serveFunction('CSK_Fieldbus.setBigEndianReceive', setBigEndianReceive)
+
+local function setDataTypeTransmit(dataType)
+ _G.logger:fine(nameOfModule .. ": Preset data type of transmit to: " .. tostring(dataType))
+ fieldbus_Model.dataTypeTransmit = dataType
+end
+Script.serveFunction('CSK_Fieldbus.setDataTypeTransmit', setDataTypeTransmit)
+
+local function setDataTypeReceive(dataType)
+ _G.logger:fine(nameOfModule .. ": Preset type or received data to: " .. tostring(dataType))
+ fieldbus_Model.dataTypeReceive = dataType
+end
+Script.serveFunction('CSK_Fieldbus.setDataTypeReceive', setDataTypeReceive)
+
+local function editDataToTransfer(dataName)
+
+ Script.deregister(fieldbus_Model.parameters.registeredEventsTransmit[dataName], fieldbus_Model.dataUpdateFunctions[dataName])
+
+ fieldbus_Model.parameters.registeredEventsTransmit[dataName] = fieldbus_Model.registerEventTransmit
+ fieldbus_Model.parameters.convertDataTypesTransmit[dataName] = fieldbus_Model.convertDataTransmit
+ fieldbus_Model.parameters.bigEndiansTransmit[dataName] = fieldbus_Model.bigEndianTransmit
+ fieldbus_Model.parameters.dataTypesTransmit[dataName] = fieldbus_Model.dataTypeTransmit
+
+ fieldbus_Model.registerToEvent(fieldbus_Model.parameters.registeredEventsTransmit[dataName], tonumber(fieldbus_Model.selectedDataTransmit), dataName)
+
+ fieldbus_Model.totalDataSizeTransmit = fieldbus_Model.helperFuncs.getDataSize(fieldbus_Model.parameters.dataTypesTransmit)
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "New transmit data size = " .. tostring(fieldbus_Model.totalDataSizeTransmit))
+end
+
+local function addDataToTransmitViaUI()
+ if fieldbus_Model.selectedDataTransmit == '' then
+ if not fieldbus_Model.parameters.registeredEventsTransmit[fieldbus_Model.dataNameTransmit] then
+ _G.logger:fine(nameOfModule .. ": Add data to transmit.")
+ fieldbus_Model.addDataTransmit(fieldbus_Model.dataNameTransmit, fieldbus_Model.registerEventTransmit, fieldbus_Model.convertDataTransmit, fieldbus_Model.dataTypeTransmit, fieldbus_Model.bigEndianTransmit)
+ else
+ _G.logger:warning(nameOfModule .. ": Transmit data with this name already exists.")
+ end
+ else
+ local posName = fieldbus_Model.parameters.dataNamesTransmit[tonumber(fieldbus_Model.selectedDataTransmit)]
+ if posName == fieldbus_Model.dataNameTransmit then
+ _G.logger:fine(nameOfModule .. ": Edit data to transmit.")
+ editDataToTransfer(posName)
+ else
+ _G.logger:info(nameOfModule .. ": Not possible to rename transmit data. Delete first and add new one...")
+ fieldbus_Model.dataNameTransmit = fieldbus_Model.parameters.dataNamesTransmit[tonumber(fieldbus_Model.selectedDataTransmit)]
+ Script.notifyEvent("Fieldbus_OnNewStatusDataNameTransmit", fieldbus_Model.dataNameTransmit)
+ end
+ end
+ fieldbus_Model.totalDataSizeTransmit = fieldbus_Model.helperFuncs.getDataSize(fieldbus_Model.parameters.dataTypesTransmit)
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "New transmit data size = " .. tostring(fieldbus_Model.totalDataSizeTransmit))
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.addDataToTransmitViaUI', addDataToTransmitViaUI)
+
+local function deleteDataToTransmitViaUI()
+ if fieldbus_Model.selectedDataTransmit ~= '' and tonumber(fieldbus_Model.selectedDataTransmit) then
+ _G.logger:fine(nameOfModule .. ": Delete data entry no." .. fieldbus_Model.selectedDataTransmit)
+ fieldbus_Model.removeDataTransmit(tonumber(fieldbus_Model.selectedDataTransmit))
+ fieldbus_Model.selectedDataTransmit = ''
+ end
+ fieldbus_Model.totalDataSizeTransmit = fieldbus_Model.helperFuncs.getDataSize(fieldbus_Model.parameters.dataTypesTransmit)
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "New transmit data size = " .. tostring(fieldbus_Model.totalDataSizeTransmit))
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.deleteDataToTransmitViaUI', deleteDataToTransmitViaUI)
+
+local function dataTransmitPositionUp()
+ if fieldbus_Model.selectedDataTransmit ~= '' and tonumber(fieldbus_Model.selectedDataTransmit) then
+ fieldbus_Model.dataTransmitPositionUp(tonumber(fieldbus_Model.selectedDataTransmit))
+ end
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.dataTransmitPositionUp', dataTransmitPositionUp)
+
+local function dataTransmitPositionDown()
+ if fieldbus_Model.selectedDataTransmit ~= '' and tonumber(fieldbus_Model.selectedDataTransmit) then
+ fieldbus_Model.dataTransmitPositionDown(tonumber(fieldbus_Model.selectedDataTransmit))
+ end
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.dataTransmitPositionDown', dataTransmitPositionDown)
+
+--- Function to edit data to receive
+---@param dataName string Name/identifier of data to update
+local function editDataToReceive(dataName)
+
+ fieldbus_Model.parameters.convertDataTypesReceive[dataName] = fieldbus_Model.convertDataReceive
+ fieldbus_Model.parameters.bigEndiansReceive[dataName] = fieldbus_Model.bigEndianReceive
+ fieldbus_Model.parameters.dataTypesReceive[dataName] = fieldbus_Model.dataTypeReceive
+
+ fieldbus_Model.totalDataSizeReceive = fieldbus_Model.helperFuncs.getDataSize(fieldbus_Model.parameters.dataTypesReceive)
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "New data size to receive = " .. tostring(fieldbus_Model.totalDataSizeReceive))
+end
+
+local function addDataToReceiveViaUI()
+ if fieldbus_Model.selectedDataReceive == '' then
+ if not fieldbus_Model.parameters.convertDataTypesReceive[fieldbus_Model.dataNameReceive] then
+ _G.logger:fine(nameOfModule .. ": Add data to receive.")
+ fieldbus_Model.addDataReceive(fieldbus_Model.dataNameReceive, fieldbus_Model.convertDataReceive, fieldbus_Model.dataTypeReceive, fieldbus_Model.bigEndianReceive)
+ else
+ _G.logger:warning(nameOfModule .. ": Data with this name already exists.")
+ end
+ else
+ local posName = fieldbus_Model.parameters.dataNamesReceive[tonumber(fieldbus_Model.selectedDataReceive)]
+ if posName == fieldbus_Model.dataNameReceive then
+ _G.logger:fine(nameOfModule .. ": Edit data to receive.")
+ editDataToReceive(posName)
+ else
+ _G.logger:info(nameOfModule .. ": Not possible to rename data. Delete first and add new one...")
+ fieldbus_Model.dataNameReceive = fieldbus_Model.parameters.dataNamesReceive[tonumber(fieldbus_Model.selectedDataReceive)]
+ Script.notifyEvent("Fieldbus_OnNewStatusDataNameReceive", fieldbus_Model.dataNameReceive)
+ end
+ end
+ fieldbus_Model.totalDataSizeReceive = fieldbus_Model.helperFuncs.getDataSize(fieldbus_Model.parameters.dataTypesReceive)
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "New data size to receive = " .. tostring(fieldbus_Model.totalDataSizeReceive))
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.addDataToReceiveViaUI', addDataToReceiveViaUI)
+
+local function deleteDataToReceiveViaUI()
+ if fieldbus_Model.selectedDataReceive ~= '' and tonumber(fieldbus_Model.selectedDataReceive) then
+ _G.logger:fine(nameOfModule .. ": Delete receive data entry no." .. fieldbus_Model.selectedDataReceive)
+ fieldbus_Model.removeDataReceive(tonumber(fieldbus_Model.selectedDataReceive))
+ fieldbus_Model.selectedDataReceive = ''
+ end
+ fieldbus_Model.totalDataSizeReceive = fieldbus_Model.helperFuncs.getDataSize(fieldbus_Model.parameters.dataTypesReceive)
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "New data size to receive = " .. tostring(fieldbus_Model.totalDataSizeReceive))
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.deleteDataToReceiveViaUI', deleteDataToReceiveViaUI)
+
+local function dataReceivePositionUp()
+ if fieldbus_Model.selectedDataReceive ~= '' and tonumber(fieldbus_Model.selectedDataReceive) then
+ fieldbus_Model.dataReceivePositionUp(tonumber(fieldbus_Model.selectedDataReceive))
+ end
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.dataReceivePositionUp', dataReceivePositionUp)
+
+local function dataReceivePositionDown()
+ if fieldbus_Model.selectedDataReceive ~= '' and tonumber(fieldbus_Model.selectedDataReceive) then
+ fieldbus_Model.dataReceivePositionDown(tonumber(fieldbus_Model.selectedDataReceive))
+ end
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.dataReceivePositionDown', dataReceivePositionDown)
+
+--- Function to check if selection in UIs DynamicTable can find related pattern
+---@param selection string Full text of selection
+---@param pattern string Pattern to search for
+local function checkSelection(selection, pattern)
+ if selection ~= "" then
+ local _, pos = string.find(selection, pattern)
+ if pos == nil then
+ else
+ pos = tonumber(pos)
+ if pattern ~= '"selected":true' then
+ local endPos = string.find(selection, '"', pos+1)
+ local tempSelection = string.sub(selection, pos+1, endPos-1)
+ if tempSelection ~= nil and tempSelection ~= '-' then
+ return tempSelection
+ end
+ else
+ return ''
+ end
+ end
+ end
+ return nil
+end
+
+local function selectDataTransmitViaUI(selection)
+ local tempSelection = checkSelection(selection, '"DTC_IDTransmit":"')
+ if tempSelection then
+ local isSelected = checkSelection(selection, '"selected":true')
+ if isSelected then
+ _G.logger:fine(nameOfModule .. ": Selected data no." .. tostring(tempSelection))
+ fieldbus_Model.selectedDataTransmit = tempSelection
+
+ local tempName = fieldbus_Model.parameters.dataNamesTransmit[tonumber(tempSelection)]
+
+ fieldbus_Model.dataNameTransmit = tempName
+ fieldbus_Model.registerEventTransmit = fieldbus_Model.parameters.registeredEventsTransmit[tempName]
+ fieldbus_Model.convertDataTransmit = fieldbus_Model.parameters.convertDataTypesTransmit[tempName]
+ fieldbus_Model.bigEndianTransmit = fieldbus_Model.parameters.bigEndiansTransmit[tempName]
+ fieldbus_Model.dataTypeTransmit = fieldbus_Model.parameters.dataTypesTransmit[tempName]
+
+ Script.notifyEvent("Fieldbus_OnNewStatusDataNameTransmit", fieldbus_Model.dataNameTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusRegisteredEventTransmit", fieldbus_Model.registerEventTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusConvertDataTransmit", fieldbus_Model.convertDataTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusBigEndianTransmit", fieldbus_Model.bigEndianTransmit)
+ Script.notifyEvent("Fieldbus_OnNewStatusDataTypeTransmit", fieldbus_Model.dataTypeTransmit)
+ else
+ fieldbus_Model.selectedDataTransmit = ''
+ end
+ handleOnExpiredTmrFieldbus()
+ end
+end
+Script.serveFunction('CSK_Fieldbus.selectDataTransmitViaUI', selectDataTransmitViaUI)
+
+local function selectDataReceiveViaUI(selection)
+ local tempSelection = checkSelection(selection, '"DTC_IDReceive":"')
+ if tempSelection then
+ local isSelected = checkSelection(selection, '"selected":true')
+ if isSelected then
+ _G.logger:fine(nameOfModule .. ": Selected receive data no." .. tostring(tempSelection))
+ fieldbus_Model.selectedDataReceive = tempSelection
+
+ local tempName = fieldbus_Model.parameters.dataNamesReceive[tonumber(tempSelection)]
+
+ fieldbus_Model.dataNameReceive = tempName
+ fieldbus_Model.convertDataReceive = fieldbus_Model.parameters.convertDataTypesReceive[tempName]
+ fieldbus_Model.bigEndianReceive = fieldbus_Model.parameters.bigEndiansReceive[tempName]
+ fieldbus_Model.dataTypeReceive = fieldbus_Model.parameters.dataTypesReceive[tempName]
+
+ Script.notifyEvent("Fieldbus_OnNewStatusDataNameReceive", fieldbus_Model.dataNameReceive)
+ Script.notifyEvent("Fieldbus_OnNewStatusConvertDataReceive", fieldbus_Model.convertDataReceive)
+ Script.notifyEvent("Fieldbus_OnNewStatusBigEndianReceive", fieldbus_Model.bigEndianReceive)
+ Script.notifyEvent("Fieldbus_OnNewStatusDataTypeReceive", fieldbus_Model.dataTypeReceive)
+ else
+ fieldbus_Model.selectedDataReceive = ''
+ end
+ handleOnExpiredTmrFieldbus()
+ end
+end
+Script.serveFunction('CSK_Fieldbus.selectDataReceiveViaUI', selectDataReceiveViaUI)
+
+local function setTempTransmitData(data)
+ fieldbus_Model.tempDataTransmit = data
+end
+Script.serveFunction('CSK_Fieldbus.setTempTransmitData', setTempTransmitData)
+
+local function triggerTempDataViaUI()
+ if fieldbus_Model.selectedDataTransmit ~= '' then
+
+ local value
+ if fieldbus_Model.parameters.dataTypesTransmit[fieldbus_Model.dataNameTransmit] == 'CHAR' or fieldbus_Model.parameters.dataTypesTransmit[fieldbus_Model.dataNameTransmit] == 'STRING' then
+ value = fieldbus_Model.tempDataTransmit
+ else
+ value = tonumber(fieldbus_Model.tempDataTransmit)
+ end
+
+ -- Temporarily activate conversion
+ local tempConvertStatus = fieldbus_Model.parameters.convertDataTypesTransmit[fieldbus_Model.dataNameTransmit]
+ fieldbus_Model.parameters.convertDataTypesTransmit[fieldbus_Model.dataNameTransmit] = true
+ fieldbus_Model.dataUpdateFunctions[fieldbus_Model.dataNameTransmit](value)
+ fieldbus_Model.parameters.convertDataTypesTransmit[fieldbus_Model.dataNameTransmit] = tempConvertStatus
+ else
+ _G.logger:fine(nameOfModule .. ": No data position selected.")
+ end
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.triggerTempDataViaUI', triggerTempDataViaUI)
+
+local function resetTransmitData()
+ fieldbus_Model.resetTransmitData()
+ handleOnExpiredTmrFieldbus()
+end
+Script.serveFunction('CSK_Fieldbus.resetTransmitData', resetTransmitData)
-- *****************************************************************
-- Following function can be adapted for CSK_PersistentData module usage
-- *****************************************************************
local function setParameterName(name)
- _G.logger:info(nameOfModule .. ": Set parameter name: " .. tostring(name))
+ _G.logger:fine(nameOfModule .. ": Set parameter name: " .. tostring(name))
fieldbus_Model.parametersName = name
end
Script.serveFunction("CSK_Fieldbus.setParameterName", setParameterName)
@@ -148,7 +958,7 @@ local function sendParameters()
if fieldbus_Model.persistentModuleAvailable then
CSK_PersistentData.addParameter(fieldbus_Model.helperFuncs.convertTable2Container(fieldbus_Model.parameters), fieldbus_Model.parametersName)
CSK_PersistentData.setModuleParameterName(nameOfModule, fieldbus_Model.parametersName, fieldbus_Model.parameterLoadOnReboot)
- _G.logger:info(nameOfModule .. ": Send Fieldbus parameters with name '" .. fieldbus_Model.parametersName .. "' to CSK_PersistentData module.")
+ _G.logger:fine(nameOfModule .. ": Send Fieldbus parameters with name '" .. fieldbus_Model.parametersName .. "' to CSK_PersistentData module.")
CSK_PersistentData.saveData()
else
_G.logger:warning(nameOfModule .. ": CSK_PersistentData module not available.")
@@ -156,15 +966,44 @@ local function sendParameters()
end
Script.serveFunction("CSK_Fieldbus.sendParameters", sendParameters)
-local function loadParameters()
+--- Function to register on events provided e.g. by other modules (optionally react on timer started after loading of persistent parameters)
+local function registerToEvents()
+ for key, value in ipairs(fieldbus_Model.parameters.dataNamesTransmit) do
+ fieldbus_Model.addEmptySpace(fieldbus_Model.parameters.dataTypesTransmit[value])
+ fieldbus_Model.registerToEvent(fieldbus_Model.parameters.registeredEventsTransmit[value], key, value)
+ end
+end
+Timer.register(tmrWaitForSetupOfOtherModules, 'OnExpired', registerToEvents)
+
+local function loadParameters(wait)
if fieldbus_Model.persistentModuleAvailable then
local data = CSK_PersistentData.getParameter(fieldbus_Model.parametersName)
if data then
_G.logger:info(nameOfModule .. ": Loaded parameters from CSK_PersistentData module.")
fieldbus_Model.parameters = fieldbus_Model.helperFuncs.convertContainer2Table(data)
- -- If something needs to be configured/activated with new loaded data, place this here:
- -- ...
- -- ...
+
+ -- If something needs to be configured/activated with new loaded data, place this here
+ local fbMode = Parameters.get('FBmode')
+ if (fbMode == 0 and fieldbus_Model.fbMode ~= 'DISABLED') or (fbMode == 1 and fieldbus_Model.fbMode ~= 'ProfinetIO') or ( fbMode == 2 and fieldbus_Model.fbMode ~= 'EtherNetIP') then
+ _G.logger:warning(nameOfModule .. ": Current fieldbus protocol of device differs from parameter setup. Please restart device.")
+ return
+ end
+
+ fieldbus_Model.deregisterAllEvents()
+
+ if not wait then
+ registerToEvents()
+ end
+
+ fieldbus_Model.dataReceived = {}
+ for key, value in ipairs(fieldbus_Model.parameters.dataNamesReceive) do
+ fieldbus_Model.dataReceived[value] = '-'
+ fieldbus_Model.serveReceiveEvent(value)
+ end
+
+ if fieldbus_Model.parameters.active == true then
+ fieldbus_Model.openCommunication()
+ end
CSK_Fieldbus.pageCalled()
else
@@ -178,7 +1017,7 @@ Script.serveFunction("CSK_Fieldbus.loadParameters", loadParameters)
local function setLoadOnReboot(status)
fieldbus_Model.parameterLoadOnReboot = status
- _G.logger:info(nameOfModule .. ": Set new status to load setting on reboot: " .. tostring(status))
+ _G.logger:fine(nameOfModule .. ": Set new status to load setting on reboot: " .. tostring(status))
end
Script.serveFunction("CSK_Fieldbus.setLoadOnReboot", setLoadOnReboot)
@@ -197,10 +1036,13 @@ local function handleOnInitialDataLoaded()
if parameterName then
fieldbus_Model.parametersName = parameterName
fieldbus_Model.parameterLoadOnReboot = loadOnReboot
+ else
+ fieldbus_Model.create()
end
if fieldbus_Model.parameterLoadOnReboot then
- loadParameters()
+ tmrWaitForSetupOfOtherModules:start() -- Start timer to wait for events which could be provided by other modules
+ loadParameters(true)
end
Script.notifyEvent('Fieldbus_OnDataLoadedOnReboot')
end
diff --git a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Model.lua b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Model.lua
index a9886c7..ef98737 100644
--- a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Model.lua
+++ b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/Fieldbus_Model.lua
@@ -31,26 +31,133 @@ setFieldbus_ModelHandle(fieldbus_Model)
--Loading helper functions if needed
fieldbus_Model.helperFuncs = require('Communication/Fieldbus/helper/funcs')
--- Optionally check if specific API was loaded via
---[[
-if _G.availableAPIs.specific then
--- ... doSomething ...
+-- Check if specific API was loaded via
+fieldbus_Model.moduleActive = _G.availableAPIs.specific
+
+-- Check if needed CROWN is available on device
+if FieldBus == nil then
+ fieldbus_Model.moduleActive = false
+ _G.logger:warning(nameOfModule .. ': CROWN is not available. Module is not supported...')
end
-]]
---[[
--- Create parameters / instances for this module
-fieldbus_Model.object = Image.create() -- Use any AppEngine CROWN
-fieldbus_Model.counter = 1 -- Short docu of variable
-fieldbus_Model.varA = 'value' -- Short docu of variable
---...
-]]
+local fbMode = Parameters.get('FBmode')
+if fbMode == 1 then
+ fieldbus_Model.fbMode = 'ProfinetIO'
+elseif fbMode == 2 then
+ fieldbus_Model.fbMode = 'EtherNetIP'
+else
+ fieldbus_Model.fbMode = 'DISABLED'
+end
+
+fieldbus_Model.handle = nil -- Fieldbus handle
+fieldbus_Model.opened = false -- Status if fieldbus handle was opended.
+fieldbus_Model.currentStatus = 'CLOSED' -- Current status of the fieldbus communication.
+fieldbus_Model.info = 'No info available.' -- Information of the fieldbus component.
+
+fieldbus_Model.controlBitsIn = 0 -- Current value of the control bits transmitted to the PLC.
+fieldbus_Model.boolControlBitsIn = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false} -- Status of ControlBitsIN as boolean table
+fieldbus_Model.controlBitsOut = 0 -- Current value of the control bits received from the PLC.
+fieldbus_Model.boolControlBitsOut = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false} -- Status of ControlBitsOUT as boolean table
+fieldbus_Model.controlBitsToWrite = 0 -- Preset control bits to write.
+fieldbus_Model.boolControlBitsToWrite = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false} -- Status of ControlBitsIN to write as boolean table
+fieldbus_Model.bitMask = 65535 -- Preset bitMask to use for controlBits.
+fieldbus_Model.boolBitMask = {true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true} -- Status of mask of ControlBitsIN to write as boolean table
+
+fieldbus_Model.port = 'P1' -- Fieldbus port, e.g. 'P2'
+
+fieldbus_Model.dataUpdateFunctions = {} -- Functions to update transmit data
+fieldbus_Model.transmissionDataList = '' -- List of data entries for transmission
+
+fieldbus_Model.selectedDataTransmit = '' -- Number of selected data entry in UI table
+fieldbus_Model.selectedDataReceive = '' -- Number of selected data entry in UI table
+fieldbus_Model.tempDataTransmit = '' -- Data to temporarily set for selected transmit data
+
+fieldbus_Model.dataToTransmit = {} -- Preset data to transmit (binary)
+fieldbus_Model.readableDataToTransmit = {} -- Readbale preset data to transmit
+fieldbus_Model.fullDataToTransmit = '' -- Full binary string including all data to transmit
+fieldbus_Model.dataNameTransmit = 'DataName' -- Preconfigured name of data to setup for transmission
+fieldbus_Model.registerEventTransmit = 'OtherModule.OnNewEvent' -- Preconfigured event to register to receive transmit data
+fieldbus_Model.convertDataTransmit = true -- Preconfigured status if received data should be converted before transmission
+fieldbus_Model.bigEndianTransmit = true -- Preconfigured status of endianness for data to transmit, little endian per default
+fieldbus_Model.dataTypeTransmit = 'U_INT1' -- Preconfigured data type of data to setup for transmission
+fieldbus_Model.totalDataSizeTransmit = 0 -- Sum of data size to transmit
+
+fieldbus_Model.dataReceived = {} -- Holding received values per data entry
+fieldbus_Model.dataNameReceive = 'DataName' -- Preconfigured name of data to setup for receiving
+fieldbus_Model.convertDataReceive = true -- Preconfigured status if received data should be converted before transmission
+fieldbus_Model.bigEndianReceive = true -- Preconfigured status of endianness for data to transmit, little endian per default
+fieldbus_Model.dataTypeReceive = 'U_INT1' -- Preconfigured data type of data to setup for transmission
+fieldbus_Model.totalDataSizeReceive = 0 -- Sum of data size to transmit
-- Parameters to be saved permanently if wanted
fieldbus_Model.parameters = {}
---fieldbus_Model.parameters.paramA = 'paramA' -- Short docu of variable
---fieldbus_Model.parameters.paramB = 123 -- Short docu of variable
---...
+fieldbus_Model.parameters.protocol = 'DISABLED' -- Type of fieldbus communication, e.g. 'DISABLED' (0) / 'ProfinetIO' (1) / 'EtherNetIP' (2) / 'ETHERCAT' (not available yet)
+fieldbus_Model.parameters.createMode = 'EXPLICIT_OPEN' -- or 'EXPLICIT_OPEN', AUTOMATIC_OPEN
+fieldbus_Model.parameters.transmissionMode = 'RAW' -- or 'RAW', CONFIRMED_MESSAGING
+fieldbus_Model.parameters.active = false -- Status if fieldbus connection should be established
+
+fieldbus_Model.parameters.dataNamesTransmit = {} -- List of names/identifiers of data entries to transmit
+fieldbus_Model.parameters.registeredEventsTransmit = {} -- List of names of event to receive data to transmit
+fieldbus_Model.parameters.convertDataTypesTransmit = {} -- Status if received data needs to be converted to binary or is already binary
+fieldbus_Model.parameters.dataTypesTransmit = {} -- Data types of values to transmit
+fieldbus_Model.parameters.bigEndiansTransmit = {} -- Little endian per default
+
+fieldbus_Model.parameters.dataNamesReceive = {} -- List of names/identifiers of data entries to transmit
+fieldbus_Model.parameters.convertDataTypesReceive = {} -- Status if received data needs to be converted to binary or is already binary
+fieldbus_Model.parameters.dataTypesReceive = {} -- Data types of values to transmit
+fieldbus_Model.parameters.bigEndiansReceive = {} -- Little endian per default
+
+fieldbus_Model.parameters.etherNetIP = {}
+fieldbus_Model.parameters.etherNetIP.storageRequestDataPath = '/public/FieldBus/EtherNetIP/StorageData.dat' -- Path to store fieldbus storage data.
+fieldbus_Model.parameters.etherNetIP.addressingMode = 'STATIC' -- or 'DHCP' / 'BOOTP'
+fieldbus_Model.parameters.etherNetIP.ipAddress = '192.168.0.1' -- IP address
+fieldbus_Model.parameters.etherNetIP.ipAddress2 = '192.168.0.1' -- IP address
+fieldbus_Model.parameters.etherNetIP.netmask = '255.255.255.0' -- Subnet mask
+fieldbus_Model.parameters.etherNetIP.netmask2 = '255.255.255.0' -- Subnet mask
+fieldbus_Model.parameters.etherNetIP.gateway = '0.0.0.0' -- Gateway address
+fieldbus_Model.parameters.etherNetIP.gateway2 = '0.0.0.0' -- Gateway address
+fieldbus_Model.parameters.etherNetIP.nameServer = '0.0.0.0' -- Primary name server
+fieldbus_Model.parameters.etherNetIP.nameServer2 = '0.0.0.0' -- Secondary name server
+fieldbus_Model.parameters.etherNetIP.domainName = '' -- Domain name
+fieldbus_Model.parameters.etherNetIP.macAddress = '' -- MAC address of fieldbus implementation.
+
+fieldbus_Model.parameters.profinetIO = {}
+fieldbus_Model.parameters.profinetIO.storageRequestDataPath = '/public/FieldBus/ProfinetIO/StorageData.dat' -- Path to store fieldbus storage data.
+fieldbus_Model.parameters.profinetIO.deviceName = '' -- Device name
+fieldbus_Model.parameters.profinetIO.remanent = false -- Status if the network configuration tool sets the current name of the device permanently (true), that is, it will be reloaded after a restart of the device.
+fieldbus_Model.parameters.profinetIO.ipAddress = '0.0.0.0' -- IP address
+fieldbus_Model.parameters.profinetIO.netmask = '255.255.255.0' -- Subnet mask
+fieldbus_Model.parameters.profinetIO.gateway = '0.0.0.0' -- Gateway address
+fieldbus_Model.parameters.profinetIO.macAddress = '' -- MAC address of fieldbus implementation.
+
+fieldbus_Model.parameters.profinetIO.dapImDescriptor = 'Descriptor' -- The descriptor (a.k.a. 'comment') as used for the DAP’s (device access point) I&M3 data.
+fieldbus_Model.parameters.profinetIO.dapImHardwareRev = 0 -- Hardware revision as used for the DAP (device access point) used in the I&M0 data.
+fieldbus_Model.parameters.profinetIO.dapImInstallDate = 'YYYY-MM-DD' -- Installation date as used for the DAP’s (device access point) I&M2 data.
+
+-- Software revision for the DAP (device access point) used in the I&M0 data.
+fieldbus_Model.parameters.profinetIO.dapImSoftwareRevPrefix = 'Prefix' -- Prefix character of the software revision of this I&M0 data.
+fieldbus_Model.parameters.profinetIO.dapImSoftwareRevFuncEnhancement = 0 -- Functional enhancement identifier of the software revision of this I&M0 data.
+fieldbus_Model.parameters.profinetIO.dapImSoftwareRevBugFix = 0 -- Bug fix identifier of the software revision of this I&M0 data.
+fieldbus_Model.parameters.profinetIO.dapImSoftwareRevInternalChange = 0 -- Internal change identifier of the software revision of this I&M0 data.
+
+fieldbus_Model.parameters.profinetIO.dapImTagFunction = 'PlantDesignation' -- Function tag (a.k.a. 'plant designation') as used for the DAP’s (device access point) I&M1 data.
+fieldbus_Model.parameters.profinetIO.dapImTagLocation = 'LocationIdentifier' -- Location tag (a.k.a. 'location identifier') as used for the DAP’s (device access point) I&M1 data.
+
+--- Function to create folder if it does not exists
+---@param folder string Name of folder to create if it does not exists already
+local function createFolder(folder)
+ local folderExists = File.isdir(folder)
+ if not folderExists then
+ local suc = File.mkdir(folder)
+ if not suc then
+ _G.logger:warning(nameOfModule .. ': Not possible to create folder on device.')
+ end
+ end
+end
+-- Create default folders for the module
+createFolder('/public/FieldBus')
+createFolder('/public/FieldBus/EtherNetIP')
+createFolder('/public/FieldBus/ProfinetIO')
--**************************************************************************
--********************** End Global Scope **********************************
@@ -58,15 +165,873 @@ fieldbus_Model.parameters = {}
--**********************Start Function Scope *******************************
--**************************************************************************
+--- Function to get various information about the fieldbus, its componentes and internals.
+local function getInfo()
+ fieldbus_Model.info = FieldBus.getInfo(fieldbus_Model.handle)
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.helperFuncs.jsonLine2Table(fieldbus_Model.info))
+end
+fieldbus_Model.getInfo = getInfo
+
+--- Function to get status information about the fieldbus.
+local function getStatus()
+ fieldbus_Model.currentStatus = FieldBus.getStatus(fieldbus_Model.handle)
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusStatus", fieldbus_Model.currentStatus)
+end
+fieldbus_Model.getStatus = getStatus
+
+-----------------------
+-- EtherNet/IP relevant
+-----------------------
+
+
+local function getEtherNetIPConfig()
+ local ipAddress, netmask, gateway, nameServer, nameServer2, domainName = FieldBus.Config.EtherNetIP.getInterfaceConfig()
+ if ipAddress ~= '0.0.0.0' and netmask ~= '0.0.0.0' then
+ fieldbus_Model.parameters.etherNetIP.ipAddress = ipAddress
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPIPAddress", fieldbus_Model.parameters.etherNetIP.ipAddress)
+ fieldbus_Model.parameters.etherNetIP.netmask = netmask
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPGateway", fieldbus_Model.parameters.etherNetIP.gateway)
+ fieldbus_Model.parameters.etherNetIP.gateway = gateway
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPSubnetMask", fieldbus_Model.parameters.etherNetIP.netmask)
+ fieldbus_Model.parameters.etherNetIP.nameServer = nameServer
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPNameServer", fieldbus_Model.parameters.etherNetIP.nameServer)
+ fieldbus_Model.parameters.etherNetIP.nameServer2 = nameServer2
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPNameServer2", fieldbus_Model.parameters.etherNetIP.nameServer2)
+ fieldbus_Model.parameters.etherNetIP.domainName = domainName
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPDomainName", fieldbus_Model.parameters.etherNetIP.domainName)
+ end
+ if fieldbus_Model.handle then
+ getInfo()
+ getStatus()
+ else
+ fieldbus_Model.info ="Fieldbus handle not created yet."
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ end
+end
+fieldbus_Model.getEtherNetIPConfig = getEtherNetIPConfig
+
+-- Function to set EtherNet/IP config
+local function setEtherNetIPConfig()
+ if fieldbus_Model.parameters.etherNetIP.ipAddress ~= '0.0.0.0' and fieldbus_Model.parameters.etherNetIP.netmask ~= '0.0.0.0' then
+ -- Convert IPs and netmask to numbers
+ local a, b, c, d = fieldbus_Model.parameters.etherNetIP.ipAddress:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local ipNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.netmask:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local nmNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.gateway:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ local gwNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+
+ -- Perform bitwise AND between IP address and Netmask to get the network address
+ local networkAddress = ipNum & nmNum
+ local gwNetworkAddress = gwNum & nmNum
+
+ -- Check if IP address and GW address are in the same network
+ if networkAddress == gwNetworkAddress then
+ if FieldBus.Config.EtherNetIP.setInterfaceConfig(
+ fieldbus_Model.parameters.etherNetIP.ipAddress,
+ fieldbus_Model.parameters.etherNetIP.netmask,
+ fieldbus_Model.parameters.etherNetIP.gateway,
+ fieldbus_Model.parameters.etherNetIP.nameServer,
+ fieldbus_Model.parameters.etherNetIP.nameServer2,
+ fieldbus_Model.parameters.etherNetIP.domainName
+ ) then
+ if fieldbus_Model.handle then
+ getInfo()
+ getStatus()
+ else
+ fieldbus_Model.info ="Fieldbus handle not created yet."
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ end
+ else
+ print(fieldbus_Model.currentStatus)
+ _G.logger:warning("Cannot set the Ethernet connection. The configuration is not valid.")
+ fieldbus_Model.info = "Cannot set the Ethernet connection. The configuration is not valid."
+ end
+ else
+ -- Convert backup IP address to numbers
+ a, b, c, d = fieldbus_Model.parameters.etherNetIP.ipAddress2:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
+ ipNum = tonumber(a) * 256^3 + tonumber(b) * 256^2 + tonumber(c) * 256 + tonumber(d)
+
+ -- Perform bitwise AND between backup IP address and Netmask to get the network address
+ networkAddress = ipNum & nmNum
+ gwNetworkAddress = gwNum & nmNum
+
+ -- Check if IP address and gateway are in the same network
+ if networkAddress == gwNetworkAddress then
+ if FieldBus.Config.EtherNetIP.setInterfaceConfig(
+ fieldbus_Model.parameters.etherNetIP.ipAddress2,
+ fieldbus_Model.parameters.etherNetIP.netmask,
+ fieldbus_Model.parameters.etherNetIP.gateway,
+ fieldbus_Model.parameters.etherNetIP.nameServer,
+ fieldbus_Model.parameters.etherNetIP.nameServer2,
+ fieldbus_Model.parameters.etherNetIP.domainName
+ ) then
+ if fieldbus_Model.handle then
+ getInfo()
+ getStatus()
+ else
+ fieldbus_Model.info ="Fieldbus handle not created yet."
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+ end
+ else
+ print(fieldbus_Model.currentStatus)
+ _G.logger:warning("Cannot set the Ethernet connection. The configuration is not valid.")
+ fieldbus_Model.info = "Cannot set the Ethernet connection. The configuration is not valid."
+ end
+ else
+ _G.logger:warning("Cannot set the Ethernet connection. The configuration is not valid. IP address and GW address out of range.")
+ fieldbus_Model.info = "Cannot set the Ethernet connection. The configuration is not valid. IP address and GW address out of range."
+ end
+ end
+ else
+ _G.logger:warning("IP Address / NetMask = " .. tostring(fieldbus_Model.parameters.etherNetIP.ipAddress) .. " / " .. tostring(fieldbus_Model.parameters.etherNetIP.netmask))
+ fieldbus_Model.info = "Cannot set the Ethernet connection. IP Address / NetMask = " .. tostring(fieldbus_Model.parameters.etherNetIP.ipAddress) .. " / " .. tostring(fieldbus_Model.parameters.etherNetIP.netmask)
+ end
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusInfo", fieldbus_Model.info)
+end
+fieldbus_Model.setEtherNetIPConfig = setEtherNetIPConfig
+
+
+---
+---@param addressingMode FieldBus.Config.EtherNetIP.AddressingMode Addressing mode for the ip parameters.
+local function handleOnAddressingModeChanged(addressingMode)
+ _G.logger:fine("New EtherNet/IP Addressing Mode: " .. addressingMode)
+ fieldbus_Model.parameters.etherNetIP.addressingMode = addressingMode
+ Script.notifyEvent("Fieldbus_OnNewStatusEtherNetIPAddressingMode", fieldbus_Model.parameters.etherNetIP.addressingMode)
+end
+Script.register('FieldBus.Config.EtherNetIP.OnAddressingModeChanged', handleOnAddressingModeChanged)
+
+
+-- Function to react on received EtherNet/IP interface config.
+---@param ipAddress string IP address.
+---@param netmask string Subnetmask.
+---@param gateway string Gateway IP address.
+---@param nameServer? string Primary name server.
+---@param nameServer2? string Secondary name server.
+---@param domainName? string Default domain name.
+local function handleOnEthernetIPInterfaceConfigChanged(ipAddress, netmask, gateway, nameServer, nameServer2, domainName)
+ if ipAddress ~= '0.0.0.0' and netmask ~= '0.0.0.0' then
+ _G.logger:fine("New EtherNet/IP interface config: " .. ipAddress)
+-- _G.logger:finer("IP Address / NetMask = " .. tostring(ipAddress) .. ' / ' .. tostring(netmask))
+ fieldbus_Model.parameters.etherNetIP.ipAddress = ipAddress
+ fieldbus_Model.parameters.etherNetIP.netmask = netmask
+-- _G.logger:finer("Gateway = " .. tostring(gateway))
+ fieldbus_Model.parameters.etherNetIP.gateway = gateway
+ if nameServer and nameServer2 then
+-- _G.logger:finer("Nameserver 1 / 2 = " .. tostring(nameServer) .. ' / ' .. tostring(nameServer2))
+ fieldbus_Model.parameters.etherNetIP.nameServer = nameServer
+ fieldbus_Model.parameters.etherNetIP.nameServer2 = nameServer2
+ else
+ if nameServer then
+-- _G.logger:finer("Nameserver 1 = " .. tostring(nameServer))
+ fieldbus_Model.parameters.etherNetIP.nameServer = nameServer
+ end
+ if nameServer2 then
+-- _G.logger:finer("Nameserver 2 = " .. tostring(nameServer2))
+ fieldbus_Model.parameters.etherNetIP.nameServer2 = nameServer2
+ end
+ end
+ if domainName then
+-- _G.logger:finer("DomainName = " .. tostring(domainName))
+ fieldbus_Model.parameters.etherNetIP.domainName = domainName
+ end
+ elseif not fieldbus_Model.parameters.etherNetIP.addressingMode == 'STATIC' then
+ _G.logger:warning("IP Address / NetMask = " .. tostring(ipAddress) .. ' / ' .. tostring(netmask))
+ end
+ fieldbus_Model.parameters.etherNetIP.macAddress = FieldBus.Config.EtherNetIP.getMACAddress()
+ if nil == fieldbus_Model.parameters.etherNetIP.macAddress then
+ _G.logger:warning("ENIP: FieldBus.Config.EtherNetIP.getMACAddress returned NIL!!!")
+ fieldbus_Model.parameters.etherNetIP.macAddress = ''
+ end
+ getInfo()
+ getStatus()
+end
+
+-- Function to react on FieldbusStoreRequest
+---@param storageHandle FieldBus.StorageRequest Object containing the data to be saved or loaded
+local function handleOnEtherNetIPFieldbusStorageRequest(storageHandle)
+ local storageOperation = FieldBus.StorageRequest.getOperation(storageHandle)
+ --_G.logger:fine("ENIP: onFieldbusStorageRequest event received, operation: " .. storageOperation)
+ local dataToStore = FieldBus.StorageRequest.getData(storageHandle)
+ local dataFromFile = nil
+ local storageResult = false
+ if storageOperation == "SAVE" then --FieldBus.StorageRequest.StorageOperation.Save
+ -- store in a file
+ local handle = File.open(fieldbus_Model.parameters.etherNetIP.storageRequestDataPath, 'wb')
+ if handle then
+ File.write(handle, dataToStore)
+ File.close(handle)
+ storageResult = true
+ else
+ _G.logger:severe(string.format("Failed to open file for saving of storage data!"))
+ end
+ end
+ if storageOperation == "LOAD" then --FieldBus.StorageRequest.StorageOperation.Load
+ -- load from a file
+ local handle = File.open(fieldbus_Model.parameters.etherNetIP.storageRequestDataPath, 'rb')
+ if handle then
+ dataFromFile = File.read(handle)
+ File.close(handle)
+ storageResult = FieldBus.StorageRequest.setData(storageHandle, dataFromFile)
+ if storageResult == false then
+ _G.logger:severe(string.format("Setting data at storage request failed"))
+ end
+ else
+ _G.logger:severe(string.format("Failed to open file to load storage data from!"))
+ storageResult = false
+ end
+ end
+ FieldBus.StorageRequest.notifyResult(storageHandle, storageResult)
+ CSK_Fieldbus.pageCalled()
+end
+
+-----------------------
+-- ProfinetIO relevant
+-----------------------
+
+--- Function to apply ProfinetIO config
+local function applyProfinetIOConfig()
+ local suc = FieldBus.Config.ProfinetIO.applyConfig()
+ _G.logger:fine("Success of ApplyConfig = " .. tostring(suc))
+end
+fieldbus_Model.applyProfinetIOConfig = applyProfinetIOConfig
+
+--- Function to store ProfinetIO config
+local function storeProfinetIOConfig()
+ local suc = FieldBus.Config.ProfinetIO.storeConfig()
+ _G.logger:fine('Store config = ' .. tostring(suc))
+end
+fieldbus_Model.storeProfinetIOConfig = storeProfinetIOConfig
+
+--- Function to react on received ProfinetIO DeviceName.
+---@param deviceName string Currently active name of the device
+---@param remanent bool True if the network configuration tool sets the current name of the device permanently, that is, it will be reloaded after a restart of the device.
+local function handleOnDeviceNameChanged(deviceName, remanent)
+ _G.logger:fine("Received DeviceName info!")
+ _G.logger:fine("Name = " .. tostring(deviceName))
+ _G.logger:fine("Remanent = " .. tostring(remanent))
+
+ fieldbus_Model.parameters.profinetIO.deviceName = deviceName
+ fieldbus_Model.parameters.profinetIO.remanent = remanent
+
+ FieldBus.Config.ProfinetIO.setDeviceName(fieldbus_Model.parameters.profinetIO.deviceName)
+ applyProfinetIOConfig()
+
+ if remanent == true then
+ storeProfinetIOConfig()
+ end
+
+ CSK_Fieldbus.pageCalled()
+
+end
+
+-- Function to react on received ProfinetIO interface config.
+---@param ipAddress string Currently active (applied) IP address
+---@param subnetMask string Currently active (applied) subnet mask
+---@param gateway string Currently active (applied) gateway address
+---@param remanent bool True if the network configuration tool sets the current IP address settings permanently, that is, it will be reloaded after a restart of the device.
+local function handleOnProfinetIOInterfaceConfigChanged(ipAddress, subnetMask, gateway, remanent)
+ _G.logger:fine("New ProfinetIO interface config:")
+ _G.logger:fine("IP Address / NetMask = " .. tostring(ipAddress) .. ' / ' .. tostring(subnetMask))
+ _G.logger:fine("Gateway = " .. tostring(gateway))
+ _G.logger:fine("Remanent = " .. tostring(remanent))
+
+ fieldbus_Model.parameters.profinetIO.ipAddress = ipAddress
+ fieldbus_Model.parameters.profinetIO.subnetMask = subnetMask
+ fieldbus_Model.parameters.profinetIO.gateway = gateway
+ fieldbus_Model.parameters.profinetIO.remanent = remanent
+
+ FieldBus.Config.ProfinetIO.setInterfaceConfig(fieldbus_Model.parameters.profinetIO.ipAddress, fieldbus_Model.parameters.profinetIO.subnetMask, fieldbus_Model.parameters.profinetIO.gateway)
+
+ applyProfinetIOConfig()
+
+ if remanent == true then
+ storeProfinetIOConfig()
+ end
+ CSK_Fieldbus.pageCalled()
+
+end
+
+--- Function to get DAP I&M Config info
+local function getDapImConfigInfo()
+ fieldbus_Model.parameters.profinetIO.dapImDescriptor = FieldBus.Config.ProfinetIO.getDapImDescriptor()
+ fieldbus_Model.parameters.profinetIO.dapImHardwareRev = FieldBus.Config.ProfinetIO.getDapImHardwareRev()
+ fieldbus_Model.parameters.profinetIO.dapImInstallDate = FieldBus.Config.ProfinetIO.getDapImInstallDate()
+ fieldbus_Model.parameters.profinetIO.dapImSoftwareRevPrefix, fieldbus_Model.parameters.profinetIO.dapImSoftwareRevFuncEnhancement, fieldbus_Model.parameters.profinetIO.dapImSoftwareRevBugFix, fieldbus_Model.parameters.profinetIO.dapImSoftwareRevInternalChange = FieldBus.Config.ProfinetIO.getDapImSoftwareRev()
+ fieldbus_Model.parameters.profinetIO.tagFunction = FieldBus.Config.ProfinetIO.getDapImTagFunction()
+ fieldbus_Model.parameters.profinetIO.tagLocation = FieldBus.Config.ProfinetIO.getDapImTagLocation()
+end
+fieldbus_Model.getDapImConfigInfo = getDapImConfigInfo
+
+--- Function to set DAP I&M config
+local function setDapImConfig()
+ FieldBus.Config.ProfinetIO.setDapImDescriptor(fieldbus_Model.parameters.profinetIO.dapImDescriptor)
+ FieldBus.Config.ProfinetIO.setDapImInstallDate(fieldbus_Model.parameters.profinetIO.dapImInstallDate)
+ FieldBus.Config.ProfinetIO.setDapImTagFunction(fieldbus_Model.parameters.profinetIO.tagFunction)
+ FieldBus.Config.ProfinetIO.setDapImTagLocation(fieldbus_Model.parameters.profinetIO.tagLocation)
+end
+fieldbus_Model.setDapImConfig = setDapImConfig
+
+--- Function to store DAP I&M config
+local function storeDapImData()
+ local suc = FieldBus.Config.ProfinetIO.storeDapImData()
+end
+fieldbus_Model.storeDapImData = storeDapImData
+
+--- Function to get DAP I&M config
+local function getProfinetIOConfigInfo()
+ fieldbus_Model.parameters.profinetIO.deviceName = FieldBus.Config.ProfinetIO.getDeviceName()
+ fieldbus_Model.parameters.profinetIO.ipAddress, fieldbus_Model.parameters.profinetIO.subnetMask, fieldbus_Model.parameters.profinetIO.gateway, fieldbus_Model.parameters.profinetIO.remanent = FieldBus.Config.ProfinetIO.getInterfaceConfig()
+
+ local macAddress = FieldBus.Config.ProfinetIO.getMACAddress('INTERFACE')
+ if macAddress then
+ fieldbus_Model.parameters.profinetIO.macAddress = macAddress
+ else
+ fieldbus_Model.parameters.profinetIO.macAddress = ''
+ end
+ getDapImConfigInfo()
+
+ CSK_Fieldbus.pageCalled()
+
+end
+fieldbus_Model.getProfinetIOConfigInfo = getProfinetIOConfigInfo
+
+--- Function to react on FieldbusStoreRequest
+---@param storageHandle FieldBus.StorageRequest Object containing the data to be saved or loaded
+local function handleOnProfinetIOFieldbusStorageRequest(storageHandle)
+ local operation = FieldBus.StorageRequest.getOperation(storageHandle)
+ _G.logger:fine('StorageRequest operation = ' .. tostring(operation))
+ if operation == 'LOAD' then
+ -- Check if file exists
+ local dataFile = File.open(fieldbus_Model.parameters.profinetIO.storageRequestDataPath, 'rb')
+ local setSuc = false
+
+ if dataFile then
+ local data = File.read(dataFile)
+ File.close(dataFile)
+ setSuc = FieldBus.StorageRequest.setData(storageHandle, data)
+ _G.logger:fine("Setting data = " .. tostring(setSuc))
+ getProfinetIOConfigInfo()
+ else
+ _G.logger:info("Not able to LOAD data.")
+ end
+
+ if setSuc then
+ FieldBus.StorageRequest.notifyResult(storageHandle, true)
+ else
+ FieldBus.StorageRequest.notifyResult(storageHandle, false)
+ end
+
+ elseif operation == 'SAVE' then
+ local data = FieldBus.StorageRequest.getData(storageHandle)
+ local dataFile = File.open(fieldbus_Model.parameters.profinetIO.storageRequestDataPath, 'wb')
+
+ local suc = File.write(dataFile, data)
+ File.close(dataFile)
+ _G.logger:fine("Result to write SR = " .. tostring(suc))
+
+ if suc then
+ FieldBus.StorageRequest.notifyResult(storageHandle, true)
+ else
+ FieldBus.StorageRequest.notifyResult(storageHandle, false)
+ end
+ CSK_Fieldbus.pageCalled()
+ end
+end
+
+--TODO only for SIM2000Eco...
+--------------------------------------
--[[
--- Some internal code docu for local used function to do something
----@param content auto Some info text if function is not already served
-local function doSomething(content)
- _G.logger:info(nameOfModule .. ": Do something")
- fieldbus_Model.counter = fieldbus_Model.counter + 1
+local function getProtocolInfo()
+ protocol = FieldBus.Config.getProtocol()
+end
+fieldbus_Model.getProtocolInfo = getProtocolInfo
+
+local function setProtocolConfig()
+ Fieldbus_Controller.Config.setProtocol()
end
-fieldbus_Model.doSomething = doSomething
+fieldbus_Model.setProtocolConfig = setProtocolConfig
]]
+--------------------------------------
+
+-----------------------
+-- General functions --
+-----------------------
+
+-- Function to react on received data of PLC.
+---@param data binary Received data.
+local function handleOnNewData(data)
+ local dataSize = #data
+ _G.logger:fine("Received " .. tostring(dataSize) .. " Bytes = " .. tostring(data))
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "Received " .. tostring(dataSize) .. " Bytes")
+ Script.notifyEvent("Fieldbus_OnNewStatusReceivedData", data)
+
+ local startPos = 1
+ for _, value in ipairs(fieldbus_Model.parameters.dataNamesReceive) do
+ local dataSize = fieldbus_Model.helperFuncs.getTypeSize(fieldbus_Model.parameters.dataTypesReceive[value])
+ if dataSize ~= nil then
+ local dataPart = string.sub(data, startPos, startPos+dataSize-1)
+
+ -- check if value needs to be unpacked first
+ if fieldbus_Model.parameters.convertDataTypesReceive[value] and dataPart ~= nil then
+ dataPart = fieldbus_Model.helperFuncs.convertFromBinary(dataPart, fieldbus_Model.parameters.dataTypesReceive[value], fieldbus_Model.parameters.bigEndiansReceive[value])
+ end
+
+ fieldbus_Model.dataReceived[value] = dataPart
+ Script.notifyEvent('Fieldbus_OnNewData_' .. value, dataPart)
+ startPos = startPos + dataSize
+ else
+ break
+ end
+ end
+ Script.notifyEvent("Fieldbus_OnNewStatusDataReceivingList", fieldbus_Model.helperFuncs.createJsonListReceiveData(fieldbus_Model.parameters.dataNamesReceive, fieldbus_Model.parameters.dataTypesReceive, fieldbus_Model.parameters.convertDataTypesReceive, fieldbus_Model.parameters.bigEndiansReceive, fieldbus_Model.dataReceived, fieldbus_Model.selectedDataReceive))
+end
+
+--- Function to react on received ctrl bits of PLC.
+---@param ctrlBits int ctrl bits out
+local function handleOnControlBitsOutChanged(ctrlBits)
+ _G.logger:fine("New CtrlBitsOut = " .. tostring(ctrlBits))
+ fieldbus_Model.controlBitsOut = ctrlBits
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsOut", fieldbus_Model.controlBitsOut)
+ fieldbus_Model.boolControlBitsOut = fieldbus_Model.helperFuncs.toBits(fieldbus_Model.controlBitsOut)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsOutTable", fieldbus_Model.boolControlBitsOut)
+end
+
+--TODO
+local function deregisterFieldbusEvents()
+ if fieldbus_Model.handle then
+ --FieldBus.deregister(fieldbus_Model.handle, 'OnStatusChanged', handleOnStatusChanged)
+ FieldBus.deregister(fieldbus_Model.handle, 'OnNewData', handleOnNewData)
+ FieldBus.deregister(fieldbus_Model.handle, 'OnControlBitsOutChanged', handleOnControlBitsOutChanged)
+ end
+ Script.deregister('FieldBus.Config.EtherNetIP.OnFieldbusStorageRequest', handleOnEtherNetIPFieldbusStorageRequest)
+ Script.deregister('FieldBus.Config.EtherNetIP.OnAddressingModeChanged', handleOnAddressingModeChanged)
+ Script.deregister('FieldBus.Config.EtherNetIP.OnInterfaceConfigChanged', handleOnEthernetIPInterfaceConfigChanged)
+ Script.deregister('FieldBus.Config.ProfinetIO.OnFieldbusStorageRequest', handleOnProfinetIOFieldbusStorageRequest)
+ Script.deregister('FieldBus.Config.ProfinetIO.OnDeviceNameChanged', handleOnDeviceNameChanged)
+ Script.deregister('FieldBus.Config.ProfinetIO.OnInterfaceConfigChanged', handleOnProfinetIOInterfaceConfigChanged)
+end
+
+-- Function to react on new state of the fieldbus communication.
+---@param status FieldBus.Status New state of the fieldbus communication.
+local function handleOnStatusChanged(status)
+ _G.logger:info("New status = " .. tostring(status))
+ fieldbus_Model.currentStatus = status
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusStatus", fieldbus_Model.currentStatus)
+ getInfo()
+ if fieldbus_Model.currentStatus == 'CLOSED' then
+ fieldbus_Model.opened = false
+ deregisterFieldbusEvents()
+ Script.releaseObject(fieldbus_Model.handle)
+ fieldbus_Model.handle = nil
+ collectgarbage()
+ elseif status == 'OPENED' then
+ fieldbus_Model.opened = true
+ CSK_Fieldbus.setEtherNetIPConfig()
+ elseif status == 'ONLINE' then
+ fieldbus_Model.opened = true
+ elseif status == 'OFFLINE' or status == 'ERROR' then
+ fieldbus_Model.opened = false
+ end
+ Script.notifyEvent("Fieldbus_OnNewStatusFieldbusActive", fieldbus_Model.opened)
+end
+
+--- Function to create fieldbus communication handle
+local function create()
+ if fieldbus_Model.fbMode ~= 'DISABLED' then
+ if not fieldbus_Model.handle then
+ fieldbus_Model.handle = FieldBus.create(fieldbus_Model.parameters.createMode)
+ if fieldbus_Model.handle then
+ FieldBus.setMode(fieldbus_Model.handle, fieldbus_Model.parameters.transmissionMode)
+ _G.logger:fine("Successfully created Fieldbus handle.")
+ getInfo()
+ getStatus()
+
+ deregisterFieldbusEvents()
+ FieldBus.register(fieldbus_Model.handle, 'OnStatusChanged', handleOnStatusChanged)
+ FieldBus.register(fieldbus_Model.handle, 'OnNewData', handleOnNewData)
+ FieldBus.register(fieldbus_Model.handle, 'OnControlBitsOutChanged', handleOnControlBitsOutChanged)
+ if fieldbus_Model.fbMode == 'EtherNetIP' then
+ Script.register('FieldBus.Config.EtherNetIP.OnFieldbusStorageRequest', handleOnEtherNetIPFieldbusStorageRequest)
+ Script.register('FieldBus.Config.EtherNetIP.OnAddressingModeChanged', handleOnAddressingModeChanged)
+ Script.register('FieldBus.Config.EtherNetIP.OnInterfaceConfigChanged', handleOnEthernetIPInterfaceConfigChanged)
+ setEtherNetIPConfig()
+
+ elseif fieldbus_Model.fbMode == 'ProfinetIO' then
+ Script.register('FieldBus.Config.ProfinetIO.OnFieldbusStorageRequest', handleOnProfinetIOFieldbusStorageRequest)
+ Script.register('FieldBus.Config.ProfinetIO.OnDeviceNameChanged', handleOnDeviceNameChanged)
+ Script.register('FieldBus.Config.ProfinetIO.OnInterfaceConfigChanged', handleOnProfinetIOInterfaceConfigChanged)
+
+ end
+ else
+ _G.logger:warning("Not able to create Fieldbus handle.")
+ end
+ else
+ _G.logger:fine("Handle already exists.")
+ end
+ end
+end
+fieldbus_Model.create = create
+
+--- Function to set transmission mode
+---@param mode string Mode to use
+local function setTransmissionMode(mode)
+ if fieldbus_Model.opened == false then
+ if fieldbus_Model.parameters.createMode == 'EXPLICIT_OPEN' and fieldbus_Model.opened ~= true then
+ fieldbus_Model.parameters.transmissionMode = mode
+ if fieldbus_Model.handle then
+ FieldBus.setMode(fieldbus_Model.handle, fieldbus_Model.parameters.transmissionMode)
+ end
+ else
+ _G.logger:info("Transmission mode only selectable if create mode is 'EXPLICIT_OPEN'.")
+ end
+ else
+ _G.logger:info("Cannot set mode of fieldbus, it is already open.")
+ end
+ Script.notifyEvent("Fieldbus_OnNewStatusTransmissionMode", fieldbus_Model.parameters.transmissionMode)
+end
+fieldbus_Model.setTransmissionMode = setTransmissionMode
+
+--- Function to open fieldbus communication
+local function openCommunication()
+ local success = false
+ create()
+ fieldbus_Model.parameters.active = true
+ if fieldbus_Model.handle then
+ if fieldbus_Model.parameters.createMode == 'EXPLICIT_OPEN' then
+ fieldbus_Model.handle:open()
+ end
+ success = true
+ else
+ _G.logger:warning("Not able to open fieldbus communication.")
+ end
+ return success
+end
+fieldbus_Model.openCommunication = openCommunication
+
+--- Function to close fieldbus communication
+local function closeCommunication()
+ if fieldbus_Model.handle then
+ fieldbus_Model.handle:close()
+ fieldbus_Model.parameters.active = false
+ end
+end
+fieldbus_Model.closeCommunication = closeCommunication
+
+--- Function to read controlBitsIn
+local function readControlBitsIn()
+ if fieldbus_Model.handle then
+ fieldbus_Model.controlBitsIn = fieldbus_Model.handle:readControlBitsIn()
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsIn", fieldbus_Model.controlBitsIn)
+ fieldbus_Model.boolControlBitsIn = fieldbus_Model.helperFuncs.toBits(fieldbus_Model.controlBitsIn)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsInTable", fieldbus_Model.boolControlBitsIn)
+ end
+end
+fieldbus_Model.readControlBitsIn = readControlBitsIn
+
+--- Function to read controlBitsOut
+local function readControlBitsOut()
+ if fieldbus_Model.handle then
+ fieldbus_Model.controlBitsOut = fieldbus_Model.handle:readControlBitsOut()
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsOut", fieldbus_Model.controlBitsOut)
+ fieldbus_Model.boolControlBitsOut = fieldbus_Model.helperFuncs.toBits(fieldbus_Model.controlBitsOut)
+ Script.notifyEvent("Fieldbus_OnNewStatusControlBitsOutTable", fieldbus_Model.boolControlBitsOut)
+ end
+end
+fieldbus_Model.readControlBitsOut = readControlBitsOut
+
+--- Function to transmit data
+---@param data binary Data content to transmit
+local function transmit(data)
+ if fieldbus_Model.handle then
+ local numberOfBytes = fieldbus_Model.handle:transmit(data)
+ if numberOfBytes ~= 0 then
+ _G.logger:fine("Send " .. tostring(numberOfBytes) .. " data Bytes.")
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "Send " .. tostring(numberOfBytes) .. " data Bytes.")
+ else
+ _G.logger:warning("Transmit error.")
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "Transmit error.")
+ end
+ else
+ _G.logger:info("No connection available to transmit.")
+ Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', "No connection available to transmit.")
+ end
+end
+fieldbus_Model.transmit = transmit
+
+--- Function to write controlBitsIn
+---@param controlBits int Bits to write
+---@param bitMask int Mask to use for bits
+local function writeControlBitsIn(controlBits, bitMask)
+ if fieldbus_Model.handle then
+ _G.logger:fine("Send controlBits")
+ fieldbus_Model.handle:writeControlBitsIn(controlBits, bitMask)
+ end
+end
+fieldbus_Model.writeControlBitsIn = writeControlBitsIn
+
+--- Function to write data to table to transmit
+---@param pos int Position of data to update
+---@param data auto Data content to set
+local function updateTransmitData(pos, data)
+ --_G.logger:fine("Set data" .. tostring(pos) .. ' with data = ' .. tostring(data)) --DEBUG
+ fieldbus_Model.dataToTransmit[pos] = data
+
+ fieldbus_Model.fullDataToTransmit = ''
+ for key, value in ipairs(fieldbus_Model.dataToTransmit) do
+ fieldbus_Model.fullDataToTransmit = fieldbus_Model.fullDataToTransmit .. value
+ end
+
+ --DEBUG
+ --[[
+ local readableTransmitData = ''
+ for key, value in ipairs(fieldbus_Model.readableDataToTransmit) do
+ if readableTransmitData == '' then
+ readableTransmitData = value
+ else
+ readableTransmitData = readableTransmitData .. ',' .. value
+ end
+ end
+ _G.logger:fine("Send: " .. readableTransmitData)
+
+ -- Additional debugging
+ --_G.logger:fine(fieldbus_Model.fullDataToTransmit)
+ --_G.logger:fine(#fieldbus_Model.fullDataToTransmit)
+ --Script.notifyEvent('Fieldbus_OnNewStatusLogMessage', tostring(fieldbus_Model.fullDataToTransmit) .. ', Send data bytes = ' .. tostring(#fieldbus_Model.fullDataToTransmit))
+ --Script.notifyEvent("Fieldbus_OnNewStatusDataToTransmit", fieldbus_Model.dataToTransmit)
+ ]]
+
+ --TODO
+ --print(fieldbus_Model.fullDataToTransmit)
+ --print(#fieldbus_Model.fullDataToTransmit)
+
+ if fieldbus_Model.currentStatus == 'ONLINE' then
+ transmit(fieldbus_Model.fullDataToTransmit)
+ end
+end
+fieldbus_Model.updateTransmitData = updateTransmitData
+
+--- Function to register to event of (other) module to receive data and to transmit/forward it
+---@param eventName int Name of event to register
+---@param dataPosition auto Position of data
+---@param dataName string Identifier of data
+local function registerToEvent(eventName, dataPosition, dataName)
+
+ local emptyData = fieldbus_Model.helperFuncs.getEmptyBinaryContent(fieldbus_Model.parameters.dataTypesTransmit[dataName])
+ if fieldbus_Model.dataToTransmit[dataPosition] then
+ fieldbus_Model.dataToTransmit[dataPosition] = emptyData
+ else
+ table.insert(fieldbus_Model.dataToTransmit, emptyData)
+ end
+
+ if fieldbus_Model.readableDataToTransmit[dataPosition] then
+ fieldbus_Model.readableDataToTransmit[dataPosition] = 'empty'
+ else
+ table.insert(fieldbus_Model.readableDataToTransmit, 'empty')
+ end
+
+ local function updateData(data)
+ _G.logger:fine("Set data" .. tostring(dataPosition) .. ' with data = ' .. tostring(data))
+ fieldbus_Model.readableDataToTransmit[dataPosition] = data
+
+ if fieldbus_Model.parameters.convertDataTypesTransmit[dataName] then
+ data = fieldbus_Model.helperFuncs.convertToBinary(data, fieldbus_Model.parameters.dataTypesTransmit[dataName], fieldbus_Model.parameters.bigEndiansTransmit[dataName])
+ end
+ updateTransmitData(dataPosition, data)
+ end
+ fieldbus_Model.dataUpdateFunctions[dataName] = updateData
+
+ Script.register(eventName, fieldbus_Model.dataUpdateFunctions[dataName])
+end
+fieldbus_Model.registerToEvent = registerToEvent
+
+--- Function to deregister from all events for data to transmit
+local function deregisterAllEvents()
+ for key, value in pairs(fieldbus_Model.parameters.dataNamesTransmit) do
+ Script.deregister(fieldbus_Model.parameters.registeredEventsTransmit[value], fieldbus_Model.dataUpdateFunctions[value])
+ end
+ fieldbus_Model.dataToTransmit = {}
+ fieldbus_Model.readableDataToTransmit = {}
+end
+fieldbus_Model.deregisterAllEvents = deregisterAllEvents
+
+--- Function to register all events for data to transmit
+local function registerAllEvents()
+ for key, value in ipairs(fieldbus_Model.parameters.dataNamesTransmit) do
+ registerToEvent(fieldbus_Model.parameters.registeredEventsTransmit[value], key, value)
+ end
+end
+fieldbus_Model.registerAllEvents = registerAllEvents
+
+--- Function to add empty value (but with correct byte size) for data to transmit
+---@param dataType string Type of data
+local function addEmptySpace(dataType)
+ -- Insert empty spaces according to dataType...
+ local emptyData = fieldbus_Model.helperFuncs.getEmptyBinaryContent(dataType)
+ table.insert(fieldbus_Model.dataToTransmit, emptyData)
+ table.insert(fieldbus_Model.readableDataToTransmit, 'empty')
+end
+fieldbus_Model.addEmptySpace = addEmptySpace
+
+--- Function to add new data entry to transmit
+---@param dataName string Name/identifier of data
+---@param eventName string Name of event to register
+---@param convert bool Status if incoming value needs to be converted to binary
+---@param dataType string Type of data
+---@param bigEndian bool Type of endianess
+local function addDataTransmit(dataName, eventName, convert, dataType, bigEndian)
+ table.insert(fieldbus_Model.parameters.dataNamesTransmit, dataName)
+ addEmptySpace(dataType)
+
+ fieldbus_Model.parameters.dataTypesTransmit[dataName] = dataType
+ fieldbus_Model.parameters.registeredEventsTransmit[dataName] = eventName
+ fieldbus_Model.parameters.convertDataTypesTransmit[dataName] = convert
+ fieldbus_Model.parameters.bigEndiansTransmit[dataName] = bigEndian
+
+ registerToEvent(eventName, #fieldbus_Model.parameters.dataNamesTransmit, dataName)
+end
+fieldbus_Model.addDataTransmit = addDataTransmit
+
+--- Function to serve events to notify for received values
+---@param dataName string Name/identifier of data
+local function serveReceiveEvent(dataName)
+ if not Script.isServedAsEvent('CSK_Fieldbus.OnNewData_' .. dataName) then
+ Script.serveEvent('CSK_Fieldbus.OnNewData_' .. dataName, 'Fieldbus_OnNewData_' .. dataName, 'auto:?')
+ end
+end
+fieldbus_Model.serveReceiveEvent = serveReceiveEvent
+
+--- Function to add new data entry to receive
+---@param dataName string Name/identifier of data
+---@param convert bool Status if incoming value needs to be converted to binary
+---@param dataType string Type of data
+---@param bigEndian bool Type of endianess
+local function addDataReceive(dataName, convert, dataType, bigEndian)
+ table.insert(fieldbus_Model.parameters.dataNamesReceive, dataName)
+
+ fieldbus_Model.parameters.dataTypesReceive[dataName] = dataType
+ fieldbus_Model.parameters.convertDataTypesReceive[dataName] = convert
+ fieldbus_Model.parameters.bigEndiansReceive[dataName] = bigEndian
+ fieldbus_Model.dataReceived[dataName] = '-'
+
+ serveReceiveEvent(dataName)
+
+end
+fieldbus_Model.addDataReceive = addDataReceive
+
+--- Function to remove data entry to transmit
+---@param dataNo int Number of data entry
+local function removeDataTransmit(dataNo)
+ local dataName = fieldbus_Model.parameters.dataNamesTransmit[dataNo]
+
+ deregisterAllEvents()
+
+ fieldbus_Model.parameters.dataTypesTransmit[dataName] = nil
+ fieldbus_Model.parameters.registeredEventsTransmit[dataName] = nil
+ fieldbus_Model.parameters.convertDataTypesTransmit[dataName] = nil
+ fieldbus_Model.parameters.bigEndiansTransmit[dataName] = nil
+
+ table.remove(fieldbus_Model.parameters.dataNamesTransmit, dataNo)
+ registerAllEvents()
+ collectgarbage()
+end
+fieldbus_Model.removeDataTransmit = removeDataTransmit
+
+--- Function to remove data entry to receive
+---@param dataNo int Number of data entry
+local function removeDataReceive(dataNo)
+ local dataName = fieldbus_Model.parameters.dataNamesReceive[dataNo]
+
+ fieldbus_Model.parameters.dataTypesReceive[dataName] = nil
+ fieldbus_Model.parameters.convertDataTypesReceive[dataName] = nil
+ fieldbus_Model.parameters.bigEndiansReceive[dataName] = nil
+ fieldbus_Model.dataReceived[dataName] = nil
+
+ table.remove(fieldbus_Model.parameters.dataNamesReceive, dataNo)
+end
+fieldbus_Model.removeDataReceive = removeDataReceive
+
+--- Function to move the position of the transmit data about one position higher
+---@param dataNo int Position of data
+local function dataTransmitPositionUp(dataNo)
+ if dataNo ~= 1 then
+ deregisterAllEvents()
+
+ local tempDataName = fieldbus_Model.parameters.dataNamesTransmit[dataNo]
+ table.insert(fieldbus_Model.parameters.dataNamesTransmit, dataNo-1, tempDataName)
+ table.remove(fieldbus_Model.parameters.dataNamesTransmit, dataNo+1)
+ collectgarbage()
+
+ registerAllEvents()
+ fieldbus_Model.selectedDataTransmit = tostring(dataNo-1)
+ end
+end
+fieldbus_Model.dataTransmitPositionUp = dataTransmitPositionUp
+
+--- Function to move the position of the data to receive about one position higher
+---@param dataNo int Position of data
+local function dataReceivePositionUp(dataNo)
+ if dataNo ~= 1 then
+
+ local tempDataName = fieldbus_Model.parameters.dataNamesReceive[dataNo]
+ table.insert(fieldbus_Model.parameters.dataNamesReceive, dataNo-1, tempDataName)
+ table.remove(fieldbus_Model.parameters.dataNamesReceive, dataNo+1)
+ collectgarbage()
+
+ fieldbus_Model.selectedDataReceive = tostring(dataNo-1)
+ end
+end
+fieldbus_Model.dataReceivePositionUp = dataReceivePositionUp
+
+--- Function to move the position of the data to transmit about one position lower
+---@param dataNo int Position of data
+local function dataTransmitPositionDown(dataNo)
+ if dataNo ~= #fieldbus_Model.parameters.dataNamesTransmit then
+ deregisterAllEvents()
+
+ local tempDataName = fieldbus_Model.parameters.dataNamesTransmit[dataNo]
+ table.remove(fieldbus_Model.parameters.dataNamesTransmit, dataNo)
+ table.insert(fieldbus_Model.parameters.dataNamesTransmit, dataNo+1, tempDataName)
+ collectgarbage()
+
+ registerAllEvents()
+ fieldbus_Model.selectedDataTransmit = tostring(dataNo+1)
+ end
+end
+fieldbus_Model.dataTransmitPositionDown = dataTransmitPositionDown
+
+--- Function to move the position of the data to receive about one position lower
+---@param dataNo int Position of data
+local function dataReceivePositionDown(dataNo)
+ if dataNo ~= #fieldbus_Model.parameters.dataNamesReceive then
+
+ local tempDataName = fieldbus_Model.parameters.dataNamesReceive[dataNo]
+ table.remove(fieldbus_Model.parameters.dataNamesReceive, dataNo)
+ table.insert(fieldbus_Model.parameters.dataNamesReceive, dataNo+1, tempDataName)
+ collectgarbage()
+
+ fieldbus_Model.selectedDataReceive = tostring(dataNo+1)
+ end
+end
+fieldbus_Model.dataReceivePositionDown = dataReceivePositionDown
+
+--- Function to reset all data to transmit
+local function resetTransmitData()
+ for key, value in ipairs(fieldbus_Model.parameters.dataNamesTransmit) do
+ local emptyData = fieldbus_Model.helperFuncs.getEmptyBinaryContent(fieldbus_Model.parameters.dataTypesTransmit[value])
+ fieldbus_Model.dataToTransmit[key] = emptyData
+ fieldbus_Model.readableDataToTransmit[key] = 'empty'
+ end
+
+ if fieldbus_Model.currentStatus == 'ONLINE' then
+ fieldbus_Model.fullDataToTransmit = ''
+ for key, value in ipairs(fieldbus_Model.dataToTransmit) do
+ fieldbus_Model.fullDataToTransmit = fieldbus_Model.fullDataToTransmit .. value
+ end
+ transmit(fieldbus_Model.fullDataToTransmit)
+ end
+end
+fieldbus_Model.resetTransmitData = resetTransmitData
--*************************************************************************
--********************** End Function Scope *******************************
diff --git a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/FlowConfig/Fieldbus_FlowConfig.lua b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/FlowConfig/Fieldbus_FlowConfig.lua
new file mode 100644
index 0000000..9de3c7d
--- /dev/null
+++ b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/FlowConfig/Fieldbus_FlowConfig.lua
@@ -0,0 +1,31 @@
+--*****************************************************************
+-- Here you will find all the required content to provide specific
+-- features of this module via the 'CSK FlowConfig'.
+--*****************************************************************
+
+require('Communication.Fieldbus.FlowConfig.Fieldbus_OnNewData')
+require('Communication.Fieldbus.FlowConfig.Fieldbus_Transmit')
+
+-- Reference to the fieldbus_Instances handle
+local fieldbus_Instances
+
+--- Function to react if FlowConfig was updated
+local function handleOnClearOldFlow()
+ if _G.availableAPIs.default and _G.availableAPIs.specific then
+ for i = 1, #fieldbus_Instances do
+ if fieldbus_Instances[i].parameters.flowConfigPriority then
+ CSK_Fieldbus.clearFlowConfigRelevantConfiguration()
+ break
+ end
+ end
+ end
+end
+Script.register('CSK_FlowConfig.OnClearOldFlow', handleOnClearOldFlow)
+
+--- Function to get access to the fieldbus_Instances
+---@param handle handle Handle of fieldbus_Instances object
+local function setFieldbus_Instances_Handle(handle)
+ fieldbus_Instances = handle
+end
+
+return setFieldbus_Instances_Handle
\ No newline at end of file
diff --git a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/checkAPIs.lua b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/checkAPIs.lua
index 929c733..36ea4f4 100644
--- a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/checkAPIs.lua
+++ b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/checkAPIs.lua
@@ -6,14 +6,16 @@
local availableAPIs = {}
local function loadAPIs()
- CSK_ModuleName = require 'API.CSK_ModuleName'
+ CSK_Fieldbus = require 'API.CSK_Fieldbus'
Container = require 'API.Container'
Engine = require 'API.Engine'
+ File = require 'API.File'
Log = require 'API.Log'
Log.Handler = require 'API.Log.Handler'
Log.SharedLogger = require 'API.Log.SharedLogger'
Object = require 'API.Object'
+ Parameters = require 'API.Parameters'
Timer = require 'API.Timer'
-- Check if related CSK modules are available to be used
@@ -30,7 +32,11 @@ end
local function loadSpecificAPIs()
-- If you want to check for specific APIs/functions supported on the device the module is running, place relevant APIs here
-- e.g.:
- -- NTPClient = require 'API.NTPClient'
+ FieldBus = require 'API.FieldBus'
+ FieldBus.Config = require 'API.FieldBus.Config'
+ FieldBus.Config.EtherNetIP = require 'API.FieldBus.Config.EtherNetIP'
+ FieldBus.Config.ProfinetIO = require 'API.FieldBus.Config.ProfinetIO'
+ FieldBus.StorageRequest = require 'API.FieldBus.StorageRequest'
end
availableAPIs.default = xpcall(loadAPIs, debug.traceback) -- TRUE if all default APIs were loaded correctly
diff --git a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/funcs.lua b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/funcs.lua
index b1c30bf..7c6ed55 100644
--- a/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/funcs.lua
+++ b/CSK_Module_Fieldbus/scripts/Communication/Fieldbus/helper/funcs.lua
@@ -142,6 +142,423 @@ local function createStringListBySimpleTable(content)
end
funcs.createStringListBySimpleTable = createStringListBySimpleTable
+--- Function to convert value out of binary string
+---@param value binary Binary string
+---@param format string Format the value is packed
+---@param bigEndian bool Status if big endian is used. Otherwise little endian is active
+---@return auto result Converted value
+local function convertFromBinary(value, format, bigEndian)
+ local result
+ local endianness = '<' -- little endian per default
+ if bigEndian == true then
+ endianness = '>'
+ end
+
+ if format == 'DOUBLE' then
+ result = string.unpack(endianness .. 'd', value)
+ elseif format == 'FLOAT' then
+ result = string.unpack(endianness .. 'f', value)
+ elseif format == 'S_BYTE' then
+ result = string.unpack(endianness .. 'b', value)
+ elseif format == 'S_INT1' then
+ result = string.unpack(endianness .. 'i1', value)
+ elseif format == 'S_INT2' then
+ result = string.unpack(endianness .. 'i2', value)
+ elseif format == 'S_INT4' then
+ result = string.unpack(endianness .. 'i4', value)
+ elseif format == 'S_INT8' then
+ result = string.unpack(endianness .. 'i8', value)
+ elseif format == 'S_LONG' then
+ result = string.unpack(endianness .. 'l', value)
+ elseif format == 'S_SHORT' then
+ result = string.unpack(endianness .. 'h', value)
+ elseif format == 'U_BYTE' then
+ result = string.unpack(endianness .. 'B', value)
+ elseif format == 'U_INT1' then
+ result = string.unpack(endianness .. 'I1', value)
+ elseif format == 'U_INT2' then
+ result = string.unpack(endianness .. 'I2', value)
+ elseif format == 'U_INT4' then
+ result = string.unpack(endianness .. 'I4', value)
+ elseif format == 'U_INT8' then
+ result = string.unpack(endianness .. 'I8', value)
+ elseif format == 'U_LONG' then
+ result = string.unpack(endianness .. 'L', value)
+ elseif format == 'U_SHORT' then
+ result = string.unpack(endianness .. 'H', value)
+ elseif format == 'CHAR' then
+ result = string.unpack(endianness .. 'c1', value)
+ --elseif format == 'STRING' then
+ --result = string.unpack(endianness .. 'c14xx', value)
+ --result = string.unpack(endianness .. 's2', value)
+ end
+ return result
+end
+funcs.convertFromBinary = convertFromBinary
+
+--- Function to convert value to binary string
+---@param value auto Value to convert
+---@param format string Format the value is packed
+---@param bigEndian bool Status if big endian is used. Otherwise little endian is active
+---@return binary result Converted value
+local function convertToBinary(value, format, bigEndian)
+ local result
+ local endianness = '<' -- little endian per default
+ if bigEndian == true then
+ endianness = '>'
+ end
+
+ if format == 'DOUBLE' then
+ result = string.pack(endianness .. 'd', value)
+ elseif format == 'FLOAT' then
+ result = string.pack(endianness .. 'f', value)
+ elseif format == 'S_BYTE' then
+ result = string.pack(endianness .. 'b', value)
+ elseif format == 'S_INT1' then
+ result = string.pack(endianness .. 'i1', value)
+ elseif format == 'S_INT2' then
+ result = string.pack(endianness .. 'i2', value)
+ elseif format == 'S_INT4' then
+ result = string.pack(endianness .. 'i4', value)
+ elseif format == 'S_INT8' then
+ result = string.pack(endianness .. 'i8', value)
+ elseif format == 'S_LONG' then
+ result = string.pack(endianness .. 'l', value)
+ elseif format == 'S_SHORT' then
+ result = string.pack(endianness .. 'h', value)
+ elseif format == 'U_BYTE' then
+ result = string.pack(endianness .. 'B', value)
+ elseif format == 'U_INT1' then
+ result = string.pack(endianness .. 'I1', value)
+ elseif format == 'U_INT2' then
+ result = string.pack(endianness .. 'I2', value)
+ elseif format == 'U_INT4' then
+ result = string.pack(endianness .. 'I4', value)
+ elseif format == 'U_INT8' then
+ result = string.pack(endianness .. 'I8', value)
+ elseif format == 'U_LONG' then
+ result = string.pack(endianness .. 'L', value)
+ elseif format == 'U_SHORT' then
+ result = string.pack(endianness .. 'H', value)
+ elseif format == 'CHAR' then
+ if #value >= 2 then
+ value = string.sub(value, 1, 1)
+ end
+ result = string.pack(endianness .. 'c1', value)
+ --elseif format == 'STRING' then
+ -- if #value >= 15 then
+ -- value = string.sub(value, 1, 14)
+ -- end
+ -- result = string.pack(endianness .. 's2', value)
+ end
+ return result
+end
+funcs.convertToBinary = convertToBinary
+
+--- Function to create binary string with size of related format and value '0'
+---@param format string Format the value is packed
+---@return binary result Empty value
+local function getEmptyBinaryContent(format)
+ local result
+
+ if format == 'DOUBLE' then
+ result = string.pack('d', 0)
+ elseif format == 'FLOAT' then
+ result = string.pack('f', 0)
+ elseif format == 'S_BYTE' then
+ result = string.pack('b', 0)
+ elseif format == 'S_INT1' then
+ result = string.pack('i1', 0)
+ elseif format == 'S_INT2' then
+ result = string.pack('i2', 0)
+ elseif format == 'S_INT4' then
+ result = string.pack('i4', 0)
+ elseif format == 'S_INT8' then
+ result = string.pack('i8', 0)
+ elseif format == 'S_LONG' then
+ result = string.pack('l', 0)
+ elseif format == 'S_SHORT' then
+ result = string.pack('h', 0)
+ elseif format == 'U_BYTE' then
+ result = string.pack('B', 0)
+ elseif format == 'U_INT1' then
+ result = string.pack('I1', 0)
+ elseif format == 'U_INT2' then
+ result = string.pack('I2', 0)
+ elseif format == 'U_INT4' then
+ result = string.pack('I4', 0)
+ elseif format == 'U_INT8' then
+ result = string.pack('I8', 0)
+ elseif format == 'U_LONG' then
+ result = string.pack('L', 0)
+ elseif format == 'U_SHORT' then
+ result = string.pack('H', 0)
+ elseif format == 'CHAR' then
+ result = string.pack('x', '')
+ --elseif format == 'STRING' then
+ -- result = string.pack('s2', '')
+ end
+
+ return result
+end
+funcs.getEmptyBinaryContent = getEmptyBinaryContent
+
+--- Function to create a json string out of data transmission entries
+---@param dataName string[] Table with names of data entries
+---@param registerEvent string[] Table with names of registered events of data entries
+---@param dataType string[] Table with data types of data entries
+---@param convertData string[] Table with info if data needs to be converted
+---@param bigEndian string[] Table with info about endianness of data entries
+---@param values string[] Table with values to transmit
+---@param selectedParam string Currently selected parameter
+---@return string jsonstring JSON string
+local function createJsonListTransmissionData(dataName, registerEvent, dataType, convertData, bigEndian, values, selectedParam)
+
+ local list = {}
+ if dataName == nil then
+ list = {{DTC_IDTransmit = '-', DTC_NameTransmit = '-', DTC_EventTransmit = '-', DTC_DataTypeTransmit = '-', DTC_ConvertTransmit = '-', DTC_BigEndianTransmit = '-', DTC_ValueTransmit = '-'},}
+ else
+
+ for key, value in ipairs(dataName) do
+ local isSelected = false
+ if tostring(key) == selectedParam then
+ isSelected = true
+ end
+ table.insert(list, {DTC_IDTransmit = tostring(key), DTC_NameTransmit = value, DTC_EventTransmit = registerEvent[value], DTC_DataTypeTransmit = dataType[value], DTC_ConvertTransmit = convertData[value], DTC_BigEndianTransmit = bigEndian[value], DTC_ValueTransmit = tostring(values[key]), selected = isSelected})
+ end
+
+ if #list == 0 then
+ list = {{DTC_IDTransmit = '-', DTC_NameTransmit = '-', DTC_EventTransmit = '-', DTC_DataTypeTransmit = '-', DTC_ConvertTransmit = '-', DTC_BigEndianTransmit = '-', DTC_ValueTransmit = '-'},}
+ end
+ end
+
+ local jsonstring = funcs.json.encode(list)
+ return jsonstring
+end
+funcs.createJsonListTransmissionData = createJsonListTransmissionData
+
+--- Function to create a json string out of data receive entries
+---@param dataName string[] Table with names of data entries
+---@param dataType string[] Table with data types of data entries
+---@param convertData string[] Table with info if data needs to be converted
+---@param bigEndian string[] Table with info about endianness of data entries
+---@param values string[] Table with received values
+---@param selectedParam string Currently selected parameter
+---@return string jsonstring JSON string
+local function createJsonListReceiveData(dataName, dataType, convertData, bigEndian, values, selectedParam)
+
+ local list = {}
+ if dataName == nil then
+ list = {{DTC_IDReceive = '-', DTC_NameReceive = '-', DTC_DataTypeReceive = '-', DTC_ConvertReceive = '-', DTC_BigEndianReceive = '-', DTC_ValueReceive = '-'},}
+ else
+
+ for key, value in ipairs(dataName) do
+ local isSelected = false
+ if tostring(key) == selectedParam then
+ isSelected = true
+ end
+ table.insert(list, {DTC_IDReceive = tostring(key), DTC_NameReceive = value, DTC_DataTypeReceive = dataType[value], DTC_ConvertReceive = convertData[value], DTC_BigEndianReceive = bigEndian[value], DTC_ValueReceive = tostring(values[value]), selected = isSelected})
+ end
+
+ if #list == 0 then
+ list = {{DTC_IDReceive = '-', DTC_NameReceive = '-', DTC_DataTypeReceive = '-', DTC_ConvertReceive = '-', DTC_BigEndianReceive = '-', DTC_ValueReceive = '-'},}
+ end
+ end
+
+ local jsonstring = funcs.json.encode(list)
+ return jsonstring
+end
+funcs.createJsonListReceiveData = createJsonListReceiveData
+
+--- Function to convert number to related bit table
+---@param num int Number to convert
+---@return bool[]? allValues Table of boolean values per bit
+local function toBits(num)
+ local res = ''
+ local allValues = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}
+ for i = 16, 1, -1 do
+ local temp = math.fmod(num, 2)
+ if temp == 1 then
+ allValues[(16+1)-i] = true
+ end
+ num = math.floor((num - temp)/2)
+ end
+ if num == 0 then
+ return allValues
+ else
+ return nil
+ end
+end
+funcs.toBits = toBits
+
+--- Function to convert bit values to related number
+---@param values bool[]? Bit structure to convert
+---@return int result Number
+local function toNumber(values)
+ local result = 0
+ for key, value in ipairs(values) do
+ if value == true then
+ result = result + 2^(key -1)
+ end
+ end
+ return result
+end
+funcs.toNumber = toNumber
+
+--- Function to get info about the total data size
+---@param data string[] Table with info about data types to use
+---@return int size Sum of all bytes of data types
+local function getDataSize(data)
+ local size = 0
+ for key, value in pairs(data) do
+ if value == 'DOUBLE' then
+ size = size + 8
+ elseif value == 'FLOAT' then
+ size = size + 4
+ elseif value == 'S_BYTE' then
+ size = size + 1
+ elseif value == 'S_INT1' then
+ size = size + 1
+ elseif value == 'S_INT2' then
+ size = size + 2
+ elseif value == 'S_INT4' then
+ size = size + 4
+ elseif value == 'S_INT8' then
+ size = size + 8
+ elseif value == 'S_LONG' then
+ size = size + 4
+ elseif value == 'S_SHORT' then
+ size = size + 2
+ elseif value == 'U_BYTE' then
+ size = size + 1
+ elseif value == 'U_INT1' then
+ size = size + 1
+ elseif value == 'U_INT2' then
+ size = size + 2
+ elseif value == 'U_INT4' then
+ size = size + 4
+ elseif value == 'U_INT8' then
+ size = size + 8
+ elseif value == 'U_LONG' then
+ size = size + 4
+ elseif value == 'U_SHORT' then
+ size = size + 2
+ elseif value == 'CHAR' then
+ size = size + 1
+ --elseif value == 'STRING' then
+ -- size = size + 16
+ end
+ end
+ return size
+end
+funcs.getDataSize = getDataSize
+
+--- Function to get info about the data size of a specific data type
+---@param dataType string Data type to use
+---@return int? result Amount of bytes of data type
+local function getTypeSize(dataType)
+ if dataType == 'DOUBLE' then
+ return 8
+ elseif dataType == 'FLOAT' then
+ return 4
+ elseif dataType == 'S_BYTE' then
+ return 1
+ elseif dataType == 'S_INT1' then
+ return 1
+ elseif dataType == 'S_INT2' then
+ return 2
+ elseif dataType == 'S_INT4' then
+ return 4
+ elseif dataType == 'S_INT8' then
+ return 8
+ elseif dataType == 'S_LONG' then
+ return 4
+ elseif dataType == 'S_SHORT' then
+ return 2
+ elseif dataType == 'U_BYTE' then
+ return 1
+ elseif dataType == 'U_INT1' then
+ return 1
+ elseif dataType == 'U_INT2' then
+ return 2
+ elseif dataType == 'U_INT4' then
+ return 4
+ elseif dataType == 'U_INT8' then
+ return 8
+ elseif dataType == 'U_LONG' then
+ return 4
+ elseif dataType == 'U_SHORT' then
+ return 2
+ elseif dataType == 'CHAR' then
+ return 1
+ --elseif dataType == 'STRING' then
+ -- return 16
+ else
+ return nil
+ end
+end
+funcs.getTypeSize = getTypeSize
+
+local function addTabs(str, tab)
+ if tab > 0 then
+ for _=1, tab do
+ str = '\t' .. str
+ end
+ end
+ return str
+end
+local function min(arr)
+ if #arr == 0 then
+ return nil
+ end
+ table.sort(arr)
+ return arr[1]
+end
+
+local function jsonLine2Table(intiStr, startInd, tab, resStr)
+ if not intiStr then return '' end
+ if not startInd then startInd = 1 end
+ if not tab then tab = 0 end
+ if not resStr then resStr = '' end
+ local compArray = {}
+ local nextSqBrOp = string.find(intiStr, '%[', startInd)
+ if nextSqBrOp then table.insert(compArray, nextSqBrOp) end
+ local nextSqBrCl = string.find(intiStr, '%]', startInd)
+ if nextSqBrCl then table.insert(compArray, nextSqBrCl) end
+ local nextCuBrCl = string.find(intiStr, '}', startInd)
+ if nextCuBrCl then table.insert(compArray, nextCuBrCl) end
+ local nextCuBrOp = string.find(intiStr, '{', startInd)
+ if nextCuBrOp then table.insert(compArray, nextCuBrOp) end
+ local nextComma = string.find(intiStr, ',', startInd)
+ if nextComma then table.insert(compArray, nextComma) end
+ local minVal = min(compArray)
+ if minVal then
+ local currentSymbol = string.sub(intiStr, minVal, minVal)
+ local content = ''
+ if startInd < minVal then
+ content = string.sub(intiStr, startInd, minVal-1)
+ end
+ if minVal == nextCuBrOp or minVal == nextSqBrOp then
+ resStr = resStr .. addTabs(content .. currentSymbol .. '\n', tab)
+ tab = tab + 1
+
+ elseif minVal == nextCuBrCl or minVal == nextSqBrCl then
+ resStr = resStr .. addTabs(content, tab) .. '\n'
+ tab = tab - 1
+ resStr = resStr .. addTabs(currentSymbol, tab)
+ elseif nextComma and minVal == nextComma then
+ if content == '' then
+ resStr = resStr.. currentSymbol .. '\n'
+ else
+ resStr = resStr .. addTabs(content .. currentSymbol .. '\n', tab)
+ end
+ end
+ resStr = jsonLine2Table(intiStr, minVal+1, tab, resStr)
+ end
+ return resStr
+end
+funcs.jsonLine2Table = jsonLine2Table
+
return funcs
--**************************************************************************
diff --git a/README.md b/README.md
index 3c9d355..0778b78 100644
--- a/README.md
+++ b/README.md
@@ -1,33 +1,27 @@
# CSK_Module_Fieldbus
-## INFO: Draft version. Not further developed / tested so far! Check for available GitHub forks of this repository to see latest updates.
+Module to provide fieldbus communication functionality.
-Module / Application to provide [...] functionality.
-
-*If available, please also add a screenshot/gif of the UI of the module here placed within /docu/media/ (see code)*
-
+
## How to Run
-[***...please fill with informations...***]
-For further information check out the [documentation](https://raw.githack.com/SICKAppSpaceCodingStarterKit/[REPO_OF_MODULE]/main/docu/CSK_Module_[MODULENAME].html) [update link] in the folder "docu".
+The app includes an intuitive GUI to setup the fieldbus communication.
+For further information check out the [documentation](https://raw.githack.com/golluroSICKAG/CSK_Module_Fieldbus/main/docu/CSK_Module_Fieldbus.html) in the folder "docu".
## Information
Tested on:
-[Device] - [firmware]
-...
-
-[***optionally***]
-Following CSK modules are used for this application via Git subtrees and should NOT be further developed within this repository (see [contribution guideline](https://github.com/SICKAppSpaceCodingStarterKit/.github/blob/main/Contribution_Guideline.md) of this GitHub organization):
-
- * CSK_Module_XYZ (release/tag v1.2.3)
-
-This application / module is part of the SICK AppSpace Coding Starter Kit developing approach.
-It is programmed in an object oriented way. Some of the modules use kind of "classes" in Lua to make it possible to reuse code / classes in other projects.
-In general it is not neccessary to code this way, but the architecture of this app can serve as a sample to be used especially for bigger projects and to make it easier to share code.
+|Device|Firmware|Module version
+|--|--|--|
+|SIM 2x00|V1.5.0|V0.1.0|
+|SIM 2x00|V1.7.0|V1.0.0|
+
+This module is part of the SICK AppSpace Coding Starter Kit developing approach.
+It is programmed in an object-oriented way. Some of the modules use kind of "classes" in Lua to make it possible to reuse code / classes in other projects.
+In general, it is not neccessary to code this way, but the architecture of this app can serve as a sample to be used especially for bigger projects and to make it easier to share code.
Please check the [documentation](https://github.com/SICKAppSpaceCodingStarterKit/.github/blob/main/docu/SICKAppSpaceCodingStarterKit_Documentation.md) of CSK for further information.
## Topics
-Coding Starter Kit, CSK, Module, SICK-AppSpace, [key_words]
+Coding Starter Kit, CSK, Module, SICK-AppSpace, Fieldbus, Profinet, EtherCat, Ethernet/IP, PLC
diff --git a/docu/CSK_Module_Fieldbus.html b/docu/CSK_Module_Fieldbus.html
index 3cd178a..bf61348 100644
--- a/docu/CSK_Module_Fieldbus.html
+++ b/docu/CSK_Module_Fieldbus.html
@@ -6,7 +6,7 @@
-