Channel Data Forwarding

Overview

The Channel 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
            }
        }
    }
}