sentilo-catalog-web/src/main/webapp/static/js/sentilo/universal_map.js
var sensorsLastObsMap = [];
var defaultChartObsLimit = 10;
var maxChartObsLimit = 200;
var componentDetailUrl;
var currentComponentId = null;
var chartNav = null;
var carousel = null;
var fullscreenActive = false;
const carouselConfig = {
slidesToShow: 4,
infinite: false,
draggable: true,
variableWidth: true
};
window.messages = {
boolValues: {
trueValue: 'yes',
falseValue: 'no'
}
};
var mapOptions = {
modalTargetId: null,
infoboxTargetId: null,
componentDetailsUrl: null,
map: null
};
function initUniversalMap(options) {
mapOptions = options;
if (options.modalTargetId === null || options.modalTargetId === undefined || options.modalTargetId !== '') {
mapOptions.modalTargetId = "#component-detail-modal-info-window";
}
if (options.infoboxTargetId === null || options.infoboxTargetId === undefined || options.infoboxTargetId === '') {
mapOptions.infoboxTargetId = "#infobox";
}
registerSectionPillChangeEvents();
}
function showModalLayer() {
var modal = $(mapOptions.modalTargetId);
if (!modal) {
return;
}
modal.show(100, function () {
// Set modal layer as opened
$("body").addClass('modal-layer-opened').trigger('modal-layer-opened');
});
}
function hideModalLayer() {
var modal = $(mapOptions.modalTargetId);
if (!modal) {
return;
}
modal.hide(100, function () {
// Set modal layer as closed
$("body").removeClass('modal-layer-opened').trigger('modal-layer-closed');
destroySlick(true);
});
}
function isModalLayerVisible() {
const modal = $(mapOptions.modalTargetId);
return $(modal).is(":visible");
}
function destroySlick(removeItems) {
if(carousel)
$(".carousel").slick('unslick');
if(removeItems || carousel)
$(".carousel").find(".sensorItem").remove();
}
function initCarousel() {
carousel = $(".carousel").slick(carouselConfig);
}
function selectFirstCarouselItem() {
$('.slick-track').children().contents()[0].nextSibling.click();
}
function updateModalLayer(componentId) {
if (currentComponentId === componentId && isModalLayerVisible()) {
return;
}
// Prevent reload page
currentComponentId = componentId;
// Where to put data
var tabPanel = $("#sensors-list-tabs");
tabPanel.hide();
// Sensor observations panle
var dataPanel = $("#sensor-list-tab-content");
dataPanel.hide();
// Alarms list panel
var alarmsPanel = $("#alarms-list-tab-content #historic-data-wrapper");
// Orders list panel
var ordersPanel = $("#orders-list-tab-content #historic-data-wrapper");
// Show no data
$(".no-sensors-message").show();
$(".no-alarms-message").show();
$(".no-orders-message").show();
getComponentDetails(componentId, function (data1) {
if (data1 === null || data1 === undefined) {
return;
}
// Print component details on view
updateComponentDetails(data1);
// Look for component last observation details
var from = null;
var to = null;
getComponentLastObservations(componentId, from, to, function (data2) {
// Uptdate component last update details
updateComponentLastDataDetails(data2);
// Update sensor's details
if (data2.sensors.length === 0) {
return;
} else {
$('.no-sensors-message').hide();
}
// Update sensors tabs
destroySlick();
updateSensorsTabs(data2);
$('a[data-toggle="tab"]').on('shown', function (e) {
e.target // activated tab
e.relatedTarget // previous tab
const sensorId = $(this).attr("sensor-id");
const sensor = data2.sensors.find(sensor => sensor.sensor === sensorId);
updateActiveStatus(e.target);
showLastObservations(componentId, sensorId, dataPanel);
showLastAlarms(componentId, sensorId, alarmsPanel);
showLastOrders(componentId, sensorId, ordersPanel);
showDescription(sensor);
// Select sensors tab first
$('#component-sections a[href="#sensors-section"]').tab('show');
});
// Show sensors observations panel
showSensorsObservationsPanel();
initCarousel();
selectFirstCarouselItem(); // Needs to be done this because the chart isn't loaded correctly
});
// Show modal layer if it is down
showModalLayer();
// Move map!!!
const location = buildLatLng(data1.location[1],data1.location[0]);
centerMap(location);
});
}
function setComponentDetailUrl(url) {
window.componentDetailUrl = url;
}
function gotoComponentDetail() {
if (window.componentDetailUrl) {
window.location.href = window.componentDetailUrl;
}
return false;
}
/////////////////////////////////////////////////////////////////////////
// SET DATA ON VIEW
/////////////////////////////////////////////////////////////////////////
function showError(error) {
$(mapOptions.modalTargetId).html('<p style="color: red;"><strong>' + error + '</strong></p>');
}
function getComponentDetails(componentId, callback) {
var url = mapOptions.componentDetailsUrl + componentId + '/';
jsonGET(url, [], function (data) {
callback(data); // ComponentDTO
});
}
function updateComponentDetails(data) {
// data = ComponentDTO
$(mapOptions.modalTargetId + " .component-id").html(data.id);
$(mapOptions.modalTargetId + " .component-name").html(data.name);
$(mapOptions.modalTargetId + " .component-description").html(data.description);
$(mapOptions.modalTargetId + " .component-provider-id").html(data.providerId);
$(mapOptions.modalTargetId + " .component-provider-name").html(data.providerName);
$(mapOptions.modalTargetId + " .component-type").html(data.type);
$(mapOptions.modalTargetId + " .component-location").html('lat: ' + data.location[1] + ', lon: ' + data.location[0]);
if (data.photoUrl && data.photoUrl !== undefined && data.photoUrl !== '') {
$(mapOptions.modalTargetId + " .component-image").html(
'<a href="' + data.photoUrl + '" data-lightbox="component-img">' +
' <img class="component-img" src="' + data.photoUrl + '" />' +
'</a>'
);
} else {
$(mapOptions.modalTargetId + " .component-image").html('');
}
// Geolocate component address
//setComponentAddress(data.location[1], data.location[0], mapOptions.modalTargetId + " .component-address");
}
function updateComponentLastDataDetails(data) {
$(mapOptions.modalTargetId + " .component-last-update").html(data.lastUpdateTimeMessage);
}
function getComponentLastObservations(componentId, from, to, callback) {
var url = mapOptions.componentDetailsUrl + componentId + '/lastOb/';
var filters = {};
if (to) {
filters.to = to;
}
if (from) {
filters.from = from;
}
jsonGET(url, filters, function (data) {
callback(data); // InfoBoxDTO
});
}
function getComponentLastAlarms(componentId, from, to, callback) {
var url = mapOptions.componentDetailsUrl + componentId + '/lastOb/';
var filters = {};
if (to) {
filters.to = to;
}
if (from) {
filters.from = from;
}
jsonGET(url, filters, function (data) {
callback(data); // InfoBoxDTO
});
}
function getComponentLastOrders(componentId, from, to, callback) {
var url = mapOptions.componentDetailsUrl + componentId + '/lastOb/';
var filters = {};
if (to) {
filters.to = to;
}
if (from) {
filters.from = from;
}
jsonGET(url, filters, function (data) {
callback(data); // InfoBoxDTO
});
}
function setComponentAddress(latitude, longitude, target) {
var geo = new google.maps.Geocoder();
var componentDescription = '${component.description}';
geo.geocode({
'latLng': new google.maps.LatLng(latitude, longitude)
},
function (results, status) {
if (status == google.maps.GeocoderStatus.OK && results[0]) {
$(target).html(results[0].formatted_address);
}
}
);
}
function updateSensorsTabs(data) {
$("#sensors-list-tabs").hide();
$("#sensors-list-tabs").find(".sensorItem").remove();
$("#sensors-list-tabs").empty();
// Get component sensors last observations
for (var s in data.sensorLastObservations) {
var sensor = data.sensorLastObservations[s];
var sensorId = sensor.sensor;
var cssClass = 'active';
if (s > 0) {
cssClass = '';
}
var tabStyle = 'display: none;';
if (sensor.dataType === 'NUMBER' || sensor.dataType === 'BOOLEAN') {
tabStyle = '';
}
var value = '-';
if (sensor.value !== null && sensor.value !== undefined && sensor.value !== '') {
if (sensor.dataType === 'BOOLEAN') {
value = eval(sensor.value) ? messages.boolValues.trueValue.toUpperCase() : messages.boolValues.falseValue.toUpperCase();
} else {
value = sensor.value;
}
}
var tabTitle = '<div class="sensor-tab">';
tabTitle += ' <div class="sensor-last-value">' + value + '</div>';
tabTitle += ' <div class="sensor-unit" style="' + tabStyle + '">' + sensor.unit + '</div>';
tabTitle += ' <div class="sensor-id" style="display: none;">' + sensor.id + '</div>';
tabTitle += ' <div class="sensor-type">' + sensor.sensorType + '</div>';
tabTitle += '</div>';
var item =
'<div class="' + cssClass + ' sensorItem">' +
' <a id="sensor-' + sensorId + '-tab" href="#sensor-' + sensorId + '-content" data-toggle="tab" sensor-id="' + sensorId + '">' + tabTitle + '</a>' +
'</div>';
$("#sensors-list-tabs").append(item);
sensorsLastObsMap[sensorId] = sensor;
}
}
function showSensorsObservationsPanel() {
// Show tabs
$("#sensors-list-tabs").show();
// Show content
$("#sensor-list-tab-content").show();
}
function registerSectionPillChangeEvents() {
$('a[data-toggle="pill"]').on('shown', function (e) {
e.target // activated tab
e.relatedTarget // previous tab
var href = $(this).attr('href');
if (href === '#alarms-section') {
// Showing alarms
} else if (href === '#orders-section') {
// Showing orders
} else if (href === '#sensors-section') {
// Showing sensors
}
});
}
function showDescription(sensor) {
$(".sensor-description").text(sensor.sensorDescription);
}
function updateActiveStatus(element) {
$('.slick-track').children().each(removeActiveClass);
$(element.parentNode).addClass('active');
function removeActiveClass() {
$(this).removeClass('active');
}
}
function showLastObservations(componentId, sensorId, panel) {
var sensor = sensorsLastObsMap[sensorId];
if (!sensor || sensor === null || sensor === undefined) {
return;
}
var sensorLastObs = sensorsLastObsMap[sensorId];
var dataType = sensor.dataType;
// Clean data wrapper content
var dataPanel = $("#data-wrapper");
dataPanel.empty();
// Clean historic data wrapper content
var historicDataPanel = $("#historic-data-wrapper");
historicDataPanel.empty();
// Stop all media players previously
stopAllMediaPlayers();
// Show sensor name
$(".sensor-name").html(sensor.sensor);
// Select data template
if (dataType === 'BOOLEAN') {
// Show historic data chart panel
chartNav = [];
showBooleanDataChart(historicDataPanel, sensor, componentId, sensorId);
} else if (dataType === 'NUMBER') {
// Show historic data chart panel
chartNav = [];
showNumericDataChart(historicDataPanel, componentId, sensor);
} else if (dataType === 'TEXT' || dataType === 'LINK') {
// Show historic data list panel
showDataHistoryList(historicDataPanel, sensor, componentId, sensorId, dataType);
} else {
// Show historic data in accordion mode
showDataHistoryListAccordion(historicDataPanel, sensor, componentId, sensorId, dataType);
}
}
function showLastAlarms(componentId, sensorId, panel) {
$(panel).empty();
getLastSensorAlarms(componentId, sensorId, null, function (data) {
// data = List<AlarmMessage>
// { message, timestamp, sender, time }
if (data === null || data.length === 0) {
$("#alarms-list-tab-content").hide();
$("#alarms-section .no-alarms-message").show();
return;
}
$("#alarms-list-tab-content").show();
$("#alarms-section .no-alarms-message").hide();
for (var i = 0; i < data.length; i++) {
var alarm = data[i];
$(panel).append(addAlarmLineToHistoryPanel(alarm.message, alarm.timestamp));
}
});
}
function addAlarmLineToHistoryPanel(value, timestamp) {
var line =
'<div class="activity_text_element">' +
' <span class="label label-info">' + timestamp + '</span> ' +
' <span class="text">' + value + '</span>' +
'</div>';
return line;
}
function showLastOrders(componentId, sensorId, panel) {
$(panel).empty();
getLastSensorOrders(componentId, sensorId, null, function (data) {
// data = List<OrderMessage>
// { order, timestamp, sender, time }
if (data === null || data.length === 0) {
$("#orders-list-tab-content").hide();
$("#orders-section .no-orders-message").show();
return;
}
$("#orders-list-tab-content").show();
$("#orders-section .no-orders-message").hide();
for (var i = 0; i < data.length; i++) {
var order = data[i];
$(panel).append(addOrderLineToHistoryPanel(order.order, order.timestamp));
}
});
}
function addOrderLineToHistoryPanel(value, timestamp) {
var line =
'<div class="activity_text_element">' +
' <span class="label label-info">' + timestamp + '</span> ' +
' <span class="text">' + value + '</span>' +
'</div>';
return line;
}
function showBooleanDataChart(dataPanel, sensor, componentId, sensorId, filters) {
getLastSensorObservations(componentId, sensorId, filters, function (data) {
var chartAnchor = $('<div id="bool-chart" class="ct-chart ct-perfect-fourth ct-chart-centered-labels"></div>');
dataPanel.html(chartAnchor);
printBooleanChart(data, '#bool-chart', {height: 220, bottomPadding: 60});
var fromTimestamp = (data.fromTimestamp === null) ? '' : data.fromTimestamp;
var toTimestamp = (data.toTimestamp === null) ? '' : data.toTimestamp;
var iniDateMessage = (messages.chart.iniDate === null) ? 'Initial date:' : messages.chart.iniDate;
var endDateMessage = (messages.chart.endDate === null) ? 'End date:' : messages.chart.endDate;
var chartControls =
'<hr/>' +
'<div class="chart-controls row-fluid">' +
' <div class="chart-controls span3">' +
' <div class="btn-group">' +
' <button id="chart-control-prev-btn" class="btn"><i class="icon-chevron-left"></i></button>' +
' <button id="chart-control-refresh-btn" class="btn"><i class="icon-refresh"></i></button>' +
' <button id="chart-control-next-btn" class="btn"><i class="icon-chevron-right"></i></button>' +
' </div>' +
' </div>' +
' <div class="chart-start-date span3"><span class="chart-controls-label">' + iniDateMessage + ' </span><span class="chart-controls-value">' + fromTimestamp + '</span></div>' +
' <div class="chart-end-date span6"><span class="chart-controls-label">' + endDateMessage + ' </span><span class="chart-controls-value">' + toTimestamp + '</span></div>' +
'</div>';
dataPanel.append($(chartControls));
$("#chart-control-prev-btn").unbind('click');
$("#chart-control-prev-btn").on('click', function (e) {
filters = {
to: data.fromTime
};
var navActual = {
fromTimestamp: data.fromTimestamp,
toTimestamp: data.toTimestamp,
fromTime: data.fromTime,
toTime: data.toTime
};
chartNav.push(navActual);
showBooleanDataChart(dataPanel, sensor, componentId, sensorId, filters);
});
$("#chart-control-refresh-btn").unbind('click');
$("#chart-control-refresh-btn").on('click', function (e) {
chartNav = [];
filters = {};
showBooleanDataChart(dataPanel, sensor, componentId, sensorId, filters);
});
$("#chart-control-next-btn").unbind('click');
$("#chart-control-next-btn").on('click', function (e) {
var prevNav = chartNav.pop();
if (!prevNav) {
chartNav = [];
filters = {};
} else {
filters = {
to: prevNav.toTime + 1000
};
}
showBooleanDataChart(dataPanel, sensor, componentId, sensorId, filters);
});
});
}
function showNumericDataChart(dataPanel, componentId, sensor, filters) {
getLastSensorObservations(componentId, sensor.sensor, filters, function (data) {
var chartAnchor = $('<div id="num-chart" class="ct-chart ct-perfect-fourth ct-chart-centered-labels"></div>');
dataPanel.html(chartAnchor);
printNumericalChart(data, sensor.sensorType, sensor.unit, '#num-chart', {height: 220, bottomPadding: 60});
var fromTimestamp = (data.fromTimestamp === null) ? '' : data.fromTimestamp;
var toTimestamp = (data.toTimestamp === null) ? '' : data.toTimestamp;
var iniDateMessage = (messages.chart.iniDate === null) ? 'Initial date:' : messages.chart.iniDate;
var endDateMessage = (messages.chart.endDate === null) ? 'End date:' : messages.chart.endDate;
var chartControls =
'<hr/>' +
'<div class="chart-controls row-fluid">' +
' <div class="chart-controls span3">' +
' <div class="btn-group">' +
' <button id="chart-control-prev-btn" class="btn"><i class="icon-chevron-left"></i></button>' +
' <button id="chart-control-refresh-btn" class="btn"><i class="icon-refresh"></i></button>' +
' <button id="chart-control-next-btn" class="btn"><i class="icon-chevron-right"></i></button>' +
' </div>' +
' </div>' +
' <div class="chart-start-date span3"><span class="chart-controls-label">' + iniDateMessage + ' </span><span class="chart-controls-value">' + fromTimestamp + '</span></div>' +
' <div class="chart-end-date span6"><span class="chart-controls-label">' + endDateMessage + ' </span><span class="chart-controls-value">' + toTimestamp + '</span></div>' +
'</div>';
dataPanel.append($(chartControls));
$("#chart-control-prev-btn").unbind('click');
$("#chart-control-prev-btn").on('click', function (e) {
filters = {
to: data.fromTime
};
var navActual = {
fromTimestamp: data.fromTimestamp,
toTimestamp: data.toTimestamp,
fromTime: data.fromTime,
toTime: data.toTime
};
chartNav.push(navActual);
showNumericDataChart(dataPanel, componentId, sensor, filters);
});
$("#chart-control-refresh-btn").unbind('click');
$("#chart-control-refresh-btn").on('click', function (e) {
chartNav = [];
filters = {};
showNumericDataChart(dataPanel, componentId, sensor, filters);
});
$("#chart-control-next-btn").unbind('click');
$("#chart-control-next-btn").on('click', function (e) {
var prevNav = chartNav.pop();
if (!prevNav) {
chartNav = [];
filters = {};
} else {
filters = {
to: prevNav.toTime + 1000
};
}
showNumericDataChart(dataPanel, componentId, sensor, filters);
});
});
}
function getLastSensorObservations(componentId, sensorId, filters, callback) {
var url = mapOptions.sensorLastObsUrl + componentId + '.' + sensorId + '/';
jsonGET(url, filters, function (data) {
callback(data);
});
}
function getLastSensorAlarms(componentId, sensorId, filters, callback) {
var url = mapOptions.sensorLastAlarmsUrl + componentId + '.' + sensorId + '/';
jsonGET(url, filters, function (data) {
callback(data);
});
}
function getLastSensorOrders(componentId, sensorId, filters, callback) {
var url = mapOptions.sensorLastOrdersUrl + componentId + '.' + sensorId + '/';
jsonGET(url, filters, function (data) {
callback(data);
});
}
function calculateFilters(sensor, filters) {
if (filters === undefined || filters === null) {
filters = {
limit: defaultChartObsLimit
};
}
var chartNumberObs = mapOptions.chartObservationsNumber;
if (sensor !== null || senosr !== undefined) {
if (sensor.chartNumberObs !== null && sensor.chartNumberObs !== undefined && sensor.chartNumberObs !== '') {
chartNumberObs = sensor.chartNumberObs;
}
}
filters.limit = chartNumberObs;
if (filters.limit < defaultChartObsLimit || filters.limit > maxChartObsLimit) {
filters.limit = defaultChartObsLimit;
}
return filters;
}
function stopAllMediaPlayers() {
// Stop all possible running media players
stopAudioPlayer();
stopVideoPlayerUM();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//CHARTS
///////////////////////////////////////////////////////////////////////////////////////////////////
//Chartist.js
//https://codepen.io/niketmalik/pen/BZjgpQ
function cleanChart(chartPanel) {
$(chartPanel).empty();
}
function showDataHistoryListAccordion(dataPanel, sensor, componentId, sensorId, dataType) {
var sensor = sensorsLastObsMap[sensorId];
tempSensorLastObsMap = {
audio: [],
video: [],
image: [],
file: [],
json: []
};
var accordionId = 'history-accordion';
var accordionWrapperId = 'history-accordion-wrapper';
var accordionWrapper = $('<div>').addClass(accordionWrapperId).attr('id', accordionWrapperId);
var accordion = $('<div>').addClass('accordion').attr('id', accordionId);
var audioWrapperIdPrefix = 'audio-data-wrapper-';
var videoWrapperIdPrefix = 'video-data-wrapper-';
var imageWrapperIdPrefix = 'image-data-wrapper-';
var fileWrapperIdPrefix = 'file-data-wrapper-';
var jsonWrapperIdPrefix = 'json-data-wrapper-';
getLastSensorObservations(componentId, sensorId, calculateFilters(sensor, null), function (data) {
for (var e in data.events) {
var event = data.events[e];
var value = event.value;
var formattedValue = event.formattedValue;
var timestamp = event.timestamp;
var header = '<span class="label label-info">' + timestamp + '</span> <span class="">' + value + '</span>';
if (dataType === 'AUDIO_LINK') {
addAccordionGroup(accordion, accordionId, dataType, header, e, audioWrapperIdPrefix);
tempSensorLastObsMap.audio.push({
value: value,
formattedValue: formattedValue,
timestamp: timestamp
});
} else if (dataType === 'VIDEO_LINK') {
addAccordionGroup(accordion, accordionId, dataType, header, e, videoWrapperIdPrefix);
tempSensorLastObsMap.video.push({
value: value,
formattedValue: formattedValue,
timestamp: timestamp
});
} else if (dataType === 'IMAGE_LINK') {
addAccordionGroup(accordion, accordionId, dataType, header, e, imageWrapperIdPrefix);
tempSensorLastObsMap.image.push({
value: value,
formattedValue: formattedValue,
timestamp: timestamp
});
} else if (dataType === 'FILE_LINK') {
addAccordionGroup(accordion, accordionId, dataType, header, e, fileWrapperIdPrefix);
tempSensorLastObsMap.file.push({
value: value,
formattedValue: formattedValue,
timestamp: timestamp
});
} else if (dataType === 'JSON') {
addAccordionGroup(accordion, accordionId, dataType, header, e, jsonWrapperIdPrefix);
tempSensorLastObsMap.json.push({
value: value,
formattedValue: formattedValue,
timestamp: timestamp
});
}
}
});
$(accordionWrapper).html(accordion);
$(dataPanel).append(accordionWrapper);
$(dataPanel).on('hide', '.collapse', function () {
stopAllMediaPlayers();
});
$(dataPanel).on('show', '.collapse', function () {
var idx = $(this).attr('idx');
var dataType = $(this).attr('sensor-data-type');
if (dataType === 'AUDIO_LINK') {
showAndLoadAudioPlayerUM($('#' + audioWrapperIdPrefix + idx), tempSensorLastObsMap.audio[idx]);
} else if (dataType === 'VIDEO_LINK') {
showAndLoadVideoPlayerUM($('#' + videoWrapperIdPrefix + idx), tempSensorLastObsMap.video[idx]);
} else if (dataType === 'IMAGE_LINK') {
showImageUM($('#' + imageWrapperIdPrefix + idx), tempSensorLastObsMap.image[idx]);
} else if (dataType === 'FILE_LINK') {
showFileUM($('#' + fileWrapperIdPrefix + idx), tempSensorLastObsMap.file[idx]);
} else if (dataType === 'JSON') {
showJsonUM($('#' + jsonWrapperIdPrefix + idx), tempSensorLastObsMap.json[idx]);
}
});
$(dataPanel).on('hidden', '.collapse', function () {
var idx = $(this).attr('idx');
var dataType = $(this).attr('sensor-data-type');
if (dataType === 'AUDIO_LINK') {
$('#' + audioWrapperIdPrefix + idx).empty();
} else if (dataType === 'VIDEO_LINK') {
$('#' + videoWrapperIdPrefix + idx).empty();
} else if (dataType === 'IMAGE_LINK') {
$('#' + imageWrapperIdPrefix + idx).empty();
} else if (dataType === 'FILE_LINK') {
$('#' + fileWrapperIdPrefix + idx).empty();
} else if (dataType === 'JSON') {
$('#' + jsonWrapperIdPrefix + idx).empty();
}
});
setTimeout(function () {
$('#history-accordion a:first').click();
}, 500);
}
function addAccordionGroup(accordion, accordionId, dataType, header, idx, dataWrapperPrefix) {
var accordionGroup = $('<div>').addClass('accordion-group');
var accordionHeading = $('<div>').addClass('accordion-heading');
var accordionToggle = $('<a>').addClass('accordion-toggle')
.attr('data-toggle', 'collapse')
.attr('data-parent', '#' + accordionId)
.attr('href', '#collapse' + idx)
.html(header);
var accordionBody = $('<div>').addClass('accordion-body collapse audio-collapse')
.attr('id', 'collapse' + idx)
.attr('idx', idx)
.attr('sensor-data-type', dataType);
var accordionDataWrapper = $('<div>').attr('id', dataWrapperPrefix + idx);
var accordionInner = $('<div>').addClass('accordion-inner').html(accordionDataWrapper);
$(accordionBody).append(accordionInner);
$(accordionHeading).append(accordionToggle);
$(accordionGroup).append(accordionHeading);
$(accordionGroup).append(accordionBody);
$(accordion).append(accordionGroup);
}
function showDataHistoryList(dataPanel, sensor, componentId, sensorId, dataType) {
getLastSensorObservations(componentId, sensorId, calculateFilters(sensor, null), function (data) {
for (var e in data.events) {
var event = data.events[e];
var value = event.value;
var timestamp = event.timestamp;
if (dataType === 'LINK') {
$(dataPanel).append(generateLinkDataHistoryLine(value, timestamp));
} else if (dataType === 'TEXT') {
$(dataPanel).append(generateTextDataHistoryLine(value, dataType, timestamp));
}
}
});
}
function generateLinkDataHistoryLine(value, timestamp) {
var line =
'<div class="activity_text_element">' +
' <span class="label label-info">' + timestamp + '</span> ' +
' <span class="link"><a href="' + value + '" target="_blank">' + value + '</a></span>' +
'</div>';
return line;
}
function generateTextDataHistoryLine(value, dataType, timestamp) {
var line =
'<div class="activity_text_element">' +
' <span class="label label-info">' + timestamp + '</span> ' +
' <span class="label label-success">' + dataType + '</span> ' +
' <span class="text">' + value + '</span>' +
'</div>';
return line;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// MEDIA PLAYERS
///////////////////////////////////////////////////////////////////////////////////////////////////
//Audio player object
var wavesurfer;
function showAndLoadAudioPlayerUM(panel, observation) {
var link = observation.value;
var s3Link = observation.formattedValue;
var timestamp = observation.timestamp;
var filename = getFilenameFromUrl(link);
var timestampMessage = (messages.players.timestamp === null) ? 'Timestamp:' : messages.players.timestamp;
var filenameMessage = (messages.players.filename === null) ? 'File name:' : messages.players.filename;
var ellapsedMessage = (messages.players.ellapsed === null) ? 'Ellapsed time:' : messages.players.ellapsed;
var html =
'<div id="waveform-error-wrapper" style="display: none"><p class="error-message"></p></div>' +
'<div id="audio-player-wrapper">' +
' <div id="audio-details">' +
filenameMessage + ' <span id="audio-filename">' + filename + '</span> ' +
timestampMessage + ' <span id="audio-timestamp">' + timestamp + '</span>' +
' </div>' +
' <div id="waveform"></div>' +
' <div id="controller-wrapper">' +
' <div id="controller-buttons" class="btn-group">' +
' <div id="play-btn" class="btn btn-small"><i class="icon-play"></i></div>' +
' <div id="stop-btn" class="btn btn-small"><i class="icon-stop"></i></div>' +
' </div>' +
' <div id="controller-info">' +
' <p><strong>' + ellapsedMessage + ' </strong><span id="ellapsed-time"></span></p>' +
' </div>' +
' </div>' +
'</div>';
// Add audio player to the panel
$(panel).html(html);
// Create the waveform
wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: '#1abc9c',
progressColor: '#12715f'
});
// Player controller events
$("#play-btn").click(function () {
wavesurfer.playPause();
updateAudioButtons();
});
$("#stop-btn").click(function () {
wavesurfer.stop();
updateAudioButtons();
});
// Player events
wavesurfer.on('ready', function () {
$("#ellapsed-time").html('0.000s / ' + wavesurfer.getDuration().toFixed(3) + 's');
});
wavesurfer.on('audioprocess', function () {
$("#ellapsed-time").html(wavesurfer.getCurrentTime().toFixed(3) + 's / ' + wavesurfer.getDuration().toFixed(3) + 's');
});
wavesurfer.on('interaction', function () {
$("#ellapsed-time").html(wavesurfer.getCurrentTime().toFixed(3) + 's / ' + wavesurfer.getDuration().toFixed(3) + 's');
});
wavesurfer.on('error', function (message) {
$("#waveform-error-wrapper .error-message").html('<strong>ERROR: </strong> ' + message);
$("#waveform-error-wrapper").show('slow');
});
// Load audio file
loadAudioPlayerUM(panel, observation);
}
function loadAudioPlayerUM(panel, observation) {
if (!wavesurfer || wavesurfer === null || wavesurfer === undefined) {
return;
}
// Init player & load audio
wavesurfer.stop();
wavesurfer.empty();
wavesurfer.load(observation.formattedValue);
$("#audio-filename").html(getFilenameFromUrl(observation.value));
$("#audio-timestamp").html(observation.timestamp);
}
function showAndLoadVideoPlayerUM(panel, observation) {
// media_players.js overload
var link = observation.value;
var s3Link = observation.formattedValue;
var timestamp = observation.timestamp;
var filename = getFilenameFromUrl(link);
var timestampMessage = (messages.players.timestamp === null) ? 'Timestamp:' : messages.players.timestamp;
var filenameMessage = (messages.players.filename === null) ? 'File name:' : messages.players.filename;
var html =
'<div id="video-player-wrapper">' +
' <div id="video-details">' +
filenameMessage + ' <span id="video-filename">' + filename + '</span> ' +
timestampMessage + ' <span id="video-timestamp">' + timestamp + '</span>' +
' </div>' +
' <video id="video-player" playsinline controls>' +
' <source id="video-src">' +
' </video>' +
'</div>';
// Add all
$(panel).html(html);
// Load video
loadVideoPlayerUM(link, s3Link, timestamp);
}
function loadVideoPlayerUM(link, s3Link, timestamp) {
var videoPlayer = document.getElementById("video-player");
if (videoPlayer) {
// Set the video src
$("#video-src").attr('src', s3Link);
// Load the video
$('#video-player').load();
$("#video-filename").html(getFilenameFromUrl(link));
$("#video-timestamp").html(timestamp);
}
}
function stopVideoPlayerUM() {
var videoPlayer = document.getElementById("video-player");
if (videoPlayer) {
$('video').each(function () {
$(this)[0].pause();
});
}
}
function showImageUM(panel, observation) {
// Overloaded from media_players.js
var link = observation.value;
var s3Link = observation.formattedValue;
var timestamp = observation.timestamp;
var filename = getFilenameFromUrl(link);
var timestampMessage = (messages.players.timestamp === null) ? 'Timestamp:' : messages.players.timestamp;
var filenameMessage = (messages.players.filename === null) ? 'File name:' : messages.players.filename;
// Create html node
var html =
'<div id="image-player-wrapper">' +
' <div id="image-details">' +
filenameMessage + ' <span id="image-filename">' + filename + '</span> ' +
timestampMessage + ' <span id="image-timestamp">' + timestamp + '</span>' +
' </div>' +
' <div id="image-wrapper"></div>' +
'</div>';
// Add html
$(panel).html(html);
// Load image
loadImage(link, s3Link, timestamp);
}
function loadImage(link, s3Link, timestamp) {
$("#image-wrapper").empty();
var img = $('<img id="link-image" />').attr('src', s3Link)
.on('load', function () {
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
img.attr('src', getErrorImage());
$("#image-wrapper").html(img);
} else {
var imageLink = $('<a id="image-link" href="' + s3Link + '" data-lightbox="link-image"></a>');
$(imageLink).append(img);
$("#image-wrapper").html(imageLink);
}
});
}
function showFileUM(panel, observation) {
// Overloaded from media_players.js
var link = observation.value;
var s3Link = observation.formattedValue;
var timestamp = observation.timestamp;
var filename = getFilenameFromUrl(link);
var timestampMessage = (messages.players.timestamp === null) ? 'Timestamp:' : messages.players.timestamp;
var filenameMessage = (messages.players.filename === null) ? 'File name:' : messages.players.filename;
var downloadMessage = (messages.players.download === null) ? 'Download:' : messages.players.download;
// Create html node
var html =
'<div id="file-downloader-wrapper">' +
' <div id="file-details">' +
filenameMessage + ' <span id="file-filename">' + filename + '</span> ' +
timestampMessage + ' <span id="file-timestamp">' + timestamp + '</span>' +
' </div>' +
' <div id="file-wrapper">' +
' <a id="file-link" class="btn btn-success" href="' + s3Link + '" target="_blank" download="' + filename + '">' + downloadMessage + ' ' + filename + '</a>' +
' </div>' +
'</div>';
// Add html
$(panel).html(html);
}
function loadFile(link, s3Link, timestamp) {
if ($('#file-downloader-wrapper').length) {
var filename = getFilenameFromUrl(link);
$("#file-link").attr('href', s3Link);
$("#file-link").attr('download', filename);
$("#file-link").html('Dowload ' + filename);
$("#file-filename").html(filename);
$("#file-timestamp").html(timestamp);
}
}
function showJsonUM(panel, observation) {
var json = observation.value;
var timestamp = observation.timestamp;
var timestampMessage = (messages.json.timestamp === null) ? 'Timestamp:' : messages.json.timestamp;
var expandAllMessage = (messages.json.expandAll === null) ? 'Expand all:' : messages.json.expandAll;
var collapseAllMessage = (messages.json.collapseAll === null) ? 'Collapse all:' : messages.json.collapseAll;
var expandLevelsMessage = (messages.json.expandLevels === null) ? 'Expand levels:' : messages.json.expandLevels;
// See: https://www.jqueryscript.net/other/Render-JSON-Schema-In-HTML-jQuery-JSON-Presenter.html
var html =
'<div id="json-presenter-wrapper">' +
' <div id="json-details">' +
timestampMessage + ' <span id="json-timestamp">' + timestamp + '</span>' +
' </div>' +
' <div id="json-container"></div>' +
' <div id="json-controller">' +
' <form class="form-inline">' +
' <button id="expand-all" class="btn btn-small btn-primary">' + expandAllMessage + '</button>' +
' <button id="collapse-all" class="btn btn-small btn-success">' + collapseAllMessage + '</button>' +
' <button id="expand-levels" class="btn btn-small btn-danger">' + expandLevelsMessage + '</button>' +
' <input id="levels" type="text" class="input-small" value="1" size="5" maxlength="5">' +
' </form>' +
' </div>' +
'</div>';
// Add html json-presenter panel & tools
panel.html(html);
var jsonContainer = $('#json-container');
doJsonPresenterUM(json, timestamp);
$('#expand-all').on('click', function () {
jsonContainer.jsonPresenter('expandAll');
});
$('#collapse-all').on('click', function () {
jsonContainer.jsonPresenter('collapseAll');
});
$('#expand-levels').on('click', function () {
var levels = parseInt($('#levels').val());
jsonContainer.jsonPresenter('expand', levels);
});
}
function doJsonPresenterUM(json, timestamp) {
var jsonContainer = $('#json-container');
var error = false;
try {
var json = JSON.parse(json);
} catch (e) {
error = true;
alert(e);
}
$('.error').toggleClass('hidden', !error);
$('#output-container').toggleClass('hidden', error);
jsonContainer
.jsonPresenter('destroy')
.jsonPresenter({json: json})
.jsonPresenter('expand', 0);
$('#json-timestamp').html(timestamp);
}
function downloadFile(fileURL, s3FileURL) {
var filename = fileURL.substring(fileURL.lastIndexOf('/') + 1);
var link = document.createElement('a');
link.setAttribute('href', s3FileURL);
link.setAttribute('download', fileName);
link.setAttribute('target', '_blank');
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function getFilenameFromUrl(link) {
return link.substring(link.lastIndexOf('/') + 1);
}
function toggleFullScreen(elem) {
if ((document.fullScreenElement !== undefined && document.fullScreenElement === null) ||
(document.msFullscreenElement !== undefined && document.msFullscreenElement === null) ||
(document.mozFullScreen !== undefined && !document.mozFullScreen) ||
(document.webkitIsFullScreen !== undefined && !document.webkitIsFullScreen)) {
if (elem.requestFullScreen) {
elem.requestFullScreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullScreen) {
elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
} else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
}
fullscreenActive = true;
} else {
if (document.cancelFullScreen) {
document.cancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
fullscreenActive = false;
}
}
function exitFullScreenHandler() {
if (!document.fullscreenElement && !document.webkitIsFullScreen && !document.mozFullScreen && !document.msFullscreenElement) {
fullscreenActive = false;
}
}
document.addEventListener('fullscreenchange', exitFullScreenHandler);
document.addEventListener('webkitfullscreenchange', exitFullScreenHandler);
document.addEventListener('mozfullscreenchange', exitFullScreenHandler);
document.addEventListener('MSFullscreenChange', exitFullScreenHandler);