The Kaa platform currently supports HTTP(s) and MQTT(s) device protocols.
While it does not support direct communication via TCP or UDP, you can still communicate with Kaa by bridging TCP/UDP to HTTP or MQTT.
In this article, we will demonstrate how to bridge TCP/UDP into MQTT using Node-RED.
Node-RED will receive data over TCP/UDP on its own server and forward it over MQTT to the Kaa platform.
First, create an endpoint by following the Getting Started Tutorial.
You will need its application version and endpoint token.
Next, deploy the flow for the protocol of your choice.
Copy the flow code for either TCP or UDP, and then import the flow into Node-RED.
[
{
"id": "4a8d6d5bb5991164",
"type": "tab",
"label": "TCP to MQTT flow",
"disabled": false,
"info": "",
"env": []
},
{
"id": "d199710e28b08c36",
"type": "inject",
"z": "4a8d6d5bb5991164",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "5",
"crontab": "",
"once": false,
"onceDelay": "5",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 190,
"y": 240,
"wires": [
[
"82dd82e7538dc64e"
]
]
},
{
"id": "90ac99e2faddb1c6",
"type": "tcp in",
"z": "4a8d6d5bb5991164",
"name": "tcp server",
"server": "server",
"host": "",
"port": "5000",
"datamode": "stream",
"datatype": "utf8",
"newline": "",
"topic": "",
"trim": false,
"base64": false,
"tls": "",
"x": 180,
"y": 360,
"wires": [
[
"540e34258b26e018",
"b8a4ef02a3d58e4e"
]
]
},
{
"id": "540e34258b26e018",
"type": "debug",
"z": "4a8d6d5bb5991164",
"name": "debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 350,
"y": 360,
"wires": []
},
{
"id": "aa17bc8de5e6c2de",
"type": "mqtt out",
"z": "4a8d6d5bb5991164",
"name": "kaa mqtt broker out",
"topic": "",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "dc0deea1.ea5b2",
"x": 710,
"y": 420,
"wires": []
},
{
"id": "b3f28565df168d63",
"type": "function",
"z": "4a8d6d5bb5991164",
"name": "init CONSTANTS",
"func": "node.warn(\"Initializing flow variables\")\n\n// Set the application version and device token from here. \n// Don't forget to save and deploy your changes\nconst APP_VERSION = '<your-app-version>'\nconst TOKEN = '<your-endpoint-token>'\nconst SERVER_URL = 'cloud.kaaiot.com'\n\nflow.set('COUNT', 0)\nflow.set('APP_VERSION', APP_VERSION)\nflow.set('SERVER_URL', SERVER_URL)\nflow.set('TOKEN', TOKEN)\n",
"outputs": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 390,
"y": 120,
"wires": [],
"icon": "node-red/alert.svg"
},
{
"id": "65ec82e0cce9c282",
"type": "inject",
"z": "4a8d6d5bb5991164",
"name": "startup",
"props": [],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 180,
"y": 120,
"wires": [
[
"b3f28565df168d63"
]
]
},
{
"id": "0c61307c1474c53b",
"type": "mqtt in",
"z": "4a8d6d5bb5991164",
"name": "kaa mqtt broker in",
"topic": "kp1/+/dcx/+/json/#",
"qos": "2",
"datatype": "auto-detect",
"broker": "dc0deea1.ea5b2",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 210,
"y": 580,
"wires": [
[
"cfd3faa4794f0722"
]
]
},
{
"id": "b8a4ef02a3d58e4e",
"type": "function",
"z": "4a8d6d5bb5991164",
"name": "prepare data for Kaa MQTT ",
"func": "// Retrieving flow variables\nconst APP_VERSION = flow.get('APP_VERSION')\nconst TOKEN = flow.get('TOKEN')\n\n// Preparing data for Kaa MQTT broker\nmsg.topic = `kp1/${APP_VERSION}/dcx/${TOKEN}/json/1`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 420,
"y": 420,
"wires": [
[
"aa17bc8de5e6c2de"
]
]
},
{
"id": "307dcd1adfb5cf16",
"type": "function",
"z": "4a8d6d5bb5991164",
"name": "prepare data for TCP client",
"func": "// Retrieving flow variables\nconst APP_VERSION = flow.get('APP_VERSION')\nconst TOKEN = flow.get('TOKEN')\nconst COUNT = flow.get('COUNT')\n\n// Preparing data for TCP client\nmsg.topic = `kp1/${APP_VERSION}/dcx/${TOKEN}/json/1`\nmsg.payload = JSON.stringify({\n \"count\": COUNT\n})\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 620,
"y": 240,
"wires": [
[
"9a789498da90ae8d"
]
]
},
{
"id": "04fe6cbc5a81d394",
"type": "comment",
"z": "4a8d6d5bb5991164",
"name": "IMPORTANT: Set the APP_VERSION and TOKEN",
"info": "",
"x": 310,
"y": 80,
"wires": []
},
{
"id": "6477f34491af26a6",
"type": "comment",
"z": "4a8d6d5bb5991164",
"name": "TCP Client",
"info": "",
"x": 180,
"y": 200,
"wires": []
},
{
"id": "93b0ab80a2650cf5",
"type": "comment",
"z": "4a8d6d5bb5991164",
"name": "TCP Server",
"info": "",
"x": 190,
"y": 320,
"wires": []
},
{
"id": "103bf5caccc0183c",
"type": "comment",
"z": "4a8d6d5bb5991164",
"name": "Response from Kaa Mqtt",
"info": "",
"x": 230,
"y": 500,
"wires": []
},
{
"id": "f67d93516e466799",
"type": "comment",
"z": "4a8d6d5bb5991164",
"name": "An empty payload indicates that there were no errors",
"info": "",
"x": 310,
"y": 540,
"wires": []
},
{
"id": "d55d5288ef8cb685",
"type": "comment",
"z": "4a8d6d5bb5991164",
"name": "This flow bridges TCP to MQTT",
"info": "",
"x": 250,
"y": 40,
"wires": []
},
{
"id": "82dd82e7538dc64e",
"type": "function",
"z": "4a8d6d5bb5991164",
"name": "increase count ",
"func": "// Custom logic to simulate a real device\n// Increase count by 1\nconst COUNT = flow.get('COUNT')\nflow.set('COUNT', COUNT + 1)\n\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 380,
"y": 240,
"wires": [
[
"307dcd1adfb5cf16"
]
]
},
{
"id": "cfd3faa4794f0722",
"type": "json",
"z": "4a8d6d5bb5991164",
"name": "",
"property": "payload",
"action": "str",
"pretty": false,
"x": 490,
"y": 580,
"wires": [
[
"5214dfed88bb27f4"
]
]
},
{
"id": "5214dfed88bb27f4",
"type": "debug",
"z": "4a8d6d5bb5991164",
"name": "response from kaa",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 710,
"y": 580,
"wires": []
},
{
"id": "9a789498da90ae8d",
"type": "tcp out",
"z": "4a8d6d5bb5991164",
"name": "tcp client",
"host": "127.0.0.1",
"port": "5000",
"beserver": "client",
"base64": false,
"end": false,
"tls": "",
"x": 840,
"y": 240,
"wires": []
},
{
"id": "dc0deea1.ea5b2",
"type": "mqtt-broker",
"name": "mqtt.cloud.kaaiot.com",
"broker": "mqtt.cloud.kaaiot.com",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
}
]
[
{
"id": "4233a8e0fb20e448",
"type": "tab",
"label": "UDP to MQTT flow",
"disabled": false,
"info": "",
"env": []
},
{
"id": "61a858f3d88a9f20",
"type": "inject",
"z": "4233a8e0fb20e448",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "5",
"crontab": "",
"once": false,
"onceDelay": "5",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 260,
"wires": [
[
"62423136c882dab1"
]
]
},
{
"id": "6d8970cf19cae3ad",
"type": "debug",
"z": "4233a8e0fb20e448",
"name": "debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 370,
"y": 380,
"wires": []
},
{
"id": "4d94e40615c6c571",
"type": "mqtt out",
"z": "4233a8e0fb20e448",
"name": "kaa mqtt broker out",
"topic": "",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "dc0deea1.ea5b2",
"x": 730,
"y": 440,
"wires": []
},
{
"id": "32aa5ffb9c6d22d8",
"type": "function",
"z": "4233a8e0fb20e448",
"name": "init CONSTANTS",
"func": "node.warn(\"Initializing flow variables\")\n\n// Set the application version and device token from here. \n// Don't forget to save and deploy your changes\nconst APP_VERSION = '<your-app-version>'\nconst TOKEN = '<your-endpoint-token>'\nconst SERVER_URL = 'cloud.kaaiot.com'\n\nflow.set('COUNT', 0)\nflow.set('APP_VERSION', APP_VERSION)\nflow.set('SERVER_URL', SERVER_URL)\nflow.set('TOKEN', TOKEN)\n",
"outputs": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 410,
"y": 140,
"wires": [],
"icon": "node-red/alert.svg"
},
{
"id": "cb445b568b81d29b",
"type": "inject",
"z": "4233a8e0fb20e448",
"name": "startup",
"props": [],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 160,
"y": 140,
"wires": [
[
"32aa5ffb9c6d22d8"
]
]
},
{
"id": "662a3f77cc23c6a2",
"type": "mqtt in",
"z": "4233a8e0fb20e448",
"name": "kaa mqtt broker in",
"topic": "kp1/+/dcx/+/json/#",
"qos": "2",
"datatype": "auto-detect",
"broker": "dc0deea1.ea5b2",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 190,
"y": 600,
"wires": [
[
"ecccd3107d6d1e04"
]
]
},
{
"id": "dc0d141b655def2d",
"type": "function",
"z": "4233a8e0fb20e448",
"name": "prepare data for Kaa MQTT ",
"func": "// Retrieving flow variables\nconst APP_VERSION = flow.get('APP_VERSION')\nconst TOKEN = flow.get('TOKEN')\n\n// Preparing data for Kaa MQTT broker\nmsg.topic = `kp1/${APP_VERSION}/dcx/${TOKEN}/json/1`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 440,
"y": 440,
"wires": [
[
"4d94e40615c6c571"
]
]
},
{
"id": "cba0c5d64f88a539",
"type": "function",
"z": "4233a8e0fb20e448",
"name": "prepare data for UDP client",
"func": "// Retrieving flow variables\nconst APP_VERSION = flow.get('APP_VERSION')\nconst TOKEN = flow.get('TOKEN')\nconst COUNT = flow.get('COUNT')\n\n// Preparing data for UDP client\nmsg.topic = `kp1/${APP_VERSION}/dcx/${TOKEN}/json/1`\nmsg.payload = JSON.stringify({\n \"count\": COUNT\n})\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 660,
"y": 260,
"wires": [
[
"e5143e5a61d7d576"
]
]
},
{
"id": "6c478a9c7ea3628c",
"type": "comment",
"z": "4233a8e0fb20e448",
"name": "IMPORTANT: Set the APP_VERSION and TOKEN",
"info": "",
"x": 290,
"y": 100,
"wires": []
},
{
"id": "ae5063aad4baa726",
"type": "comment",
"z": "4233a8e0fb20e448",
"name": "UDP Client",
"info": "",
"x": 160,
"y": 220,
"wires": []
},
{
"id": "c3ff3368734c048c",
"type": "comment",
"z": "4233a8e0fb20e448",
"name": "UDP Server",
"info": "",
"x": 170,
"y": 340,
"wires": []
},
{
"id": "e112d82b51d63bdb",
"type": "comment",
"z": "4233a8e0fb20e448",
"name": "Response from Kaa Mqtt",
"info": "",
"x": 210,
"y": 520,
"wires": []
},
{
"id": "9546f5a900614bbd",
"type": "comment",
"z": "4233a8e0fb20e448",
"name": "An empty payload indicates that there were no errors",
"info": "",
"x": 290,
"y": 560,
"wires": []
},
{
"id": "5b941733b228407a",
"type": "comment",
"z": "4233a8e0fb20e448",
"name": "This flow bridges UDP to MQTT",
"info": "",
"x": 230,
"y": 60,
"wires": []
},
{
"id": "62423136c882dab1",
"type": "function",
"z": "4233a8e0fb20e448",
"name": "increase count ",
"func": "// Custom logic to simulate a real device\n// Increase count by 1\nconst COUNT = flow.get('COUNT')\nflow.set('COUNT', COUNT + 1)\n\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 400,
"y": 260,
"wires": [
[
"cba0c5d64f88a539"
]
]
},
{
"id": "ecccd3107d6d1e04",
"type": "json",
"z": "4233a8e0fb20e448",
"name": "",
"property": "payload",
"action": "str",
"pretty": false,
"x": 470,
"y": 600,
"wires": [
[
"83939a8dbb0eed3c"
]
]
},
{
"id": "83939a8dbb0eed3c",
"type": "debug",
"z": "4233a8e0fb20e448",
"name": "debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 730,
"y": 600,
"wires": []
},
{
"id": "e5143e5a61d7d576",
"type": "udp out",
"z": "4233a8e0fb20e448",
"name": "udp client",
"addr": "127.0.0.1",
"iface": "",
"port": "5000",
"ipv": "udp4",
"outport": "",
"base64": false,
"multicast": "false",
"x": 900,
"y": 260,
"wires": []
},
{
"id": "76dc1858e3373d7f",
"type": "udp in",
"z": "4233a8e0fb20e448",
"name": "udp server",
"iface": "",
"port": "5000",
"ipv": "udp4",
"multicast": "false",
"group": "",
"datatype": "utf8",
"x": 160,
"y": 380,
"wires": [
[
"6d8970cf19cae3ad",
"dc0d141b655def2d"
]
]
},
{
"id": "dc0deea1.ea5b2",
"type": "mqtt-broker",
"name": "mqtt.cloud.kaaiot.com",
"broker": "mqtt.cloud.kaaiot.com",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
}
]
In Node-RED, click the red Deploy button at the top right of the screen to deploy your flow. Then, from the dropdown menu, select Restart to apply the changes and start the flow.
Next, open the debug tab in the sidebar and check if any logs appear.
If you see logs, it means everything is functioning correctly.
However, you may encounter errors like statusCode: 400
, which occur because the application version and endpoint token have not been provided yet.
As a result, the Kaa platform cannot identify the endpoint from which the data is coming.
To resolve this issue above, open the init CONSTANTS node and paste your application version and endpoint token into the code.
After making these changes, save the code, redeploy the flow, and restart it.
If everything was configured correctly, the statusCode
error should no longer appear.
Go back to Kaa, open your device page, and you should see the count
variable displayed on the graph.
This example runs both the client and server on port 5000
within a single flow.
You can use this flow to configure your own device to send data to Kaa.
If you’re running Node-RED on your local network, configure your device to send data to the IP address of the machine running Node-RED, using port 5000
(the Node-RED TCP/UDP server port).