CSK Template to show how CSK modules can be used/combined to e.g. push sensor data to the SICK AssetHub.
Please have a look into the README of CSK_Module_LiveConnect for further details of LiveConnect.

Please note This project has dependencies to other modules which were included as subtrees (see 'subtrees' folder) and are linked via symbolic links.
If you want to clone this repository, please make sure that within your gitconfig you set the parameter 'core.symlinks' to TRUE (regarding further information see the Contribution Guideline ).
By doing this, the project directory can directly be used as working directory within AppStudio / VS Code.
See following chapters to run this template.
For further information of this template check out the documentation in the folder "docu".
Before data can be exchanged, the physical gateway device must first be paired with the digital twin in the SICK AssetHub. Please do the following step by step:
SICK AssetHub
- Open the digital service SICK AssetHub -- In order to use the SICK AssetHub, you need to subscribe it via the SICK Digital Service Catalog -- You also need a subscription for SICK LiveConnect
- Create a digital twin of your gateway device using the part-/ and serial number of the physical device.
- Start the pairing process to pair the digital twin with a physical device via SICK LiveConnect.

- Please copy the pairing code.
SICK LiveConnect Client App
- Open the UI of the SICK LiveConnect Client app by entering the IP address of your device in the browser.
- If you need to configure IP addresses of your device, please open the app "CSK_Module_DeviceNetworkConfig".
- Open the app "CSK_Module_DateTime" to setup the system time of your gateway device. -- As an NTP server, you can use a server of your choice or the NTP server provided by SICK (35.157.9.76) -- The system time must be synchronized, otherwise a secure connection to the cloud cannot be established.
- Open the app "CSK_Module_LiveConnect".
- Check if the System clock status is "configured". Enter the pairing code generated by the AssetHub in order to pair this device with LiveConnect.

- The "connection status" should then switched to "Online".
- Now the device is paired and ready to exchange data with the cloud.

The data that is exchanged between the device and the AssetHub is defined via profiles. It is possible to bind one or more profiles to a device. There are two types of profiles that can be used:
- Use-Case: The device automatically push data into the cloud.
- Profile-Type: AsyncAPI
- Profile-Editor: AsyncAPI Studio
sequenceDiagram
participant DEVICE as Device
participant APP as Application
participant LC as LiveConnect Client
participant AH as AssetHub
LC ->> AH: pairing code
AH ->> LC: status paired
APP ->> LC: add MQTT profile
LC ->> AH: register profile
DEVICE ->> APP: Process data
APP ->> LC: data according profile
LC ->> AH: push data
DEVICE ->> APP: Process data
APP ->> LC: data according profile
LC ->> AH: push data
DEVICE ->> APP: ...
- Use-Case: An HTTP request sent from the cloud side is transmitted to the device. The device generates a response that corresponds to the data profile and sends it back to the cloud (data poll mechanism).
- Profile-Type: OpenAPI
- Profile-Editor: Swagger Editor
sequenceDiagram
participant DEVICE as Device
participant APP as Application
participant LC as LiveConnect Client
participant AH as AssetHub
LC ->> AH: pairing code
AH ->> LC: status paired
APP ->> LC: add HTTP profile and binded functions
LC ->> AH: register profile
AH ->> LC: request data
note over AH: Request generated by a connected web service (e.g. SICK Dynamic Data Display)
LC ->> APP: call function
APP ->> DEVICE: read process data
DEVICE ->> APP: process data
APP ->> LC : data according profile
LC ->> AH : response data
AH ->> LC: request data
LC ->> APP: call function
APP ->> DEVICE: read process data
DEVICE ->> APP: process data
APP ->> LC : data according profile
LC ->> AH : response data
AH ->> LC: ...
Code snipped to add an MQTT profile and send data every 5s into the cloud.
Remark The UUID is profile specific. If you want to create an own profile, please generate a UUID for it.
-------------------------------------------------------------------------------------
-- Variables
local m_timer = Timer.create()
local m_json = require("utils.Lunajson")
-------------------------------------------------------------------------------------
-- Payload to be sent at a specific interval
local function sendMqttData(partNumber, serialNumber, topic)
local l_payload = {}
l_payload.timestamp = DateTime.getDateTime()
l_payload.index = math.random(0,255)
l_payload.data = "Payload from the edge side"
local l_payloadJson = m_json.encode(l_payload)
CSK_LiveConnect.publishMqttData(topic, partNumber, serialNumber, l_payloadJson)
end
-------------------------------------------------------------------------------------
-- Add MQTT application profile
local function addMqttProfile(partNumber, serialNumber)
-- Profile definition
local l_mqttProfile = CSK_LiveConnect.MqttProfile.create()
local l_topic = "sick/device/mqtt-test"
l_mqttProfile:setUuid("55aa8083-24dc-41aa-bad0-ee28d5892d9d")
l_mqttProfile:setName("LiveConnect MQTT test profile")
l_mqttProfile:setDescription("Profile to test data push mechanism")
l_mqttProfile:setBaseTopic(l_topic)
l_mqttProfile:setAsyncAPISpecification(File.open("resources/profileMqttTest.yaml", "rb"):read())
l_mqttProfile:setVersion("0.1.0")
-- Payload definition
local l_sendData = function()
return sendMqttData(partNumber, serialNumber, l_topic)
end
m_timer:setExpirationTime(5000)
m_timer:setPeriodic(true)
m_timer:register("OnExpired", l_sendData)
m_timer:start()
-- Register application profile
CSK_LiveConnect.addMqttProfile(partNumber, serialNumber, l_mqttProfile)
end
-------------------------------------------------------------------------------------
-- Main
local function main()
addMqttProfile("1057651", "17410401") -- Part- and serial number of a SICK DT35 IO-Link device
end
Script.register("Engine.OnStarted", main)On the AssetHub side, the data can be viewed and forwarded to a web application.

