Dashboard

Flow Event Grid Widget

<div class="row">
    <div class="col-md-12">
        <div class="table-responsive">
            <h5>Total Records: <span class="totalCount"></span></h5>
            <table id="gridTable" class="display nowrap table table-hover table-bordered" cellspacing="0" width="100%">
            </table>
        </div>

    </div>
</div>
table{
    font-size:13px;
}
/********************************************
 Pre Defined variables to access in the widget 
********************************************/

// API_BASE_PATH - to get boodskap api base path
// DOMAIN_KEY - to get domain key
// API_KEY - to get api key
// API_TOKEN - to get api token
// MESSAGE_ID - to get message id
// DEVICE_ID - to get device id
// ASSET_ID - to get asset id
// RECORD_ID - to get record id
// WIDGET_ID - to get current widget id
// USER_ID - to get user id (In public share this will be empty)

$(document).ready(function () {
//To start realtime time update
startLiveUpdate()
loadTable();
});
var loading=true;
// for realtime update, call the initial method inside this function too
function liveUpdate(){ 
    
    if(loading){
        loading=false;
        loadTable();    
    }
    

}

var gridTable = null;



function loadTable(){
    
    
     if (gridTable) {
        gridTable.destroy();
        $("#gridTable").html("");
    }

    
      var fields = [
          
           {
            mData: 'created_ts',
            orderable: true,
            "aTargets": [ 0 ],
            sTitle: 'Last Updated Time',
            mRender: function (data, type, row) {

                return moment(data).format('MM/DD/YYYY hh:mm:ss a')
            }
        },
        
        {
            mData: 'device_id',
            sTitle: 'Device',
            orderable: false,
            mRender: function (data, type, row) {

                return '<b>'+data+'</b>';
            }
        },
        
        {
            mData: 'event_name',
            sTitle: 'Event Name',
            orderable: false,
            mRender: function (data, type, row) {
                
                var str="";
                
                if(data =="HIGH"){
                    str = '<label class="label label-danger">High</label>'
                }
                else if(data == "LOW"){
                    str = '<label class="label label-warning">Low</label>'
                }
                return data+' FLOW<br>'+str;
            }
        },
       
       

    ];

    var queryParams = {
        query: {
            "bool": {
                "must": [],

            }
        },
        sort: [{"created_ts": {"order": "desc"}}],
    };



    var tableOption = {
        fixedHeader: false,
        responsive: false,
        paging: true,
        searching: true,
        //aaSorting: [[5, 'desc']],
        "ordering": true,
        iDisplayLength: 5,
        lengthMenu: [[5,10, 50, 100], [5,10, 50, 100]],
        aoColumns: fields,
        "oLanguage": {
            sSearchPlaceholder : 'Search',
            "sSearch": "<i class='fa fa-search'></i>",
            "sProcessing": '<i class="fa fa-spinner fa-spin" style="color:#333"></i> Processing',
            "sEmptyTable" : "No data available!",
        },
        "bProcessing": true,
        "bServerSide": true,
        "sAjaxSource": API_BASE_PATH + "/elastic/search/query/" + API_TOKEN,
        "fnServerData": function (sSource, aoData, fnCallback, oSettings) {

            queryParams.query['bool']['must'] = [];
            queryParams.query['bool']['should'] = [];
            delete queryParams.query['bool']["minimum_should_match"];

            var keyName = fields[oSettings.aaSorting[0][0]]

            var sortingJson = {};
            sortingJson[keyName['mData']] = {"order": oSettings.aaSorting[0][1]};
            queryParams.sort = [sortingJson];

            queryParams['size'] = oSettings._iDisplayLength;
            queryParams['from'] = oSettings._iDisplayStart;

            var searchText = oSettings.oPreviousSearch.sSearch;

            if (searchText) {

                queryParams.query['bool']['should'].push({"wildcard" : { "device_addr" : "*"+searchText.toLowerCase()+"*" }})
              
                queryParams.query['bool']["minimum_should_match"]=1;

            }
            
             var searchQuery = {
                "extraPath": "",
                "query": JSON.stringify(queryParams),
                "params": [],
                "specId" : RECORD_ID,
                "type":"RECORD"
            };



            oSettings.jqXHR = $.ajax({
                "dataType": 'json',
                "contentType": 'application/json',
                "type": "POST",
                "url": sSource,
                "data": JSON.stringify(searchQuery),
                success: function (data) {
                    
                    


                    var resultData = searchQueryFormatter(data).data;

                    $(".totalCount").html(resultData.recordsFiltered);

                  
                    resultData['draw'] = oSettings.iDraw;
                    
                    loading=true;

                    fnCallback(resultData);
                }
            });
        }

    };

    gridTable = $("#gridTable").DataTable(tableOption);


}


