Hi all,
another small inspiration for how to use timeline diagrams in basic UI:
Again this needs my common openhab utility .js:
// ***
// * Required definitions:
// * - var baseURL = "../";
// *
// ***
// * Required API
// * - Google jQuery: https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// * - jQuery CSV: https://github.com/evanplaice/jquery-csv
// * - date.js: http://www.datejs.com/
// ***
function GetGroupItemNames(groupItem) {
var groupUrl = baseURL.concat("rest/items/").concat(groupItem);
var groupData = GetData(groupUrl);
var items = [];
groupData.members.forEach(function (item) {
items.push(item.name);
});
return items;
}
function GetOpenHABHistory(item, days, serviceId) {
var csv = GetOpenItemHABHistoryCSV(item, days, serviceId);
var arrayData = $.csv.toArrays(csv, {
onParseValue: $.csv.hooks.castToScalar
});
return arrayData;
}
function GetData(itemUrl) {
var itemValue = null;
$.ajax({
contentType: 'text/plain',
url: itemUrl,
data: {},
async: false,
success: function (data) {
if (data != "NULL") {
itemValue = data;
}
}
});
return itemValue;
}
// JSON to CSV Converter
function ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
for (var i = 0; i < array.data.length; i++) {
var line = '';
for (var index in array.data[i]) {
if (line !== '') line += ',';
line += array.data[i][index];
}
str += line + '\r\n';
}
return str;
}
function GetOpenHABItemState(item) {
var itemUrl = baseURL.concat("rest/items/").concat(item).concat("/state/");
return GetData(itemUrl);
}
function GetOpenHABItem(item) {
var itemUrl = baseURL.concat("rest/items/").concat(item);
return GetData(itemUrl);
}
function GetOpenHABItemIntValue(item) {
return Math.round(GetOpenHabItemState(item));
}
function GetOpenHABItemHistoryJSON(item, days = 1, service = "rrd4j") {
var jsonData = null;
// var numberOfMilliseconds = 86400 * 1000 * days;
var startTimeObject = (new Date()).addDays(days * -1);
// var endTimeObject = new Date();
var _month = startTimeObject.getMonth() + 1;
var _starttime = startTimeObject.getFullYear() + "-" + _month + "-" + startTimeObject.getDate() + "T" + startTimeObject.getHours() + ":" + startTimeObject.getMinutes() + ":" + startTimeObject.getSeconds();
// var _endtime = endTimeObject.getFullYear() + "-" + endTimeObject.getMonth() + "-" + endTimeObject.getDate() + "T" + endTimeObject.getHours() + ":" + endTimeObject.getMinutes() + ":" + endTimeObject.getSeconds();
var itemUrl = baseURL.concat("rest/persistence/items/").concat(item);
itemUrl = itemUrl.concat("?serviceId=" + service);
if (days != 1) {
itemUrl = itemUrl.concat("&starttime=" + _starttime);
}
// itemUrl = itemUrl.concat("&endtime=" + _endtime);
jsonData = GetData(encodeURI(itemUrl));
return jsonData;
}
function GetOpenItemHABHistoryCSV(item, days = 1, service = "rrd4j") {
var jsonData = GetOpenHABItemHistoryJSON(item, days, service);
return ConvertToCSV(jsonData);
}
function GetParameter(parameterName) {
var result = null,
tmp = [];
location.search.substr(1).split("&")
.forEach(function (item) {
tmp = item.split("=");
if (tmp[0] === parameterName) {
result = decodeURIComponent(tmp[1]);
}
});
return result;
}
function DOMSetElementHeight(elementId, height) {
var pageElement = document.getElementById(elementId);
pageElement.style.height = height + "px";
}
function DOMSetElementWidth(elementId, width) {
var pageElement = document.getElementById(elementId);
pageElement.style.width = width + "px";
}
The .css:
visualizationStyle.css (163 Bytes)
The html page to create a timeline diagram from a switch group:
<!DOCTYPE html>
<html>
<head>
<Title>Timeline</Title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="stylesheet" type="text/css" href="../css/visualizationStyle.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<!-- https://github.com/evanplaice/jquery-csv -->
<script type="text/javascript" src="../javascript/jquery.csv.min.js"></script>
<script type="text/javascript" src="../javascript/date.js"></script>
<script type="text/javascript" src="../javascript/openHAB.js"></script>
<script type="application/javascript">
var baseURL = "../../../";
var serviceId = "rrd4j";
var openHABItemNames = [];
var groupParameter = GetParameter("Group");
var itemParameter = GetParameter("Item");
if (groupParameter != null) {
openHABItemNames = GetGroupItemNames(GetParameter("Group"));
}
if (itemParameter != null) {
openHABItemNames.push(itemParameter);
}
var numberOfDays = 1;
function filterStateChanges(data) {
var filteredData = [];
for (var i = 0; i < data.length; i++) {
// always keep the 1st entry ...
if (i == 0) {
if (data[i][1] == "ON")
filteredData.push(data[i]);
} else {
// only keep transitions ...
if (data[i][1] != data[i - 1][1]) {
filteredData.push(data[i]);
}
}
}
return filteredData;
}
function addItemToChart(itemName, numberOfDays, serviceId, chartData) {
var openHABItem = GetOpenHABItem(itemName);
var openHABHistoryData = GetOpenHABHistory(itemName, numberOfDays, serviceId);
var stateChanges = filterStateChanges(openHABHistoryData);
for (var i = 0; i < stateChanges.length; i++) {
var entry = [];
entry[0] = openHABItem.label;
entry[1] = new Date(parseInt(stateChanges[i][0]));
if (i + 1 < stateChanges.length) {
entry[2] = new Date(parseInt(stateChanges[++i][0]));
} else {
entry[2] = new Date();
}
chartData.addRow(entry);
}
return chartData;
}
function drawChart() {
var container = document.getElementById("chart");
var chart = new google.visualization.Timeline(container);
var chartData = new google.visualization.DataTable();
chartData.addColumn({
type: 'string',
id: "Label"
});
chartData.addColumn({
type: 'date',
id: 'Start'
});
chartData.addColumn({
type: 'date',
id: 'End'
});
openHABItemNames.forEach(function(itemName) {
chartData = addItemToChart(itemName, numberOfDays, serviceId, chartData);
});
var xAxisFormat = "HH:mm"; // "EEE, HH:mm";
var chartOptions = {
height : window.innerHeight,
/* A theme is a set of predefined option values that work together to achieve
* a specific chart behavior or visual effect. Currently only one theme is available:
* 'maximized' - Maximizes the area of the chart, and draws the legend and
* all of the labels inside the chart area.
*/
theme: 'maximized',
hAxis: {
textPosition: 'in',
format: xAxisFormat
}
}
chart.draw(chartData, chartOptions);
};
// on document ready ...
$(document).ready(function() {
// load google charts ...
google.charts.load("current", {
packages: ["timeline"]
});
// set callback ...
google.charts.setOnLoadCallback(drawChart);
});
</script>
</head>
<body>
<center>
<div id="chart"></div>
</center>
</body>
</html>
And the entry in the sitemap:
Webview url="/static/Visualization/Timeline.html?Group=GroupStatus" height=9
As usual not a step-by-step guide; but some hints how to achieve this (I call them inspirations ) … hope it is helpful.
with kind regards,
Patrik