Skip to content

Commit 6f8ce5d

Browse files
Release 3.0.0 (#4)
# Release 3.0.0 ## New features - Provide features even without CSK_IODDInterpreter - Possibility to create readMessages without IODD information, by setting start-/endByte and unpack format - Possibility to search and cut relevant part out of created JSON within readMessage - New FlowConfig block 'OnNewDataAuto' which automatically creates readMessages and optionally checks to power selected port (WARNING: Do NOT mix with manual readMessage setup) - React on "OnStopFlowConfigProviders" event of FlowConfig modul to stop pulling IO-Link data - Check and handle different kind of IOLink.SMI APIs - Function to delete all existing readMessages - Check if persistent data to load provides all relevant parameters. Otherwise add default values - Selectable if timers for readMessages should start automatically after parameters were loaded ## Improvements - Changed event name "OnNewReadMessage_PORT_MESSAGENAME" to "OnNewReadMessage_INSTANCE_PORT_MESSAGENAME" to make it possible to switch between ports during runtime - Do not start readMessage timers automatically with creation of readMessage - Use new event 'OnNewRawReadMessage_INSTANCE_PORT_MESSAGENAME" within FlowConfig (only providing data content as first parameter) - If using FlowConfig, start readMessage timers after 5 seconds - Add info about port within "OnNewIOLinkPortStatus" event - Add list of ports related to instances within "getInstancePortMap" function - Better handling if CSK_IODDInterpreter is not available ## Bugfix - Issue with CSK_UserManagement support - Error if sending process data without any selection - Error in handling IODD data
1 parent db14222 commit 6f8ce5d

20 files changed

Lines changed: 5104 additions & 2093 deletions

CHANGELOG.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,44 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## Release 3.0.0
5+
6+
### New features
7+
- Provide features even without CSK_Module_IODDInterpreter
8+
- Create readMessages without IODD information, by setting start-/endByte (or bit position within byte) and unpack format
9+
- Optionally search and cut relevant part out of created JSON within readMessage
10+
- Register to event to forward content as writeMessage
11+
- New FlowConfig block 'OnNewDataAuto' which automatically creates readMessages and optionally checks to power selected port (WARNING: Do NOT mix with manual readMessage setup)
12+
- New FlowConfig block 'WriteProcessData'
13+
- React on "OnStopFlowConfigProviders" event of FlowConfig modul to stop pulling IO-Link data
14+
- Check and handle different kind of IOLink.SMI APIs
15+
- Function to delete all existing readMessages
16+
- Check if persistent data to load provides all relevant parameters. Otherwise add default values
17+
- Selectable if timers for readMessages should start automatically after parameters were loaded
18+
19+
### Improvements
20+
- Changed event name "OnNewReadMessage_PORT_MESSAGENAME" to "OnNewReadMessage_INSTANCE_PORT_MESSAGENAME" to make it possible to switch between ports during runtime
21+
- Do not start readMessage timers automatically with creation of readMessage
22+
- Use new event 'OnNewRawReadMessage_INSTANCE_PORT_MESSAGENAME" within FlowConfig (only providing data content as first parameter)
23+
- If using FlowConfig, start readMessage timers after 5 seconds
24+
- Add info about port within "OnNewIOLinkPortStatus" event
25+
- Add list of ports related to instances within "getInstancePortMap" function
26+
- Better handling if CSK_IODDInterpreter is not available
27+
28+
### Bugfix
29+
- Issue with CSK_UserManagement support
30+
- Error if sending process data without any selection
31+
- Error in handling IODD data
32+
433
## Release 2.1.1
534

635
### Bugfixes
7-
writing of process data and parameters is available again
36+
- writing of process data and parameters is available again
837

938
## Release 2.1.0
1039

1140
### New features
12-
Now it is possible to read subindexes (even if the subindex access is not supported). Requires IODD interpreter v2.1.0 or more
41+
- Now it is possible to read subindexes (even if the subindex access is not supported). Requires IODD interpreter v2.1.0 or more
1342

1443
### Improvements
1544
- Speeding up of data parsing when reading from IO-Link device

CSK_Module_MultiIOLinkSMI/pages/pages/CSK_Module_MultiIOLinkSMI/CSK_Module_MultiIOLinkSMI.html

Lines changed: 499 additions & 151 deletions
Large diffs are not rendered by default.

CSK_Module_MultiIOLinkSMI/project.mf.xml

Lines changed: 193 additions & 18 deletions
Large diffs are not rendered by default.

CSK_Module_MultiIOLinkSMI/scripts/CSK_Module_MultiIOLinkSMI.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ local multiIOLinkSMI_Instances = {} -- Handle all instances
4949
-- Check / edit this script to see/edit functions which communicate with the UI
5050
local multiIOLinkSMIController = require('Communication/MultiIOLinkSMI/MultiIOLinkSMI_Controller')
5151

52-
if _G.availableAPIs.default and _G.availableAPIs.specific and Engine.getEnumValues('IOLinkMasterPorts') ~= nil then
52+
if _G.availableAPIs.default and _G.availableAPIs.specificSMI and Engine.getEnumValues('IOLinkMasterPorts') ~= nil then
5353
local setInstanceHandle = require('Communication/MultiIOLinkSMI/FlowConfig/MultiIOLinkSMI_FlowConfig')
5454
table.insert(multiIOLinkSMI_Instances, multiIOLinkSMI_Model.create(1))
5555
multiIOLinkSMIController.setMultiIOLinkSMI_Instances_Handle(multiIOLinkSMI_Instances) -- share handle of instances
@@ -90,7 +90,7 @@ local function main()
9090
CSK_MultiIOLinkSMI.setIODDReadMessageName('readMessageTitle')
9191
CSK_MultiIOLinkSMI.createIODDReadMessage()
9292
CSK_MultiIOLinkSMI.setSelectedIODDReadMessage('readMessageTitle')
93-
-- Register to "CSK_MultiIOLinkSMI.OnNewReadMessage_[port]_[readMessageTitle]"-event
93+
-- Register to "CSK_MultiIOLinkSMI.OnNewReadMessage_[instance]_[port]_[readMessageTitle]"-event
9494
9595
-- Write message handling
9696
CSK_MultiIOLinkSMI.createIODDWriteMessage()
@@ -114,7 +114,7 @@ local function main()
114114
]]
115115
----------------------------------------------------------------------------------------
116116

