(function () { 'use strict'; angular .module('hyperion') .controller('system.RoomsController.view', ['$scope', '$state', '$filter', '$http', '$location', '$timeout', '$sessionStorage', '$mdMenu', 'timerange', 'modalDialog', 'authService', 'CONFIG', '$stateParams', 'sysClock', 'wiz', 'debounce', function($scope, $state, $filter, $http, $location, $timeout, $sessionStorage, $mdMenu, timerange, modalDialog, authService, CONFIG, $stateParams, sysClock, wiz, debounce){ // set #content div margin if($sessionStorage.currentUser !== undefined) { if($sessionStorage.currentUser.smallMenu) { $("#content").css('margin-left', 50); } } $scope.scenes = [ {id:0, name:'OFF', icon:'power_settings_new', state: false, speed:null, brightness: null, temperature: null, color:null}, // Custom Color {id:33, name:'Custom Color', icon:'style', state: true, speed:null, brightness: 100, temperature: null, color:'ffffff'}, // White {id:11, name:'Warm white', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:12, name:'Daylight', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:13, name:'Cool white', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:34, name:'Custom white', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: 2700, color:null}, // Simple {id:6, name:'Cozy', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:17, name:'True colors', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:16, name:'Relax', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:15, name:'Focus', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:18, name:'TV Time', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, // Routine {id:9, name:'Wake Up', icon:'alarm', state: true, speed:null, brightness: null, temperature: null, color:null}, {id:10, name:'Bedtime', icon:'hotel', state: true, speed:null, brightness: 100, temperature: null, color:null}, // Functional {id:19, name:'Plant growth', icon:'light_mode', state: true, speed:null, brightness: 100, temperature: null, color:null}, {id:14, name:'Night Light', icon:'nights_stay', state: true, speed:null, brightness: null, temperature: null, color:null}, // Dynamic {id:1, name:'Ocean', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:2, name:'Romance', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:3, name:'Sunset', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:4, name:'Party', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:5, name:'Fireplace', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:7, name:'Forest', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:8, name:'Pastel Colors', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:20, name:'Spring', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:21, name:'Summer', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:22, name:'Fall', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:23, name:'Deep dive', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:24, name:'Jungle', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:25, name:'Mojito', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:26, name:'Club', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:29, name:'Candlelight', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:30, name:'Golden white', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:31, name:'Pulse', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:32, name:'Steampunk', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, // Special {id:27, name:'Christmas', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, {id:28, name:'Halloween', icon:'light_mode', state: true, speed:100, brightness: 100, temperature: null, color:null}, ]; $scope.ismanager = $sessionStorage.currentUser.ismanager; $scope.isLoading = true; // show ajax loader /////////////////////////////////////////////////////////////////////////////////////// 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.room = {isvisible: false}; $scope.equipment = []; function load_data() { return new Promise((resolve, reject) => { $scope.chart_consumption_loading = true; // show chart 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 { ' + 'rooms(id:"' + $stateParams.room_id + '", time_start:"' + time_start + '", time_end:"' + time_end + '", timezone:"' + sysClock.getTimeZone() + '") { ' + 'id ' + 'name ' + 'isactive ' + 'created ' + 'sqm ' + 'room_equipment_total ' + 'room_equipment_active ' + 'power_consumption ' + 'co2_emission ' + 'status ' + 'company { ' + 'id ' + '} ' + 'location { ' + 'id ' + 'name ' + '} ' + 'floor { ' + 'id ' + 'name ' + '} ' + 'equipment { ' + 'id ' + 'name ' + 'status ' + 'type {' + 'id ' + 'name ' + '} ' + 'brand {' + 'id ' + 'name ' + '} ' + 'model {' + 'id ' + 'name ' + '} ' + 'request {' + 'id ' + 'created ' + 'status ' + '} ' + '... on EquipmentLight { ' + 'power_consumption ' + 'isemergency ' + 'state { ' + 'connected ' + 'rssi ' + 'state ' + 'r ' + 'g ' + 'b ' + 'c ' + 'w ' + 'temperature ' + 'brightness ' + 'scene ' + 'on_since ' + 'off_since ' + '} ' + '} ' + '... on EquipmentUPS { ' + 'state { ' + 'status ' + '} ' + '} ' + '... on EquipmentInverter { ' + 'state { ' + 'status ' + '} ' + '} ' + '... on EquipmentNT { ' + 'state { ' + 'mode ' + '} ' + '} ' + '... on EquipmentFACP { ' + 'state { ' + 'status ' + '} ' + '} ' + '... on EquipmentOOC { ' + 'state { ' + 'status ' + '} ' + '} ' + '... on EquipmentSocket { ' + 'power_consumption ' + 'state { ' + 'status ' + '} ' + '} ' + '... on EquipmentGeneric { ' + 'socket { ' + 'power_consumption ' + 'state { ' + 'status ' + '} ' + '} ' + '} ' + '} ' + '} ' + '}' }; $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve console.log('response:', response); if(response.data.data.rooms.length) { $scope.room = response.data.data.rooms[0]; $scope.equipment = $scope.room.equipment; console.log($scope.equipment); for(let i=0;i<$scope.equipment.length;i++){ let device = $scope.equipment[i]; console.log('device type:', device.type); if(!([1,2,3,4,5,6,7].includes(parseInt(device.type.id)))) { console.log('generic device:', device); /* */ } } $scope.equipment.forEach(device => { if(parseInt(device.type.id) == 1) { // UPS device.power_consumption = 0; console.log(device.id, device.state); if(!device.state.status) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.state.status.toLowerCase()) { case 'ol': // On Line device.state.status_display = 'ON GRID'; device.state.status_type = 'normal'; break; case 'ol chrg': // On Line - Charging device.state.status_display = 'CHARGING'; device.state.status_type = 'normal'; break; case 'ob': // On Battery device.state.status_display = 'ON BATTERY'; device.state.status_type = 'alert'; break; case 'lb': // Low Battery device.state.status_display = 'LOW BATTERY'; device.state.status_type = 'alert'; break; case 'rb': // Replace Battery device.state.status_display = 'REPLACE BATTERY'; device.state.status_type = 'warning'; break; case 'nocomm': // NO COMMUNICATION device.state.status_display = 'OFFLINE'; device.state.status_type = 'alert'; break; default: device.state.status_display = device.state.status; device.state.status_type = 'warning'; } } } if(parseInt(device.type.id) == 3) { // Inverter device.power_consumption = 0; if(!device.state.status) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.state.status.toLowerCase()) { case 'ol': // On Line device.state.status_display = 'ON GRID'; device.state.status_type = 'normal'; break; case 'ob': // On Battery device.state.status_display = 'ON BATTERY'; device.state.status_type = 'alert'; break; case 'lb': // Low Battery device.state.status_display = 'LOW BATTERY'; device.state.status_type = 'alert'; break; case 'rb': // Replace Battery device.state.status_display = 'REPLACE BATTERY'; device.state.status_type = 'warning'; break; default: device.state.status_display = $scope.equipment.state.status; device.state.status_type = 'warning'; } } } if(parseInt(device.type.id) == 2) { // PoE Light if(device.state) { if(device.state.state) { // light is ON device.brightness = device.state.brightness?device.state.brightness:0; if(device.state.scene) { // we have SCENE information device.scene = $filter('filter')($scope.scenes, {id: device.state.scene})[0]; } else { device.scene = $filter('filter')($scope.scenes, {id: 11})[0];; // White Light = default scene if no data available } } else { device.brightness = device.state.brightness?device.state.brightness:0; device.scene = $filter('filter')($scope.scenes, {id: 0})[0]; // OFF } } else { // if object is empty = no record in equipment_light_status table for corresponding equipment device.brightness = 0; device.scene = $filter('filter')($scope.scenes, {id: 0})[0]; // OFF } } if(parseInt(device.type.id) == 4) { // OOC device.power_consumption = 0; if(!device.state.status) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.state.status.toLowerCase()) { case 'online': // On Line device.state.status_display = 'ONLINE'; device.state.status_type = 'normal'; break; case 'reboot': // On Battery device.state.status_display = 'REBOOT'; device.state.status_type = 'warning'; break; case 'offline': // Low Battery device.state.status_display = 'OFFLINE'; device.state.status_type = 'alert'; break; default: device.state.status_display = $scope.equipment.state.status; device.state.status_type = 'warning'; } } } if(parseInt(device.type.id) == 5) { // NT device.type.generic = false; device.power_consumption = 0; if(!device.state.mode) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.state.mode.toUpperCase()) { case 'H': // On Line device.state.status_display = 'HEAT'; device.state.status_type = 'normal'; break; case 'C': // On Line device.state.status_display = 'COOL'; device.state.status_type = 'normal'; break; case 'A': // On Line device.state.status_display = 'AUTO'; device.state.status_type = 'normal'; break; case 'E': // On Battery device.state.status_display = 'EHEAT'; device.state.status_type = 'normal'; break; case 'O': device.state.status_display = 'OFF'; device.state.status_type = 'warning'; break; default: device.state.status_display = $scope.equipment.state.status; device.state.status_type = 'warning'; } } } if(parseInt(device.type.id) == 6) { // FACP device.power_consumption = 0; if(!device.state.status) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.state.status.toUpperCase()) { case 'N': // On Line / Normal device.state.status_display = 'ONLINE'; device.state.status_type = 'normal'; break; case 'O': // Off Line device.state.status_display = 'OFFLINE'; device.state.status_type = 'warning'; break; case 'A': // On Alert device.state.status_display = 'ALERT'; device.state.status_type = 'alert'; break; default: device.state.status_display = $scope.equipment.state.status; device.state.status_type = 'warning'; } } } if(parseInt(device.type.id) == 7) { // Socket //device.power_consumption = 0; if(!device.state.status) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.state.status.toUpperCase()) { case 'TRUE': // On Line / Normal device.state.status_display = 'ON'; device.state.status_type = 'normal'; break; case 'FALSE': // Off Line device.state.status_display = 'OFF'; device.state.status_type = 'warning'; break; default: device.state.status_display = $scope.equipment.state.status; device.state.status_type = 'warning'; } } } //if(!([1,2,3,4,5,6,7].includes(parseInt(device.type.id)))) { // Generic Device if(parseInt(device.type.id)>7) { // Generic Device device.type.generic = true; device.power_consumption = device.socket.power_consumption; device.state = {}; if(!device.socket.state.status) { device.state.status_display = 'NO DATA'; device.state.status_type = 'nodata'; } else { switch(device.socket.state.status.toUpperCase()) { case 'TRUE': // On Line / Normal device.state.status_display = 'ON'; device.state.status_type = 'normal'; break; case 'FALSE': // Off Line device.state.status_display = 'OFF'; device.state.status_type = 'warning'; break; default: device.state.status_display = $scope.equipment.state.status; device.state.status_type = 'warning'; } } } }); $scope.room.isvisible = true; if($scope.room.equipment.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.room.power_consumption = $scope.room.power_consumption?$scope.room.power_consumption:0; $scope.room.co2_emission = $scope.room.co2_emission?$scope.room.co2_emission:0; },function(error) { // failure console.error(error); reject(error); } ); }); }); } $timeout(function() { load_data().then(() => { // nothing }).catch(error => { console.warn(error); }); }, 100); $scope.debouncer = debounce(trigger_request, 500); $scope.lightSlider = function(light_id) { var device = $filter('filter')($scope.equipment, {id: light_id})[0]; if(device.brightness==0) { device.scene = $filter('filter')($scope.scenes, {id: 0})[0]; // OFF } else { if(device.brightness>0 && (device.scene.id==14 || device.scene.id==0)) { device.scene = $filter('filter')($scope.scenes, {id: 11})[0]; // White Light } } $scope.debouncer(light_id); }; function trigger_request(light_id) { var device = $filter('filter')($scope.equipment, {id: light_id})[0]; equipment_light_request({ equipment: device.id, state: device.brightness>0?true:false, brightness: device.brightness, scene: device.scene.id }); }; $scope.setDayMode = function(light_id) { var device = $filter('filter')($scope.equipment, {id: light_id})[0]; var scene = $filter('filter')($scope.scenes, {id: 11})[0]; device.scene = scene; device.brightness = 100; equipment_light_request({equipment: device.id, state:true, scene:device.scene.id, brightness:device.brightness}); }; $scope.setOffMode = function(light_id) { var device = $filter('filter')($scope.equipment, {id: light_id})[0]; var scene = $filter('filter')($scope.scenes, {id: 0})[0]; device.scene = scene; equipment_light_request({equipment: device.id, state:false, scene:device.scene.id, brightness:null}); }; $scope.setNightMode = function(light_id) { var device = $filter('filter')($scope.equipment, {id: light_id})[0]; var scene = $filter('filter')($scope.scenes, {id: 14})[0]; device.scene = scene; device.brightness = scene.brightness; equipment_light_request({equipment: device.id, state:true, scene:device.scene.id, brightness:device.brightness}); }; function equipment_light_request(change) { console.log(change); change.brightness = change.brightness?wiz.dimm2wiz(change.brightness):null; authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'equipmentlightchange ( ' + 'company_id: "' + $scope.room.company.id + '", ' + 'equipment_id: "' + change.equipment + '", ' + (change.scene ? ('scene: ' + change.scene + ', ') : '') + (change.brightness ? ('brightness: ' + change.brightness + ', ') : '') + 'state: ' + change.state + '){id, created, status}' + '}' }; console.log(request); $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(response){ // resolve //$state.reload(); let device = $filter('filter')($scope.equipment, {id: change.equipment})[0]; let request = response.data.data.equipmentlightchange; device.request = request; $mdMenu.hide(); // close menu with light mode selector setTimeout(() => { // check status after 1min - if still ongoing then mark as failed and unlock UI if(device.request.status === 'new' || device.request.status === 'waiting') { console.log('request failed', device.request); console.log(device); console.log($scope.equipment); device.request.status = 'failed'; } else { console.log('request succeed', device.request); } }, 60000); },function(error) { // failure console.error(error); } ); }); } $scope.roomLight = function() { modalDialog.showDialog({ 'template':'modal.lightsetings.html', 'controller':'modalLightController', 'entity': "ROOM" }).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 { ' + 'roomlightchange ( ' + 'company_id: "' + $scope.room.company.id + '", ' + 'room_id: "' + $stateParams.room_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.roomlightchange); },function(error) { // failure console.error(error); } ); }); } ) } $scope.removeRoom = function() { 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.room.company.id + '", ' + 'room_id: "' + $stateParams.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.editEquipment = function(device) { modalDialog.showDialog({ 'template':'modal.editdevice.html', 'controller':'modalEditEquipmentController', 'id': device.id, 'brand': device.brand, 'type': device.type, 'model': device.model, 'name': device.name }).then( // acknowledge function(device){ if(device!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'equipmentupdate ( ' + 'company_id: "' + $scope.room.company.id + '", ' + 'equipment_id: "' + device.id + '", ' + 'model_id: ' + device.model.id + ', ' + 'name: "' + device.name + '" ' + ') { id }' + '}' }; console.log(request); $http({ method: 'POST', url: CONFIG.APP_API, data: request, headers: authHeader }).then( function(device){ // resolve console.log(device); $state.reload(); },function(error) { // failure console.error(error); } ); }); } } ) } $scope.editRoom = function() { modalDialog.showDialog({ 'template':'modal.editroom.html', 'controller':'modalEditRoomController', 'company_id': $scope.room.company.id, 'location_id': $scope.room.location.id, 'location_name': $scope.room.location.name, 'floor_id': $scope.room.floor.id, 'floor_name': $scope.room.floor.name, 'name': $scope.room.name, 'sqm': $scope.room.sqm }).then( // acknowledge function(room){ if(room!==null) { authService.getJWTAuth().then(authHeader => { var request = {'query': 'mutation { ' + 'roomupdate ( ' + 'company_id: "' + $scope.room.company.id + '", ' + 'floor_id: "' + room.floor.id + '", ' + 'room_id: "' + $stateParams.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.removeEquipment = function(equipment_id) { modalDialog.showDialog({ 'template':'modal.codeconfirmation.html', 'controller':'modalCodeConfirmationController', 'subtitle': "DELETING EQUIPMENT", '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.room.company.id + '", ' + 'equipment_id: "' + equipment_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/floors/' + $scope.room.floor.id); }; $scope.viewEquipment = function(equipment_id) { $location.path('/system/equipment/' + equipment_id); } $scope.$on('light:state', function(event, payload) { // light state update event var device = $filter('filter')($scope.equipment, {id: payload.id})[0]; //console.log('> Light: ' + device.name + ' > Object: ' + payload.object); //console.log('light:state payload: ', payload); //console.log('> Light: ' + device.name + ' @state: ' + payload.state.state + ' @brightness: ' + wiz.wiz2dimm(payload.state.brightness) + ' @scene: ' + payload.state.scene + ' @RSSI: ' + payload.state.rssi); if(device) { if(payload.state.state) { device.state = payload.state.state; device.brightness = wiz.wiz2dimm(payload.state.brightness); if(payload.state.scene == null && device.state) { // no sceneId but light is ON //console.log('> Light: ' + device.name + ' set scene: White Light'); device.scene = $filter('filter')($scope.scenes, {id: 11})[0]; // White Light } else { //console.log('> Light: ' + device.name + ' set scene: ' + ($filter('filter')($scope.scenes, {id: payload.state.scene})[0].name)); device.scene = $filter('filter')($scope.scenes, {id: payload.state.scene})[0]; } } else { //console.log('> Light: ' + device.name + ' set scene: OFF'); device.scene = $filter('filter')($scope.scenes, {id: 0})[0]; // OFF } } }); $scope.$on('light:request', function(event, payload) { // light state update event var device = $filter('filter')($scope.equipment, {id: payload.id})[0]; console.log('light:request device.request.id:', device.request.id); console.log('light:request payload.request.request: ', payload.request.request); console.log('light:request', payload); if(device && device.request.id === payload.request.request) { if(payload.request.status) { device.request.status = payload.request.status; console.log('* WS: ', payload); } } }); //////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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.room_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.room_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){ chart_consumption = chart; chart_load_daily_data(); // dafault $scope.chart_consumption_loading = false; resolve(); }); }); } }]) })();