function searchQueryFormatter(data) {

        var resultObj = {
            total: 0,
            data: {},
            aggregations: {}
        }

        if (data.httpCode === 200) {

            var arrayData = JSON.parse(data.result);

            var totalRecords = arrayData.hits.total.value;
            var records = arrayData.hits.hits;

            var aggregations = arrayData.aggregations ? arrayData.aggregations : {};


            for (var i = 0; i < records.length; i++) {
                records[i]['_source']['_id'] = records[i]['_id'];
            }

            resultObj = {
                "total": totalRecords,
                "data": {
                    "recordsTotal": totalRecords,
                    "recordsFiltered": totalRecords,
                    "data": _.pluck(records, '_source')
                },
                aggregations: aggregations
            }

            console.log(resultObj)
            return resultObj;

        } else {

            return resultObj;
        }

    }
// CSS
cdn.datatables.net/1.11.2/css/jquery.dataTables.min.css


//JS
cdn.datatables.net/1.11.2/js/jquery.dataTables.min.js

Flow Gauge Widget

<p>Last Reported Time: <span id="reported_ts"></span></p>
<div class = "container" id="chart_div" style="width: 400px; height: 120px;"></div>
#box{
   
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

#chart_div text {
  font-size: 16;
 
}
/********************************************
 Pre Defined variables to access in the widget 
********************************************/

// API_BASE_PATH - to get boodskap api base path
// DOMAIN_KEY - to get domain key
// API_KEY - to get api key
// API_TOKEN - to get api token
// MESSAGE_ID - to get message id
// DEVICE_ID - to get device id
// ASSET_ID - to get asset id
// RECORD_ID - to get record id
// WIDGET_ID - to get current widget id
// USER_ID - to get user id (In public share this will be empty)

var DATA_FIELD = "flow_rate"
var FLOW_UNIT = 'L/mins'
var DATE_TIME_FORMAT = 'MM/DD/YYYY hh:mm:ss a';
var CHART_WIDTH = 600
var CHART_HEIGHT = 300
var CHART_LABEL = 'Flow Rate in'+' '+FLOW_UNIT
var	RED_FROM = 90
var RED_TO = 100
var YELLOW_FROM = 75
var YELLOW_TO = 90
var MINOR_TICKS = 5

		  


$(document).ready(function () {
//To start realtime time update


startLiveUpdate()
loadPage()

});

// for realtime update, call the initial method inside this function too
function liveUpdate(){ 
loadPage()
}

function loadPage(){
    
 var queryParams = {
        sort: [{
            receivedstamp: {
                order: 'desc'
            }
        }],
        size: 1,
        query: {
            bool: {
                must: [{
                    match: {
                        deviceid: DEVICE_ID
                    }
                }]
            }
        }
    };
    var searchQuery = {
        "extraPath": "",
        "query": JSON.stringify(queryParams),
        "params": [],
        "specId": MESSAGE_ID,
        "type": "MESSAGE"
    };
    searchByQuery(searchQuery, function(status, data) {
        if (status) {
            var result = searchQueryFormatter(data);
            if (result.total > 0) {
                var resultData = result.data.data;
                $("#reported_ts").html(resultData[0].receivedstamp ? moment(resultData[0].receivedstamp).format(DATE_TIME_FORMAT) : "-")

                renderGauge(resultData, DATA_FIELD);
            } 
        } else {
            $('.container-widget').html('<h5 class="text-danger text-center py-5"><i class="fa fa-info-circle" aria-hidden="true"></i> Please Check the widget configuration settings</h5>');
        }
    });
    
}    

function searchByQuery(data, cbk) {
    $.ajax({
        url: API_BASE_PATH + "/elastic/search/query/" + API_TOKEN,
        data: JSON.stringify(data),
        contentType: "application/json",
        type: 'POST',
        success: function(data) {
            //called when successful
            cbk(true, data);
        },
        error: function(e) {
            //called when there is an error
            cbk(false, e);
        }
    });
}
function searchQueryFormatter(data) {
    var resultObj = {
        total: 0,
        data: {},
        aggregations: {}
    };
    if (data.httpCode === 200) {
        var arrayData = JSON.parse(data.result);
        var totalRecords = arrayData.hits.total.value;
        var records = arrayData.hits.hits;
        var aggregations = arrayData.aggregations ? arrayData.aggregations : {};
        for (var i = 0; i < records.length; i++) {
            records[i]['_source']['_id'] = records[i]['_id'];
        }
        resultObj = {
            "total": totalRecords,
            "data": {
                "recordsTotal": totalRecords,
                "recordsFiltered": totalRecords,
                "data": _.pluck(records, '_source')
            },
            aggregations: aggregations
        };
        return resultObj;
    } else {
        return resultObj;
    }
}
    