117-
if _G.availableAPIs.default and _G.availableAPIs.specific then
117+
if _G.availableAPIs.default and _G.availableAPIs.specificSMI then
118118
CSK_MultiIOLinkSMI.setSelectedInstance(1)
119119
CSK_MultiIOLinkSMI.pageCalled()
120120
end

CSK_Module_MultiIOLinkSMI/scripts/CSK_MultiIOLinkSMI_Processing.lua

Lines changed: 204 additions & 54 deletions
Large diffs are not rendered by default.

CSK_Module_MultiIOLinkSMI/scripts/Communication/MultiIOLinkSMI/FlowConfig/MultiIOLinkSMI_FlowConfig.lua

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
--*****************************************************************
55

66
require('Communication.MultiIOLinkSMI.FlowConfig.MultiIOLinkSMI_OnNewData')
7-
--require('Communication.MultiIOLinkSMI.FlowConfig.MultiIOLinkSMI_SendRequest')
7+
require('Communication.MultiIOLinkSMI.FlowConfig.MultiIOLinkSMI_OnNewDataAuto')
8+
require('Communication.MultiIOLinkSMI.FlowConfig.MultiIOLinkSMI_WriteProcessData')
89

910
-- Reference to the multiIOLinkSMI_Instances handle
1011
local multiIOLinkSMI_Instances
1112

1213
--- Function to react if FlowConfig was updated
1314
local function handleOnClearOldFlow()
14-
if _G.availableAPIs.default and _G.availableAPIs.specific then
15+
if _G.availableAPIs.default and _G.availableAPIs.specificSMI then
1516
for i = 1, # multiIOLinkSMI_Instances do
1617
if multiIOLinkSMI_Instances[i].parameters.flowConfigPriority then
1718
CSK_MultiIOLinkSMI.clearFlowConfigRelevantConfiguration()
@@ -22,6 +23,19 @@ local function handleOnClearOldFlow()
2223
end
2324
Script.register('CSK_FlowConfig.OnClearOldFlow', handleOnClearOldFlow)
2425

