(function () { 'use strict'; angular .module('hyperion') .controller('system.FloorsController.view', ['$scope', '$state', '$http', '$location', '$timeout', '$sessionStorage', 'timerange', 'modalDialog', 'authService', 'CONFIG', '$stateParams', 'sysClock', 'wiz', function($scope, $state, $http, $location, $timeout, $sessionStorage, timerange, modalDialog, authService, CONFIG, $stateParams, sysClock, wiz){ // set #content div margin if($sessionStorage.currentUser !== undefined) { if($sessionStorage.currentUser.smallMenu) { $("#content").css('margin-left', 50); } } $scope.ismanager = $sessionStorage.currentUser.ismanager; $scope.isLoading = true; // show ajax loader // Location Sensor Count $scope.sensors_tempperature = null; $scope.sensors_humidity = null; $scope.sensors_power = null; /////////////////////////////////////////////////////////////////////////////////////// var time = timerange.calc($sessionStorage.currentUser.timerange); $scope.$on('trUpdate', function(event, payload) { // time range update event console.log('trUpdate event: ' + $sessionStorage.currentUser.timerange); time = timerange.calc($sessionStorage.currentUser.timerange); load_data().catch(error => { console.warn(error); }); }); /////////////////////////////////////////////////////////////////////////////////////// $scope.$on('clockUpdate', function(event, payload) { // time range update event console.log('clockUpdate event: ' + sysClock.getTimeZone()); Highcharts.setOptions({ colors: ['#192a56', '#00b894', '#ff4757'], time: { timezone: sysClock.getTimeZone() } }); if($scope.chart_consumption_drilldown) { // if data is shown in hourly graph chart_load_hourly_data($scope.chart_consumption_drilldown_timestamp); } else { // if data is shown in daily graph chart_load_daily_data(); } }); /////////////////////////////////////////////////////////////////////////////////////// $scope.floor = {isvisible: false}; $scope.rooms = []; function load_data() { return new Promise((resolve, reject) => { $scope.chart_consumption_loading = true; // show ajax loader let time_start = moment(time.start).format('YYYY-MM-DDTHH:mm:ss'); let time_end = moment(time.today).format('YYYY-MM-DDTHH:mm:ss'); console.log('time_start: ' + time_start); console.log('time_end: ' + time_end); authService.getJWTAuth().then(authHeader => { var request = {'query': 'query { ' + 'floors(id:"' + $stateParams.floor_id + '", time_start:"' + time_start + '", time_end:"' + time_end + '", timezone:"' + sysClock.getTimeZone() + '") { ' + 'id ' + 'name ' + 'isactive ' + 'sqm ' + 'power_consumption ' + 'co2_emission ' + 'status ' + 'company { ' + 'id ' + '} ' + 'location { ' + 'id ' + 'name ' + '} ' + 'rooms { ' + 'id ' + 'name ' + 'sqm ' + 'room_equipment_total ' + 'power_consumption ' + 'co2_emission ' + 'status ' + '} ' + '} ' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve if(response.data.data.floors.length) { $scope.floor = response.data.data.floors[0]; $scope.rooms = $scope.floor.rooms; $scope.floor.isvisible = true; if($scope.floor.rooms.length) { loadChart().then(() => { // create chart object resolve(null); }); } else { reject('no equipment found'); } } else { // object not found reject('room object not found'); } $scope.isLoading = false; // hide ajax loader $scope.floor.power_consumption = $scope.floor.power_consumption?$scope.floor.power_consumption:0; $scope.floor.co2_emission = $scope.floor.co2_emission?$scope.floor.co2_emission:0; },function(error) { // failure console.error(error); reject(error); } ); }); }); } $timeout(function() { load_data().then(() => { // nothing }).catch(error => { console.warn(error); }); }, 100); $scope.floorLight = function() { modalDialog.showDialog({ 'template':'modal.lightsetings.html', 'controller':'modalLightController', 'entity': "FLOOR" }).then( // settings applied function(settings){ var change = { state: settings.state, brightness: settings.brightness, scene: settings.id }; authService.getJWTAuth().then(authHeader => { change.brightness = change.brightness?wiz.dimm2wiz(change.brightness):null; var request = {'query': 'mutation { ' + 'floorlightchange ( ' + 'company_id: "' + $scope.floor.company.id + '", ' + 'floor_id: "' + $stateParams.floor_id + '", ' + (change.scene ? ('scene: ' + change.scene + ', ') : '') + (change.brightness ? ('brightness: ' + change.brightness + ', ') : '') + 'state: ' + change.state + ')' + '}' }; console.log(request); $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve //$state.reload(); console.log('response: ', response.data.data.floorlightchange); },function(error) { // failure console.error(error); } ); }); } ) } $scope.editFloor = function() { modalDialog.showDialog({ 'template':'modal.editfloor.html', 'controller':'modalEditFloorController', 'company_id': $scope.floor.company.id, 'location_id': $scope.floor.location.id, 'location_name': $scope.floor.location.name, 'name': $scope.floor.name }).then( // acknowledge function(floor){ if(floor!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'floorupdate ( ' + 'company_id: "' + $scope.floor.company.id + '", ' + 'floor_id: "' + $stateParams.floor_id + '", ' + 'name: "' + floor.name + '", ' + ') { id }' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(newfloor){ // resolve console.log(newfloor); $state.reload(); },function(error) { // failure console.error(error); } ); }); } } ) } $scope.editRoom = function(room) { modalDialog.showDialog({ 'template':'modal.editroom.html', 'controller':'modalEditRoomController', 'room_id': room.id, 'company_id': $scope.floor.company.id, 'location_id': $scope.floor.location.id, 'location_name': $scope.floor.location.name, 'floor_id': $scope.floor.id, 'floor_name': $scope.floor.name, 'name': room.name, 'sqm': room.sqm }).then( // acknowledge function(room){ if(room!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'roomupdate ( ' + 'company_id: "' + $scope.floor.company.id + '", ' + 'floor_id: "' + $stateParams.floor_id + '", ' + 'room_id: "' + room.room_id + '", ' + 'name: "' + room.name + '", ' + 'sqm: ' + room.sqm + ' ' + ') { id }' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(newroom){ // resolve console.log(newroom); $state.reload(); },function(error) { // failure console.error(error); } ); }); } } ) } $scope.removeRoom = function(room) { modalDialog.showDialog({ 'template':'modal.codeconfirmation.html', 'controller':'modalCodeConfirmationController', 'subtitle': "DELETING ROOM", 'message': "PLEASE VALIDATE WITH CONFIRMATION CODE" }).then( // acknowledge function(confirmationcode){ if(confirmationcode!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'roomdelete ( ' + 'passcode: "' + confirmationcode + '", ' + 'company_id: "' + $scope.floor.company.id + '", ' + 'room_id: "' + room.id + '"' + ')' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve $location.path('/system/floors/view/' + $scope.room.floor.id); },function(error) { // failure console.error(error); } ); }); } } ) } $scope.removeFloor = function() { modalDialog.showDialog({ 'template':'modal.codeconfirmation.html', 'controller':'modalCodeConfirmationController', 'subtitle': "DELETING FLOOR", 'message': "PLEASE VALIDATE WITH CONFIRMATION CODE" }).then( // acknowledge function(confirmationcode){ if(confirmationcode!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'floordelete ( ' + 'passcode: "' + confirmationcode + '", ' + 'company_id: "' + $scope.floor.company.id + '", ' + 'floor_id: "' + $stateParams.floor_id + '"' + ')' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve $location.path('/system/locations/view/' + $scope.floor.location.id); },function(error) { // failure console.error(error); } ); }); } } ) } $scope.editRomm = function(room_id) { $location.path('/system/rooms/edit/' + room_id); } $scope.removeRomm = function(room_id) { modalDialog.showDialog({ 'template':'modal.codeconfirmation.html', 'controller':'modalCodeConfirmationController', 'subtitle': "DELETING ROOM", 'message': "PLEASE VALIDATE WITH CONFIRMATION CODE" }).then( // acknowledge function(confirmationcode){ if(confirmationcode!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'equipmentdelete ( ' + 'passcode: "' + confirmationcode + '", ' + 'company_id: "' + $scope.floor.company.id + '", ' + 'room_id: "' + room_id + '"' + ')' + '}' }; console.log(request); $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve console.log(response); //$location.path('/system/rooms/' + $stateParams.room_id); $state.reload(); },function(error) { // failure console.error(error); } ); }); } } ) } $scope.back = function() { $location.path('/system/locations/view/' + $scope.floor.location.id); }; $scope.viewRoom = function(room_id) { $location.path('/system/rooms/' + room_id); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// // CHART: POWER CONSUMPTION DATA var chart_consumption = null; // chart object $scope.chart_consumption_loading = true; // turn on and off AJAX loader and show graph $scope.chart_consumption_drilldown = false; // false: graph shows data aggregated to 1d, true: aggregation to 1h $scope.chart_consumption_drilldown_timestamp = null; // if 1h aggregation is shown then this variable holds information about which day $scope.chart_drillup = () => { // exit from drilldown (back to 1d aggregation) chart_load_daily_data(); } const chart_clean = () => { // remove data servies (empty graph) while(chart_consumption.series.length) { chart_consumption.series[0].remove(); } } const chart_load_daily_data = () => { // prepare loading 1d aggregation data to graph $scope.chart_consumption_drilldown = false; // mark drolldown false $scope.chart_consumption_drilldown_timestamp = null; // remove drilldown timestamp chart_clean(); // remove data servies (empty graph) $scope.chart_consumption_title = 'Last ' + $sessionStorage.currentUser.timerange + ' Days Power Consumption'; // set graph title let tickInterval = 86400000; // 3600 * 24 * 1000 = 1 day (tickInterval = 1d in milliseconds) chart_consumption.xAxis.forEach((xaxis, i) => { // set graph X Axis (time:days) display range xaxis.options.tickInterval = tickInterval; xaxis.setExtremes(time.start, time.today, true); }) let time_start = moment.utc(time.start).format('YYYY-MM-DDTHH:mm:ss'); let time_end = moment.utc(time.today).format('YYYY-MM-DDTHH:mm:ss'); chart_add_power_daily(time_start, time_end); // execute data request and series prepare } const chart_load_hourly_data = (timestamp) => { // drilldown: 24h data $scope.chart_consumption_drilldown = true; // mark drolldown true $scope.chart_consumption_drilldown_timestamp = timestamp; // remember for which day we show drilldown chart_clean(); // remove data servies (empty graph) $scope.chart_consumption_title = moment.utc(timestamp).format('ll') + ' Power Consumption'; // set graph title let tickInterval = 3600000; // 3600 * 1000 = 1 hour chart_consumption.xAxis.forEach((xaxis, i) => { // set graph X Axis (time:hours) display range xaxis.options.tickInterval = tickInterval; xaxis.setExtremes(timestamp, (timestamp + (tickInterval * 23)), true); }); let time_start = moment.utc(timestamp).format('YYYY-MM-DDTHH:mm:ss'); let time_end = moment.utc(timestamp + (tickInterval * 24)).format('YYYY-MM-DDTHH:mm:ss'); chart_add_power_hourly(time_start, time_end); // execute data request and series prepare } const chart_add_power_daily = (time_start, time_end) => { let power_series = { name: "Energy Consumption", type: "column", marker: { symbol: 'circle' }, yAxis: 0, zIndex: 1, tooltip: { valueSuffix: 'kWh' }, color: '#51c4d3', data: [] }; authService.getJWTAuth().then(authHeader => { var request = {'query': 'query { ' + 'power_daily(object:"' + $stateParams.floor_id + '", time_start:"' + time_start + '", time_end:"' + time_end + '", timezone:"' + sysClock.getTimeZone() + '") { ' + 'step ' + 'epoch ' + 'p_avg ' + '} ' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( (response) => { // resolve response.data.data.power_daily.forEach(day => { power_series.data.push({ x: parseInt(day.epoch, 10), y: day.p_avg }); }); chart_consumption.addSeries(power_series); },(error) => { // failure console.error(error); } ); }); } const chart_add_power_hourly = (time_start, time_end) => { let power_series = { name: "Energy Consumption", type: "column", marker: { symbol: 'circle' }, yAxis: 0, zIndex: 1, tooltip: { xDateFormat: '%b %e, %Y %l %p %Z', valueSuffix: 'kWh' }, color: '#51c4d3', data: [], }; authService.getJWTAuth().then(authHeader => { var request = {'query': 'query { ' + 'power_hourly(object:"' + $stateParams.floor_id + '", time_start:"' + time_start + '", time_end:"' + time_end + '", timezone:"' + sysClock.getTimeZone() + '") { ' + 'step ' + 'epoch ' + 'p_avg ' + '} ' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( (response) => { // resolve response.data.data.power_hourly.forEach(hour => { power_series.data.push({ x: parseInt(hour.epoch, 10), y: hour.p_avg }); }); chart_consumption.addSeries(power_series); },(error) => { // failure console.error(error); } ); }); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// // CHART: POWER CONSUMPTION OBJECT Highcharts.setOptions({ colors: ['#192a56', '#00b894', '#ff4757'], time: { timezone: sysClock.getTimeZone() } }); Highcharts.dateFormats = { 'Z': () => { return moment.tz(sysClock.getTimeZone()).format('Z'); } } function loadChart() { return new Promise((resolve, reject) => { new Highcharts.Chart({ chart: { renderTo: 'dashboard_consumption', height: 200, borderWidth: 0 }, time: { useUTC: true }, title: { text: null }, subtitle: { text: null }, exporting: { enabled: false }, credits: { enabled: false }, accessibility: { announceNewData: { enabled: true } }, xAxis: { type: 'datetime', tickInterval: 86400000, // 24 * 3600 * 1000 = 1 day }, yAxis: [{ // Power Consumption labels: { format: '{value}kWh', style: { color: Highcharts.getOptions().colors[0] } }, title: { text: 'Power Consumption', style: { color: Highcharts.getOptions().colors[0] } } }], tooltip: { xDateFormat: '%b %e, %Y', shared: true }, legend: { enabled: false }, plotOptions: { column: { stacking: 'normal', dataLabels: { enabled: false } }, series: { cursor: 'pointer', pointPadding: 0.01, groupPadding: 0.01, borderWidth: 0.01, shadow: false, dataLabels: { enabled: false }, marker: { enabled: false }, point: { events: { click: function() { //console.log('drilldown: ' + this.series.name + ' ['+this.x+'] -> ' + $scope.chart_consumption_drilldown); if(!$scope.chart_consumption_drilldown) { $scope.chart_consumption_drilldown = true; chart_load_hourly_data(this.x); } } } } } }, drilldown: { activeAxisLabelStyle: { cursor: 'default', color: '#3E576F', fontWeight: 'normal', textDecoration: 'none' }, activeDataLabelStyle: { cursor: 'default', color: '#3E576F', fontWeight: 'normal', textDecoration: 'none' } } }, function(chart){ //console.log('* chart is ready!'); chart_consumption = chart; chart_load_daily_data(); // dafault $scope.chart_consumption_loading = false; resolve(); }); }); } }]) })();