function renderGauge(data)
{    
      google.charts.load('current', {'packages':['gauge']});
      google.charts.setOnLoadCallback(drawChart);
      
      var value = data[0][DATA_FIELD] ? data[0][DATA_FIELD] : "-"

      function drawChart() {

        var data = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          [CHART_LABEL,value],
        
        ]);
        		  


        var options = {
          width: CHART_WIDTH, 
          height: CHART_HEIGHT,
          redFrom: RED_FROM, 
          redTo: RED_TO,
          yellowFrom:YELLOW_FROM, 
          yellowTo: YELLOW_TO,
          minorTicks: MINOR_TICKS
        };

        var chart = new google.visualization.Gauge(document.getElementById('chart_div'));

        chart.draw(data, options);

}}
//Java Script
https://www.gstatic.com/charts/loader.js

Flow Line Chart Widget

<div id="chart" style="width:auto; height:80%;"></div>
#box{
   
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

#chart text {
  font-size: 13px;
 
}
/********************************************
Pre Defined variables to access in the widget 
********************************************/

// API_BASE_PATH - to get boodskap api base path
// DOMAIN_KEY - to get domain key
// API_KEY - to get api key
// API_TOKEN - to get api token
// MESSAGE_ID - to get message id
// DEVICE_ID - to get device id
// ASSET_ID - to get asset id
// RECORD_ID - to get record id
// WIDGET_ID - to get current widget id
// USER_ID - to get user id (In public share this will be empty)

// majar properties
var CHART_TITLE = "Flow Rate History";

var YAXIS_LABEL = 'Flow Rate';
var YAXIS_VALUES = 'flow_rate'; //message field name

var XAXIS_LABEL = 'Time';
var XAXIS_VALUES = 'receivedstamp'; //message field name
var DATE_TIME_FORMAT = 'MM/DD/YYYY hh:mm a';



$(document).ready(function () {
	//To start realtime time update
	startLiveUpdate();
	loadPage();
  
});

// for realtime update, call the initial method inside this function too
function liveUpdate() {

	loadPage();
}

function loadPage() {

	var queryParams = {
		sort: [{
			receivedstamp: {
				order: 'desc'
			}
		}],
		size: 300,
		query: {
			bool: {
				must: [{
					match: {
						deviceid: DEVICE_ID
					}
				}]
			}
		}
	};

	var searchQuery = {
		"extraPath": "",
		"query": JSON.stringify(queryParams),
		"params": [],
		"specId": MESSAGE_ID,
		"type": "MESSAGE"
	};

	searchByQuery(searchQuery, function (status, data) {
		if (status) {

			var result = searchQueryFormatter(data);
			if (result.total > 0) {

				var resultData = result.data.data;

				renderChart(resultData);
			} else {
				renderChart(0);
			}
		} else {
			$('.main').html('<h5 class="text-danger text-center py-5"><i class="fa fa-info-circle" aria-hidden="true"></i> Please Check the widget configuration settings</h5>');
		}
	});
}

function searchByQuery(data, cbk) {

	$.ajax({
		url: API_BASE_PATH + "/elastic/search/query/" + API_TOKEN,
		data: JSON.stringify(data),
		contentType: "application/json",
		type: 'POST',
		success: function (data) {
			//called when successful
			cbk(true, data);
		},
		error: function (e) {
			//called when there is an error
			cbk(false, e);
		}
	});
}

function searchQueryFormatter(data) {

	var resultObj = {
		total: 0,
		data: {},
		aggregations: {}
	};
	if (data.httpCode === 200) {

		var arrayData = JSON.parse(data.result);
		var totalRecords = arrayData.hits.total.value;
		var records = arrayData.hits.hits;
		var aggregations = arrayData.aggregations ? arrayData.aggregations : {};

		for (var i = 0; i < records.length; i++) {
			records[i]['_source']['_id'] = records[i]['_id'];
		}

		resultObj = {
			"total": totalRecords,
			"data": {
				"recordsTotal": totalRecords,
				"recordsFiltered": totalRecords,
				"data": _.pluck(records, '_source')
			},
			aggregations: aggregations
		};
		return resultObj;

	} else {

		return resultObj;
	}

}


function renderChart(data){
    
    google.charts.load('visualization', { packages: ['corechart'] });
    google.charts.setOnLoadCallback(drawLineChart);

    function drawLineChart() {
        
              var value_array = [[YAXIS_LABEL, XAXIS_LABEL,]]; 
       
                $.each(data, function (index, value) {

                    value_array.push([moment(value[XAXIS_VALUES]).format(DATE_TIME_FORMAT), value[YAXIS_VALUES]]);
                });

                // Set chart Options.
                var options = {
                    title: CHART_TITLE,
                    legend: { position: 'none' },

                   
                
                     hAxis: {
                          title: XAXIS_LABEL
                     },
                     vAxis: {
                          title: YAXIS_LABEL
                    },
                    tooltip: {isHtml: true}

                };

                // Create DataTable and add the array to it.
                var figures = google.visualization.arrayToDataTable(value_array)

                // Define the chart type (LineChart) and the container (a DIV in our case).
                var chart = new google.visualization.LineChart(document.getElementById('chart'));
                chart.draw(figures, options);      // Draw the chart with Options.
            }
           
}
//Java Script File
https://www.gstatic.com/charts/loader.js