26+
--- Function to react if FlowConfig was updated
27+
local function handleOnStopProvider()
28+
if _G.availableAPIs.default and _G.availableAPIs.specificSMI then
29+
for i = 1, # multiIOLinkSMI_Instances do
30+
if multiIOLinkSMI_Instances[i].parameters.flowConfigPriority then
31+
CSK_MultiIOLinkSMI.stopFlowConfigRelevantProvider()
32+
break
33+
end
34+
end
35+
end
36+
end
37+
Script.register('CSK_FlowConfig.OnStopFlowConfigProviders', handleOnStopProvider)
38+
2539
--- Function to get access to the multiIOLinkSMI_Instances
2640
---@param handle handle Handle of multiIOLinkSMI_Instances object
2741
local function setMultiIOLinkSMI_Instances_Handle(handle)

CSK_Module_MultiIOLinkSMI/scripts/Communication/MultiIOLinkSMI/FlowConfig/MultiIOLinkSMI_OnNewData.lua

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ local nameOfModule = 'CSK_MultiIOLinkSMI'
55
--*************************************************************
66
--*************************************************************
77

8+
--- Timer to start readMessage timers
9+
local tmr = Timer.create()
10+
tmr:setExpirationTime(5000)
11+
tmr:setPeriodic(false)
12+
13+
local function handleOnExpired()
14+
CSK_MultiIOLinkSMI.setReadMessageTimerActive(true)
15+
end
16+
Timer.register(tmr, 'OnExpired', handleOnExpired)
17+
818
-- Required to keep track of already allocated resource
919
local instanceTable = {}
1020

@@ -16,17 +26,27 @@ local function register(handle, _ , callback)
1626
local port = Container.get(handle, 'Port')
1727
local readMessageName = Container.get(handle,"ReadMessageName")
1828

29+
local _, portList = CSK_MultiIOLinkSMI.getInstancePortMap()
30+
local instanceUsed = 1
31+
for key, value in pairs(portList) do
32+
if value == port then
33+
instanceUsed = key
34+
end
35+
end
36+
1937
local function localCallback()
2038
local cbFunction = Container.get(handle,"CB_Function")
2139

2240
if cbFunction ~= nil then
23-
Script.callFunction(cbFunction, 'CSK_MultiIOLinkSMI.OnNewReadMessage_' .. tostring(port) .. '_' .. tostring(readMessageName))
41+
Script.callFunction(cbFunction, 'CSK_MultiIOLinkSMI.OnNewRawReadMessage_' .. tostring(instanceUsed) .. '_' .. tostring(port) .. '_' .. tostring(readMessageName))
2442
else
2543
_G.logger:warning(nameOfModule .. ": " .. BLOCK_NAMESPACE .. ".CB_Function missing!")
2644
end
2745
end
2846
Script.register('CSK_FlowConfig.OnNewFlowConfig', localCallback)
2947

