Introduction
The Covid-19 pandemic has brought many changes to our daily lifestyle. Mask on, and social distancing is one of many. In my country, Singapore, every shopping mall, big or small attraction, must adhere to government restrictions on capacity limits. Many companies took this opportunity to digitally transform their operations by introducing robots, automated gantry, people counters, etc. SensMax is a low-cost, simple IR people counters that tally the number of people inside a space using the difference in numbers from the entrance and exit counters.
Background
SensMax comes with two types of devices, the bidirectional infrared beam sensors, which do the actual counting, and the collectors, which collect data from the IR sensors and upload them to SensMax cloud. Owners then can log in to the dashboard to view the live counts, create graphs and generate reports on the fly. However, if SensMax is deployed at multiple sites, it will be helpful to view all the live counts on a single webpage. The SensMax dashboard only provides individual site reports, but we can use their API to create a web page to include all. Optionally, we can manipulate the numbers to offset the actual count with a constant multiplier for a more accurate count.
Prerequisites
- PHP cURL extension
- HTML / CSS with Bootstrap framework
Get Data from Reports using SensMax API
<!DOCTYPE html>
<html>
<head>
<title>Cloud Variance % - My SensMax</title>
<meta http-equiv="refresh" content="10">
<link rel="stylesheet" href="/css/flatly/bootstrap.min.css">
</head>
<body>
<?php
/**
* Step 1 - Run function json_extract() and apply a constant multiplier
*/
$api = json_extract('https://my.sensmax.eu/api/v2/report/500738');
echo '<h4 class="text-primary pl-5 pt-4 pb-2">Cloud (variance)</h4>';
echo '<hr>';
echo '<h1 class="display-1 text-primary pl-5 pt-4 text-success">';
echo round($api['inside'] * 0.9). '<sub style="font-size:0.2em;">'.$api['inside'].'</sub>';
echo '</h1>';
echo '<p class="small text-muted pl-5">adjustment: actual -10% at Cloud';
echo '</p>';
/**
* Step 2 - Make HTTP request to my.sensmax.eu to download live number
*/
function json_extract($url)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
$headers = array(
'GET /api/v2/sensors HTTP/1.1',
'HOST: my.sensmax.eu',
'apikey: 0ffcef0ea6fcf87172f62b69d7742fc62e824ea6ab492419a',
'Content-Type', 'application/json',
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);
$a = json_decode($result, true); // remove \u0022id\
$a1 = substr($a, 1, -1); // remove [ ]
return json_decode($a1, true);
}
?>
</body>
</html>
Step 1 – Run function json_extract() to Get Live Count and Apply Multiplier
Line 14 execute function json_extract() and return data as an array to variable $api. Line 19 display both the number (after multiplier) and the actual number. For example, if the live count is over counting by 10%, we multiply the live count by 0.9 and vice versa; if the live count is undercounting by 10%, we multiply by 1.1 to get a more accurate live count. We display the SensMax actual count on the bottom right in smaller font size to be reminded that this location is under or overcount.
Step 2 – Make HTTP Request with cURL
Regarding the SensMax API manual online, we apply the GET, HOST, and apikey to our codes but replace the apikey with your own. To get your API key, log in to the SensMax dashboard and go to Profile. Then, click on the Get API key and enter your password. Lines 30 to 43 $headers and curl_setopt commands are standard ways to use cURL, so we will not go into details.
Example of raw data:
"[{\u0022id\u0022:6350,\u0022name\u0022:\u0022Cloud\u0022,\u0022date\u0022:\u00222021-11-01 23:55 +00:00\u0022,\u0022currentTime\u0022:\u00222021-11-01 16:22\u0022,\u0022inside\u0022:109,\u0022max\u0022:680,\u0022almostFullPreset\u0022:612,\u0022offline\u0022:false,\u0022color\u0022:\u0022green\u0022,\u0022message\u0022:\u0022Welcome to Cloud\u0022,\u0022messageWhenLimitReached\u0022:\u0022Cloud is full\u0022,\u0022messageWhenAlmostFullReached\u0022:\u0022Cloud is almost full\u0022,\u0022messageWhenFree\u0022:\u0022Welcome to Cloud\u0022}]"
Line 45 and 46 will strip all the \u0022 and remove the square brackets [ ]. The final JSON data:
{"id":6350,"name":"Cloud","date":"2021-11-01 23:55 +00:00","currentTime":"2021-11-01 16:27","inside":116,"max":680,"almostFullPreset":612,"offline":false,"color":"green","message":"Welcome to Cloud","messageWhenLimitReached":"Cloud is full","messageWhenAlmostFullReached":"Cloud is almost full","messageWhenFree":"Welcome to Cloud"}
We can get an array of data from this API, and some useful ones are name, inside, and max. Since we assign this array to $api, to get the live count, we use $api[‘inside’] to display the live number or $api[‘max’] to display the maximum capacity of the site.
Live Reports Overview (optional)
We use <iframe>, part of HTML language, to integrate all site reports into a single web page. Below is an example of a 2×2 grid layout using Bootstrap.
<?php
$title = 'Home';
<!DOCTYPE html>
<html>
<head>
<title>Home - My SensMax</title>
<link rel="stylesheet" href="/css/flatly/bootstrap.min.css">
<style>
.blocker { position:absolute; height:100%; width:100%; z-index:1; }
.linkwrap iframe { z-index: 2; }
</style>
</head>
<body>
<div class="container">
<div class="row mt-4">
<div class="col-sm-6">
<a href="https://my.sensmax.eu/r/500737" target="_blank" class="linkwrap">
<div class="blocker"></div>
<iframe height="400" src="https://my.sensmax.eu/r/500737" title="Flower" class="w-100">
</iframe>
</a>
</div>
<div class="col-sm-6">
<a href="https://my.sensmax.eu/r/500738" target="_blank" class="linkwrap">
<div class="blocker"></div>
<iframe height="400" src="https://my.sensmax.eu/r/500738" title="Cloud" class="w-100">
</iframe>
</a>
</div>
</div>
<div class="row mt-4">
<div class="col-sm-6">
<a href="https://my.sensmax.eu/r/500740" target="_blank" class="linkwrap">
<div class="blocker"></div>
<iframe height="400" src="https://my.sensmax.eu/r/500740" title="Floral" class="w-100">
</iframe>
</a>
</div>
<div class="col-sm-6">
<a href="https://my.sensmax.eu/r/500739" target="_blank" class="linkwrap">
<div class="blocker"></div>
<iframe height="400" src="https://my.sensmax.eu/r/500739" title="Skyway" class="w-100">
</iframe>
</a>
</div>
</div>
</body>
</html>
Conclusion
Apart from learning the SensMax API, we also learned how to use PHP cURL and <iframe> to consolidate multiple reports into a web page. The basic cURL commands can be used for other use cases like polling for a product price or availability and sending an email alert if there is a change. You can use the standard Bootstrap framework to build a simple website with APIs from any IoT device and showcase your soft skills to your management.