Overview
The Channel Feeds Data Forwarding service will forward a copy of the original feed data from any UbiBot device to the given URL endpoint. This can be useful to seamlessly connect UbiBot devices to third-party platform business logic or third-party applications. This service requires activation on the UbiBot platform along with some development work on the data endpoint to correctly handle the incoming data feeds.
Activation Method
- Please login to https://console.ubibot.com
- From left side menu, click “Data Factory” -> “Data Forwarding”.
- Follow the “Add new forwarding” instructions.
Data Forwarding Message Format
Data forwarding is achieved by sending POST requests to the given endpoint URL. The Content-Type header is set to “application/json”. The original feed data is contained in the request body as follows:
- The feed data will be forwarded in JSON format to the given URL.
- The unique device channel_id: (string) can be used to distinguish the data from different devices.
- product_id: (string) device model
- serial: (string) serial number of the device.
- The feeds are an array consisting of:
- created_at: the time when the data feed was sampled in ISO 8601 format.
- field1..field10: sensor readings
- status: status information, such as SSID and ICCID
Note that you will need to send a response to the UbiBot platform within 15 seconds for each message.
Example Forwarded Data:
{
"channel_id": "123456",
"product_id": "ubibot-ws1p",
"serial": "123456XXXXX",
"feeds": [{
"created_at": "2022-04-24T09:06:56Z",
"field1": 24.495308
}, {
"created_at": "2022-04-24T09:06:56Z",
"field2": 82
}, {
"created_at": "2022-04-24T09:07:00Z",
"field5": -34
}],
"status": "mac=98:7b:f3:10:a1:e2,usb=1",
"ssid_base64": "VFBHUw=="
}
Requirements for Endpoint Response
- Please ensure the endpoint’s response is made within 15 seconds, otherwise the platform will close the connection.
- If the endpoint sends a response with the string “SUCCESS”, the platform will mark this forward request as successful. If the endpoint sends the string “ERROR” it means the request was unsuccessful. The UbiBot platform keeps track of all the response results for statistics purposes.
Simple PHP endpoint example:
<?php
try{
$data = file_get_contents('php://input'); //get POST payload forwarded from the UbiBot platform
$json = json_decode($data, true); //parse input data into json. You can handle the $json object from here.
//------Please make sure the response is made within 15 seconds, otherwise connection will be disconnected and marked unsuccessful.----------//
$myfile = file_put_contents('log.txt', $data.PHP_EOL , FILE_APPEND | LOCK_EX); //Write to a local log file for the demo.
echo "SUCCESS"; // if the request has been handled successfully.
}
catch (Exception $ex)
{
echo "ERROR";// if there is some error encountered
}
Simple NodeJS endpoint example:
const http = require('http');
const server = http.createServer(function (req, res) {
let type = req.headers["content-type"];
if (req.method.toLowerCase() === 'post' && type === "application/json") {
try{
////get POST payload
var jsonData = "";
req.on("data", function(chunk) {
jsonData += chunk;
});
req.on("end", function() {
//parse input data into json
var reqObj = JSON.parse(jsonData);
//-----------Make sure response is sent within 15 seconds------------//
var fs = require('fs');
fs.writeFile("log.txt", JSON.stringify(reqObj), function(err) {
if(err) {
res.end('ERROR');//mark request as error
}
});
res.end('SUCCESS');//mark request as successful
});
}catch{
res.end('ERROR');//mark request as error
}
}else{
res.end('ERROR');//mark request as error
}
});
//Setup listening IP and port
server.listen(8080, "127.0.0.1", function () {
console.log("server is started listen port 8080");
});
Simple Python endpoint example:
from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
import json
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
try:
ctype, pdict = cgi.parse_header(self.headers.get('content-type'))
if ctype == 'application/json':
#get POST payload, parse input data into json
length = int(self.headers['content-length'])
jsonArray = json.loads(self.rfile.read(length))
#-----------Make sure response is made within 15 seconds------------#
myfile = open("log.txt",'a')
myfile.write(json.dumps(jsonArray))
myfile.write("\n")
myfile.close()
#request handled successfully
self.protocal_version = 'HTTP/1.1'
self.send_response(200)
self.send_header("Welcome", "Contect")
self.end_headers()
self.wfile.write(bytes("SUCCESS", "utf-8"))
return
else:
#request handled with error
self.protocal_version = 'HTTP/1.1'
self.send_response(300)
self.send_header("Welcome", "Contect")
self.end_headers()
self.wfile.write(bytes("ERROR", "utf-8"))
return
except:
#request handled with error
self.protocal_version = 'HTTP/1.1'
self.send_response(300)
self.send_header("Welcome", "Contect")
self.end_headers()
self.wfile.write(bytes("ERROR", "utf-8"))
return
def run():
port = 8080
print('starting server, port', port)
# Server settings
server_address = ('', port)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
if __name__ == '__main__':
run()
Simple C# ASP.NET endpoint example:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace demo1.Controllers
{
public class FeedData
{
public DateTime created_at { get; set; }
public object field1 { get; set; }
public object field2 { get; set; }
public object field3 { get; set; }
public object field4 { get; set; }
public object field5 { get; set; }
public object field6 { get; set; }
public object field7 { get; set; }
public object field8 { get; set; }
public object field9 { get; set; }
public object field10 { get; set; }
}
public class DeviceData
{
public string channel_id { get; set; }
public string status { get; set; }
public List feeds { get; set; }
public string ssid_base64 { get; set; }
}
[Route("api/[controller]")]
[ApiController]
public class RestApiController : ControllerBase
{
[HttpPost]
[Route("recv")]
public string ReceiveData([FromBody] DeviceData data)
{
try
{
//Data is used for processing
return "SUCCESS";//Successfully processed a request
}
catch (Exception)
{
return "ERROR";//An error occurred while processing your request
}
}
}
}