Total Consumption Widget

<div class="container-fluid" id="box">
  <div class="card">
   
    <div class="card-body">
        <p>Last Reported Time: <span id="reported_ts"></span></p>
         
        <h4 class="center">Total Consumption</h4><br><br>
        
        <img id="icon"
        src="https://cdn-icons-png.flaticon.com/512/4343/4343120.png" alt="" /><br><br>
        
        <p class="center" id="value_text"><span  id="consumption"></span> <span id="consumption_unit"></span></p>


    </div> 
    
  </div>
</div>
.center{
    text-align:center;
}


#icon{
  display: block;
  margin-left: auto;
  margin-right: auto;
  width: 15%;
  height:15%;
}

#value_text{
    font-size:20px;
}
/********************************************
 Pre Defined variables to access in the widget 
********************************************/

// API_BASE_PATH - to get boodskap api base path
// DOMAIN_KEY - to get domain key
// API_KEY - to get api key
// API_TOKEN - to get api token
// MESSAGE_ID - to get message id
// DEVICE_ID - to get device id
// ASSET_ID - to get asset id
// RECORD_ID - to get record id
// WIDGET_ID - to get current widget id
// USER_ID - to get user id (In public share this will be empty)

var DATA_FIELD = 'total_consumption'
var CONSUMPTION_UNIT = 'L'
var DATE_TIME_FORMAT = 'MM/DD/YYYY hh:mm:ss a';

$(document).ready(function () {
//To start realtime time update


$("#main").css('height',  '100%');
startLiveUpdate()
loadPage()

});

// for realtime update, call the initial method inside this function too
function liveUpdate(){ 
loadPage()
}

function loadPage(){
    
 var queryParams = {
        sort: [{
            receivedstamp: {
                order: 'desc'
            }
        }],
        size: 1,
        query: {
            bool: {
                must: [{
                    match: {
                        deviceid: DEVICE_ID
                    }
                }]
            }
        }
    };
    var searchQuery = {
        "extraPath": "",
        "query": JSON.stringify(queryParams),
        "params": [],
        "specId": MESSAGE_ID,
        "type": "MESSAGE"
    };
    searchByQuery(searchQuery, function(status, data) {
        if (status) {
            var result = searchQueryFormatter(data);
            if (result.total > 0) {
                var resultData = result.data.data;
             

                renderContent(resultData);
            } 
        } else {
            $('.container-widget').html('<h5 class="text-danger text-center py-5"><i class="fa fa-info-circle" aria-hidden="true"></i> Please Check the widget configuration settings</h5>');
        }
    });
    
}    

function searchByQuery(data, cbk) {
    $.ajax({
        url: API_BASE_PATH + "/elastic/search/query/" + API_TOKEN,
        data: JSON.stringify(data),
        contentType: "application/json",
        type: 'POST',
        success: function(data) {
            //called when successful
            cbk(true, data);
        },
        error: function(e) {
            //called when there is an error
            cbk(false, e);
        }
    });
}
function searchQueryFormatter(data) {
    var resultObj = {
        total: 0,
        data: {},
        aggregations: {}
    };
    if (data.httpCode === 200) {
        var arrayData = JSON.parse(data.result);
        var totalRecords = arrayData.hits.total.value;
        var records = arrayData.hits.hits;
        var aggregations = arrayData.aggregations ? arrayData.aggregations : {};
        for (var i = 0; i < records.length; i++) {
            records[i]['_source']['_id'] = records[i]['_id'];
        }
        resultObj = {
            "total": totalRecords,
            "data": {
                "recordsTotal": totalRecords,
                "recordsFiltered": totalRecords,
                "data": _.pluck(records, '_source')
            },
            aggregations: aggregations
        };
        return resultObj;
    } else {
        return resultObj;
    }
}
    
function renderContent(data){
    
       $("#reported_ts").html(data[0].receivedstamp ? moment(data[0].receivedstamp).format(DATE_TIME_FORMAT) : "-")
        $("#consumption").html(data[0][DATA_FIELD]  ? data[0][DATA_FIELD] : "-")
        $("#consumption_unit").html( CONSUMPTION_UNIT ? CONSUMPTION_UNIT : "")

    
    
    
}
//CSS
https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css

//JS
https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js