Requirements
An active Ubidots account
A Terabee people counting device, model M
WiFi/Ethernet Internet access
Table of contents
1. Setting up Terabee push configuration
An Ubifunction is a user-defined code that runs, on-demand, in our case, each time it receives new data from your Terabee sensor. We will use MQTT + Ubifunctions to allow the Terabee device model M to publish data to Ubidots. In section 2 of this article, you will see in detail how to create an Ubifunction. Having an Ubifunction already, here we will focus on how to set up a Terabee device using the relevant information about it and from your Ubidots account.
First, you should refer to your Terabees’s people counting M installation guide on how to access and open its user interface, then in section 6, they explain “Data Push settings” where you can choose whether HTTP or MQTT. We will use the latter for this example. Bear in mind that you can find your Ubidots username and your accounts token as indicated in this article. The Ubifunctions name can be checked as seen below.
With this at hand, we can go ahead and configure your Terabee People Counting model M as follows:
By checking “push on event” each time the values of the counters update, the device will publish data otherwise, you must check “push period(seconds)“ set a push period.
Check push to MQTT broker and enter mqtt://functions.ubidots.com
MQTT topic path: /prv/<Your Ubidots Username>/<Ubifunction’s Name>
User: <Your Ubidots Username>
Password: <Your Ubidots Token>
Authorization: <Your Ubidots Token>
Certificate: If you don't want to use it, then you must check on the Skip Common Name Verification Box otherwise, you can download and use one of the certificates available here in section 4. Here you can find a configuration sample.
2. Decoding Terabee payload using a Ubifunction
Data received by the Ubifunction in the “args” dictionary, can be printed, parsed, interpreted, and modified in order to create an Ubidots compatible JSON payload which will be sent to your Ubidots account by an HTTP “POST“ request allowing you to see the values of the people coming in or out and the number of people inside a room (people in - people out). Here’s an Ubifunction example code for a Terabee model M device, notice that in this case, we did not receive any value for the “at” key inside the “body”, therefore we set the timestamp using the Ubifunction by means of the datetime and pytz modules of Python 3.7.
'''
This code parses data comming from a terabee model M device and converts it into
an Ubidots compatible payload
'''
from datetime import datetime as dt
import pytz
import requests
import json
import time
TIMEZONE = "Europe/London" # or your corresponding timezone
TOKEN = "<your Ubidots token>"
BASE_URL = "https://industrial.api.ubidots.com"
REQUESTS_FUNCTIONS = {"get": requests.get, "post": requests.post}
def main(args):
'''
Main function - runs every time the function is executed.
"args" is a dictionary containing both the URL params and the HTTP body (for POST requests).
'''
NOW = dt.now(tz=pytz.timezone(TIMEZONE))
print(args) #Print payload recieved
payload = dict()
timestamp = int(NOW.timestamp()*1000)
data = json.loads(args["body"])
device = data["from_client_id"]
p_in = data["payload"]["value"]["in"]
p_out = data["payload"]["value"]["out"]
diff = p_in - p_out #People inside a room
if diff < 0:
diff = 0
payload["in"] = {"value": p_in, "timestamp": timestamp}
payload["out"] = {"value": p_out, "timestamp": timestamp}
payload["diff"] = {"value": diff, "timestamp": timestamp}
# Log the payload to the console, for debugging purposes. You may access the function's logs using
print("[INFO] Payload to send: {}".format(payload))
# Use the remaining parameters as payload
res = update_device(device, payload, TOKEN)
# Prints the request result
return {"status": "Ok", "result": res.json()}
def update_device(device, payload, token):
"""
updates a variable with a single dot
"""
url = "{}/api/v1.6/devices/{}".format(BASE_URL, device)
headers = {"X-Auth-Token": token, "Content-Type": "application/json"}
req = create_request(url, headers, payload, attempts=5, request_type="post")
return req
def create_request(url, headers, data, attempts, request_type):
"""
Function to create a request to the server
"""
request_func = REQUESTS_FUNCTIONS.get(request_type)
kwargs = {"url": url, "headers": headers}
if request_type == "post":
kwargs["json"] = data
try:
req = request_func(**kwargs)
print("[INFO] Request result: {}".format(req.text))
status_code = req.status_code
time.sleep(1)
while status_code >= 400 and attempts < 5:
req = request_func(**kwargs)
print("[INFO] Request result: {}".format(req.text))
status_code = req.status_code
attempts += 1
time.sleep(1)
return req
except Exception as e:
print("[ERROR] There was an error with the request, details:")
print(e)
return None
Once you have your payload decoded and sent to your account by the Ubifunction it will display as follows.