48+
tmr:start()
49+
3050
return true
3151
end
3252
Script.serveFunction(BLOCK_NAMESPACE ..".register", register)
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
-- Block namespace
2+
local BLOCK_NAMESPACE = "MultiIOLinkSMI_FC.OnNewDataAuto"
3+
local nameOfModule = 'CSK_MultiIOLinkSMI'
4+
5+
--*************************************************************
6+
--*************************************************************
7+
8+
-- Required to keep track of already allocated resource
9+
local instanceTable = {}
10+
11+
-- Information about IO-Link configuration made by FlowConfig blocks
12+
local portInfos = {}
13+
14+
--- Timer to start readMessage timers
15+
local tmrReadMessage = Timer.create()
16+
tmrReadMessage:setExpirationTime(5000)
17+
tmrReadMessage:setPeriodic(false)
18+
19+
--- Timer to setup IO-Link incl. power management
20+
local tmrSetup = Timer.create()
21+
tmrSetup:setExpirationTime(3000)
22+
tmrSetup:setPeriodic(false)
23+
24+
--- Function to start periocic timer for readMessages
25+
local function handleOnExpired()
26+
CSK_MultiIOLinkSMI.setReadMessageTimerActive(true)
27+
end
28+
Timer.register(tmrReadMessage, 'OnExpired', handleOnExpired)
29+
30+
--- Function to automatically setup IO-Link configuration
31+
local function handleIOLinkSetup()
32+
33+
local amount = CSK_MultiIOLinkSMI.getInstancesAmount()
34+
35+
-- First reset setup if it was configured before
36+
for i = 1, amount do
37+
CSK_MultiIOLinkSMI.setSelectedInstance(i)
38+
CSK_MultiIOLinkSMI.deleteAllReadMessages()
39+
CSK_MultiIOLinkSMI.activateInstance(false)
40+
CSK_MultiIOLinkSMI.setPort('')
41+
end
42+
43+
if CSK_PowerManager then
44+
local moduleActive = CSK_PowerManager.getStatusModuleActive()
45+
if moduleActive then
46+
for key, value in ipairs(portInfos) do
47+
local status = CSK_PowerManager.getCurrentPortStatus(value.port)
48+
if status == false then
49+
CSK_PowerManager.changeStatusOfPort(value.port)
50+
end
51+
end
52+
CSK_PowerManager.setAllStatus()
53+
end
54+
end
55+
56+
for key, value in ipairs(portInfos) do
57+
local instanceAmount = CSK_MultiIOLinkSMI.getInstancesAmount()
58+
if instanceAmount < key then
59+
CSK_MultiIOLinkSMI.addInstance()
60+
end
61+
62+
CSK_MultiIOLinkSMI.setSelectedInstance(key)
63+
CSK_MultiIOLinkSMI.setPort(value.port)
64+
CSK_MultiIOLinkSMI.activateInstance(true)
65+
end
66+
67+
tmrReadMessage:start()
68+
end
69+
Timer.register(tmrSetup, 'OnExpired', handleIOLinkSetup)
70+
71+
--- Function to setup readMessages
72+
---@param instance int Instance ID.
73+
---@param status string Port status.
74+
---@param port string Port
75+
local function handleOnNewIOLinkPortStatus(instance, status, port)
76+
if status == 'OPERATE' then
77+
for key, value in ipairs(portInfos) do
78+
if value.port == port then
79+
-- Check to only setup once, even with multiple events of OPERATION
80+
if value.portActive == false then
81+
value.portActive = true
82+
CSK_MultiIOLinkSMI.setSelectedInstance(instance)
83+
84+
-- Add readMessages
85+
for subKey, subValue in ipairs(value.messageInfos.names) do
86+
CSK_MultiIOLinkSMI.setIODDReadMessageName(subValue)
87+
CSK_MultiIOLinkSMI.setReadMessageMode('NO_IODD')
88+
CSK_MultiIOLinkSMI.createIODDReadMessage()
89+
CSK_MultiIOLinkSMI.setTriggerType('Periodic')
90+
CSK_MultiIOLinkSMI.setTriggerValue(value.messageInfos.cycleTimes[subKey])
91+
CSK_MultiIOLinkSMI.setReadMessageProcessDataStartByte(value.messageInfos.startBytes[subKey])
92+
CSK_MultiIOLinkSMI.setReadMessageProcessDataEndByte(value.messageInfos.endBytes[subKey])
93+
CSK_MultiIOLinkSMI.setReadMessageProcessDataUnpackFormat(value.messageInfos.unpackFormats[subKey])
94+
end
95+
end
96+
end
97+
end
98+
end
99+
end
100+
Script.register('CSK_MultiIOLinkSMI.OnNewIOLinkPortStatus', handleOnNewIOLinkPortStatus)
101+
102+
local function register(handle, _ , callback)
103+
104+
Container.remove(handle, "CB_Function")
105+
Container.add(handle, "CB_Function", callback)
106+
107+
local port = Container.get(handle, 'Port')
108+
local cycleTime = Container.get(handle, 'CycleTime')
109+
local startByte = Container.get(handle, 'StartByte')
110+
local endByte = Container.get(handle, 'EndByte')
111+
local unpackFormat = Container.get(handle, 'UnpackFormat')
112+
113+
local portExists = false
114+
local portPosition = 1
115+
116+
-- Check if port config already exists
117+
for key, value in pairs(portInfos) do
118+
if value.port == port then
119+
portExists = true
120+
portPosition = key
121+
break
122+
end
123+
end
124+
125+
if not portExists then
126+
-- Create new table for port configuration
127+
local instanceSetup = {}
128+
instanceSetup.port = port
129+
instanceSetup.portActive = false
130+
instanceSetup.messageInfos = {}
131+
instanceSetup.messageInfos.names = {}
132+
instanceSetup.messageInfos.cycleTimes = {}
133+
instanceSetup.messageInfos.startBytes = {}
134+
instanceSetup.messageInfos.endBytes = {}
135+
instanceSetup.messageInfos.unpackFormats = {}
136+
137+
table.insert(portInfos, instanceSetup)
138+
portPosition = #portInfos
139+
end
140+
141+
table.insert(portInfos[portPosition].messageInfos.names, 'FlowConfig' .. tostring(#portInfos[portPosition].messageInfos.names))
142+
local messagePos = portInfos[portPosition].messageInfos.names[#portInfos[portPosition].messageInfos.names]
143+
table.insert(portInfos[portPosition].messageInfos.cycleTimes, cycleTime)
144+
table.insert(portInfos[portPosition].messageInfos.startBytes, startByte)
145+
table.insert(portInfos[portPosition].messageInfos.endBytes, endByte)
146+
table.insert(portInfos[portPosition].messageInfos.unpackFormats, unpackFormat)
147+
148+
local function localCallback()
149+
local cbFunction = Container.get(handle,"CB_Function")
150+
151+
if cbFunction ~= nil then
152+
Script.callFunction(cbFunction, 'CSK_MultiIOLinkSMI.OnNewRawReadMessage_' .. tostring(portPosition) .. '_' .. port .. '_' .. messagePos)
153+
else
154+
_G.logger:warning(nameOfModule .. ": " .. BLOCK_NAMESPACE .. ".CB_Function missing!")
155+
end
156+
end
157+
Script.register('CSK_FlowConfig.OnNewFlowConfig', localCallback)
158+
159+
tmrSetup:start()
160+
161+
return true
162+
end
163+
Script.serveFunction(BLOCK_NAMESPACE ..".register", register)
164+
165+
--*************************************************************
166+
--*************************************************************
167+
168+
local function create(port, cycleTime, startByte, endByte, unpackFormat)
169+
170+
local fullInstanceName = tostring(port) .. '_' .. tostring(cycleTime) .. tostring(startByte) .. '_' .. tostring(endByte) .. '_' .. tostring(unpackFormat)
171+
172+
-- Check if same instance is already configured
173+
if instanceTable[fullInstanceName] ~= nil then
174+
_G.logger:warning(nameOfModule .. ": Instance invalid or already in use, please choose another one")
175+
return nil
176+
else
177+
-- Otherwise create handle and store the restriced resource
178+
local handle = Container.create()
179+
instanceTable[fullInstanceName] = fullInstanceName
180+
Container.add(handle, 'Port', port)
181+
Container.add(handle, 'CycleTime', cycleTime)
182+
Container.add(handle, 'StartByte', startByte)
183+
Container.add(handle, 'EndByte', endByte)
184+
Container.add(handle, 'UnpackFormat', unpackFormat)
185+
Container.add(handle, "CB_Function", "")
186+
return handle
187+
end
188+
end
189+
Script.serveFunction(BLOCK_NAMESPACE .. ".create", create)
190+
191+
--- Function to reset instances if FlowConfig was cleared
192+
local function handleOnClearOldFlow()
193+
194+
Script.releaseObject(instanceTable)
195+
instanceTable = {}
196+
197+
Script.releaseObject(portInfos)
198+
portInfos = {}
199+
end
200+
Script.register('CSK_FlowConfig.OnClearOldFlow', handleOnClearOldFlow)

0 commit comments

Comments
 (0)