Code snipped to add an HTTP profile and register a callback function
Remark The UUID is profile specific. If you want to create an own profile, please generate a UUID for it.
-------------------------------------------------------------------------------------
-- Variables
local m_json = require("utils.Lunajson")
-------------------------------------------------------------------------------------
-- Respond to HTTP request
local function httpCallback(request)
local l_response = CSK_LiveConnect.Response.create()
local l_header = CSK_LiveConnect.Header.create()
CSK_LiveConnect.Header.setKey(l_header, "Content-Type")
CSK_LiveConnect.Header.setValue(l_header, "application/json")
l_response:setHeaders({l_header})
l_response:setStatusCode(200)
local l_responsePayload = {}
l_responsePayload["timestamp"] = DateTime.getDateTime()
l_responsePayload["index"] = math.random(0,255)
l_responsePayload["data"] = "Response payload from the edge side"
l_response:setContent(m_json.encode(l_responsePayload))
return l_response
end
-------------------------------------------------------------------------------------
-- Add HTTP application profile
local function addHttpProfile(partNumber, serialNumber)
local l_httpProfile = CSK_LiveConnect.HttpProfile.create()
l_httpProfile:setName("LiveConnect HTTP test profile")
l_httpProfile:setDescription("Profile to test bi-direction communication between the server and the client")
l_httpProfile:setVersion("0.2.0")
l_httpProfile:setUuid("68f372d5-607c-4e16-b137-63af9fadaaa5")
l_httpProfile:setOpenAPISpecification(File.open("resources/profileHttpTest.yaml", "rb"):read())
l_httpProfile:setServiceLocation("http-test")
-- Endpoint definition
local l_uri = "getwithoutparam"
local l_crownName = Engine.getCurrentAppName() .. "." .. l_uri
local l_endpoint = CSK_LiveConnect.HttpProfile.Endpoint.create()
l_endpoint:setHandlerFunction(l_crownName)
l_endpoint:setMethod("GET")
l_endpoint:setURI(l_uri)
-- Register callback function, which will be called to answer the HTTP request
Script.serveFunction(l_crownName, httpCallback, "object:CSK_LiveConnect.Request", "object:CSK_LiveConnect.Response")
-- Add endpoints
CSK_LiveConnect.HttpProfile.setEndpoints(l_httpProfile, {l_endpoint})
-- Register application profile
CSK_LiveConnect.addHttpProfile(partNumber, serialNumber, l_httpProfile)
end
-------------------------------------------------------------------------------------
-- Main
local function main()
addHttpProfile("1057651", "17410401") -- Part- and serial number of a SICK DT35 IO-Link device
end
Script.register("Engine.OnStarted", main)On the AssetHub side, the data can send a GET request to the endpoint. The response telegram can be viewed.

Please have a look into the README of CSK_Module_LiveConnect.
| Device | Firmware |
|---|---|
| SIM1012 | V2.3.0 |
| SIM1000fx | V1.7.2 |
| TDCE-E | L4M 2023.2 (with app Engine V2.0.0) |
Following CSK modules are used for this application via Git subtrees and should NOT be further developed within this repository (see contribution guideline of this GitHub organization):
| Module | Version | Remark |
|---|---|---|
| CSK_1stModule_Logger | V4.0.0 | Optional |
| CSK_Module_DateTime | V3.0.0 | This module is not required using a TDC-E as gateway device |
| CSK_Module_DeviceNetworkConfig | V2.1.0 | This module is not required using a TDC-E as gateway device |
| CSK_Module_LiveConnect | V3.0.0 | Necessary |
| CSK_Module_PersistentData | V4.0.0 | Necessary to persist data |
Please note 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.
Please check the documentation of CSK for further information.
Coding Starter Kit, CSK, Module, SICK-AppSpace, LiveConnect, AssetHub, Cloud