By Daniel Du
In previous blog, I introduced how I create a simplest weather station with Arduino and connect it to cloud. In this post, I will introduce how I consume the temperature from a client. To make it fun, I use View and Data API. Think about following scenario, the temperature sensor is installed somewhere in a smart building, or a device in a smart factory, as an import part of facility management(FM) system, we need to see real time information of the sensor and show it in BIM model.
In my sample, pretend that I install the temperature sensor on the top of gate house, I need to see the template line chart of the senor. In previous blog, I created a RESTful server so that the Arduino can post temperature value to the server periodically, now I need to keep working on the server so that client can get the temperature values and show them in a line chart. In my router configuration (compete code) I add following code
router.route('/sensors/:sensorId/values/:count')
.get(sensorController.getSensorLastNValues)
Here is the code snippet in sensor controller , I get the last N temperature values from MongoDb and output as JSON, so that it could be consumed by other clients.
exports.getSensorLastNValues = function(req,res){ var sensorId = req.params.sensorId; var count = req.params.count; Sensor.findById(sensorId, function(err, sensor){ if(err) res.json(err); if(sensor && sensor.values){ var total = sensor.values.length; if(count > total) { res.json(sensor.values); //return all values } else { res.json(sensor.values.slice(sensor.values.length - count)); } } else{ res.json({ message : "sensor with specified id does not exist."}) } }) }
Now let’s go to the client side, I am using View and Data Client API with JavaScript, so my client is browser, I will create a data loader in JavaScript to get the temperatures with REST. As defined in the route of server, it would be GET /api/sensors/<sensorId>/values/10. Here is the code snippet, the complete code is on github.
dataloader.getLast10Temperatures = function(onSuccess) { //get last 10 temperature items var url = '/api/sensors/561083be06dd6162658ae8c8/values/10'; $.getJSON(url, function(data){ if(!Array.isArray(data)) return; //sort by timestamp data.sort(function(a,b){ return parseInt(a.timeStamp) - parseInt(b.timeStamp); }); onSuccess(data); }); }
To show the temperature line chart, firstly I create an docking panel with View and Data API as the container. Here is an example of docking panel created by Philippe, so I will skip this part. To draw the temperature line chat, I use Chart.js which is pretty popular chart library to generate charts in various style. Here is the code snippet, the complete code of this part is on github:
//////////////////////////////////// ///Generate the chart /// //////////////////////////////////// var gernerateTempChart = function(){ var lineChartData = { labels : [], datasets : [ { label: "Temperatures", fillColor : "rgba(220,220,220,0.2)", strokeColor : "rgba(220,220,220,1)", pointColor : "rgba(220,220,220,1)", pointStrokeColor : "#fff", pointHighlightFill : "#fff", pointHighlightStroke : "rgba(220,220,220,1)", data : [] } ] } dataloader.getLast10Temperatures(function(tempItems){ //clear first lineChartData.labels.length = 0; lineChartData.datasets[0].data.length = 0; //prepare data tempItems.forEach(function(tempItem){ //add time as label var timeStamp = tempItem.timestamp; var lbl = new Date(timeStamp).toLocaleTimeString(); lineChartData.labels.push(lbl); //add temperature values var temperature = parseFloat(tempItem.value).toFixed(1);// 0.1 degree precise lineChartData.datasets[0].data.push(temperature); }); var min = Math.min.apply(null, lineChartData.datasets[0].data) ; var max = Math.max.apply(null, lineChartData.datasets[0].data) ; var steps = lineChartData.datasets[0].data.length ; var stepsWidth = (max - min) / steps; var stepValue = min; //with 1 degree as bottom margin on chart //so that the lowered point does not fall on the x-axis var margin = 0.5; if(max - min < 1 ){ //temperature almost constant, change is less than 1 degree stepsWidth = 1.0 / steps; stepValue = min - margin; }else{ stepsWidth = (max - min) * 1.0 / steps; stepValue = min - margin ; } //generate the chart var ctx = document.getElementById("canvasChart").getContext("2d"); window.myLine = new Chart(ctx).Line(lineChartData, { responsive: true , scaleOverride : true, scaleSteps : steps, scaleStepWidth : stepsWidth, scaleStartValue : stepValue, scaleLabel: "<%= Number(value).toFixed(1) %>" }); }); }
With that, I can draw a temperate line chart on a docking panel of viewer with View and Data API. If you are interested, please find the complete code on github: https://github.com/duchangyu/project-arduivew/tree/v0.1
Great Information. Thank You Author, for sharing your valuable information about iot with us. People who are reading this blog can continue your knowledge which you gained with us and know how to apply this practically along with our IoT Training
Posted by: SFJ Business Solution Training | 02/17/2019 at 11:33 PM