diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index ff4ef006d..ccc4ac8fa 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -5,6 +5,22 @@ require_once('Server.php'); require_once('Object.php'); require_once('Control.php'); require_once('Storage.php'); +require_once('Group.php'); + +$FunctionTypes = null; + +function getMonitorFunctionTypes() { + if ( !isset($FunctionTypes ) ) { + $FunctionTypes = array( + 'None' => translate('FnNone'), + 'Monitor' => translate('FnMonitor'), + 'Modect' => translate('FnModect'), + 'Record' => translate('FnMocord'), + 'Nodect' => translate('FnNodect') + ); + } + return $FunctionTypes; +} class Monitor extends ZM_Object { protected static $table = 'Monitors'; @@ -590,5 +606,14 @@ class Monitor extends ZM_Object { return true; } // end function sendControlCommand($mid, $command) + function Groups($new='') { + if ( $new != '' ) + $this->Groups = $new; + if ( !property_exists($this, 'Groups') ) { + $this->Groups = Group::find(array('Id'=>$this->GroupIds())); + } + return $this->Groups; + } + } // end class Monitor ?> diff --git a/web/includes/Storage.php b/web/includes/Storage.php index 3a30606e6..2c243d913 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -131,7 +131,7 @@ class Storage extends ZM_Object { public function event_disk_space() { # This isn't a function like this in php, so we have to add up the space used in each event. - if ( (! property_exists($this, 'DiskSpace')) or (!$this->{'DiskSpace'}) ) { + if ( (! property_exists($this, 'DiskSpace')) or (!isset($this->{'DiskSpace'})) ) { $used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id())); do { diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js new file mode 100644 index 000000000..86addd035 --- /dev/null +++ b/web/js/MonitorStream.js @@ -0,0 +1,205 @@ + +function MonitorStream(monitorData) { + this.id = monitorData.id; + this.connKey = monitorData.connKey; + this.url = monitorData.url; + this.width = monitorData.width; + this.height = monitorData.height; + this.status = null; + this.alarmState = STATE_IDLE; + this.lastAlarmState = STATE_IDLE; + this.streamCmdParms = 'view=request&request=stream&connkey='+this.connKey; + if ( auth_hash ) { + this.streamCmdParms += '&auth='+auth_hash; + } else if ( auth_relay ) { + this.streamCmdParms += '&'+auth_relay; + } + this.streamCmdTimer = null; + this.type = monitorData.type; + this.refresh = monitorData.refresh; + this.start = function(delay) { + if ( this.streamCmdQuery ) { + this.streamCmdTimer = this.streamCmdQuery.delay(delay, this); + } else { + console.log("No streamCmdQuery"); + } + }; + + this.eventHandler = function(event) { + console.log(event); + }; + + this.onclick = function(evt) { + var el = evt.currentTarget; + var tag = 'watch'; + var id = el.getAttribute("data-monitor-id"); + var width = el.getAttribute("data-width"); + var height = el.getAttribute("data-height"); + var url = '?view=watch&mid='+id; + var name = 'zmWatch'+id; + evt.preventDefault(); + createPopup(url, name, tag, width, height); + }; + + this.setup_onclick = function() { + var el = document.getElementById('imageFeed'+this.id); + if ( el ) el.addEventListener('click', this.onclick, false); + }; + this.disable_onclick = function() { + document.getElementById('imageFeed'+this.id).removeEventListener('click', this.onclick ); + }; + + this.setStateClass = function(element, stateClass) { + if ( !element.hasClass( stateClass ) ) { + if ( stateClass != 'alarm' ) { + element.removeClass('alarm'); + } + if ( stateClass != 'alert' ) { + element.removeClass('alert'); + } + if ( stateClass != 'idle' ) { + element.removeClass('idle'); + } + element.addClass(stateClass); + } + }; + + this.onError = function(text, error) { + console.log('onerror: ' + text + ' error:'+error); + // Requeue, but want to wait a while. + var streamCmdTimeout = 10*statusRefreshTimeout; + this.streamCmdTimer = this.streamCmdQuery.delay(streamCmdTimeout, this); + }; + this.onFailure = function(xhr) { + console.log('onFailure: ' + this.connKey); + console.log(xhr); + if ( ! requestQueue.hasNext("cmdReq"+this.id) ) { + console.log("Not requeuing because there is one already"); + requestQueue.addRequest("cmdReq"+this.id, this.streamCmdReq); + } + if ( 0 ) { + // Requeue, but want to wait a while. + if ( this.streamCmdTimer ) { + this.streamCmdTimer = clearTimeout( this.streamCmdTimer ); + } + var streamCmdTimeout = 1000*statusRefreshTimeout; + this.streamCmdTimer = this.streamCmdQuery.delay( streamCmdTimeout, this, true ); + requestQueue.resume(); + } + console.log("done failure"); + }; + + this.getStreamCmdResponse = function(respObj, respText) { + if ( this.streamCmdTimer ) { + this.streamCmdTimer = clearTimeout( this.streamCmdTimer ); + } + + var stream = $j('#liveStream'+this.id)[0]; + + if ( respObj.result == 'Ok' ) { + if ( respObj.status ) { + this.status = respObj.status; + this.alarmState = this.status.state; + + var stateClass = ""; + if ( this.alarmState == STATE_ALARM ) { + stateClass = "alarm"; + } else if ( this.alarmState == STATE_ALERT ) { + stateClass = "alert"; + } else { + stateClass = "idle"; + } + + if ( (!COMPACT_MONTAGE) && (this.type != 'WebSite') ) { + $('fpsValue'+this.id).set('text', this.status.fps); + $('stateValue'+this.id).set('text', stateStrings[this.alarmState]); + this.setStateClass($('monitorState'+this.id), stateClass); + } + this.setStateClass($('monitor'+this.id), stateClass); + + /*Stream could be an applet so can't use moo tools*/ + stream.className = stateClass; + + var isAlarmed = ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT ); + var wasAlarmed = ( this.lastAlarmState == STATE_ALARM || this.lastAlarmState == STATE_ALERT ); + + var newAlarm = ( isAlarmed && !wasAlarmed ); + var oldAlarm = ( !isAlarmed && wasAlarmed ); + + if ( newAlarm ) { + if ( false && SOUND_ON_ALARM ) { + // Enable the alarm sound + $('alarmSound').removeClass('hidden'); + } + if ( POPUP_ON_ALARM ) { + windowToFront(); + } + } + if ( false && SOUND_ON_ALARM ) { + if ( oldAlarm ) { + // Disable alarm sound + $('alarmSound').addClass('hidden'); + } + } + if ( this.status.auth ) { + if ( this.status.auth != auth_hash ) { + // Try to reload the image stream. + if ( stream ) { + stream.src = stream.src.replace(/auth=\w+/i, 'auth='+this.status.auth); + } + console.log("Changed auth from " + auth_hash + " to " + this.status.auth); + auth_hash = this.status.auth; + } + } // end if have a new auth hash + } // end if has state + } else { + console.error(respObj.message); + // Try to reload the image stream. + if ( stream ) { + if ( stream.src ) { + console.log('Reloading stream: ' + stream.src); + stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) )); + } else { + } + } else { + console.log('No stream to reload?'); + } + } // end if Ok or not + + var streamCmdTimeout = statusRefreshTimeout; + // The idea here is if we are alarmed, do updates faster. + // However, there is a timeout in the php side which isn't getting modified, + // so this may cause a problem. Also the server may only be able to update so fast. + //if ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT ) { + //streamCmdTimeout = streamCmdTimeout/5; + //} + this.streamCmdTimer = this.streamCmdQuery.delay(streamCmdTimeout, this); + this.lastAlarmState = this.alarmState; + }; + + this.streamCmdQuery = function(resent) { + if ( resent ) { + console.log(this.connKey+": timeout: Resending"); + this.streamCmdReq.cancel(); + } + //console.log("Starting CmdQuery for " + this.connKey ); + if ( this.type != 'WebSite' ) { + this.streamCmdReq.send(this.streamCmdParms+"&command="+CMD_QUERY); + } + }; + + if ( this.type != 'WebSite' ) { + this.streamCmdReq = new Request.JSON( { + url: this.url, + method: 'get', + timeout: AJAX_TIMEOUT, + onSuccess: this.getStreamCmdResponse.bind(this), + onTimeout: this.streamCmdQuery.bind(this, true), + onError: this.onError.bind(this), + onFailure: this.onFailure.bind(this), + link: 'cancel' + } ); + console.log("queueing for " + this.id + " " + this.connKey + " timeout is: " + AJAX_TIMEOUT); + requestQueue.addRequest("cmdReq"+this.id, this.streamCmdReq); + } +} // end function MonitorStream diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index 5d9481471..6d00e1b8c 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -461,6 +461,7 @@ function getStorageHTML() { $result=''; $func = function($S) { + ZM\Logger::Debug("disk_usage for " . $S->Name()); $class = ''; if ( $S->disk_usage_percent() > 98 ) { $class = 'text-danger'; diff --git a/web/skins/classic/views/_monitor_filters.php b/web/skins/classic/views/_monitor_filters.php index 4cd41baa6..1531237b0 100644 --- a/web/skins/classic/views/_monitor_filters.php +++ b/web/skins/classic/views/_monitor_filters.php @@ -18,6 +18,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // +require_once('includes/Monitor.php'); + zm_session_start(); foreach ( array('GroupId','Function','ServerId','StorageId','Status','MonitorId','MonitorName','Source') as $var ) { if ( isset($_REQUEST[$var]) ) { @@ -100,10 +102,7 @@ $html .= ''; $html .= htmlSelect('Function[]', $Functions, diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 20be7eeeb..803157e91 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -94,6 +94,7 @@ $eventCounts = array( ), ); +require_once('includes/Group_Monitor.php'); $navbar = getNavBarHTML(); ob_start(); @@ -107,6 +108,13 @@ $maxHeight = 0; $zoneCount = 0; $total_capturing_bandwidth=0; +$group_ids_by_monitor_id = array(); +foreach ( ZM\Group_Monitor::find(array('MonitorId'=>$selected_monitor_ids)) as $GM ) { + if ( !isset($group_ids_by_monitor_id[$GM->MonitorId()]) ) + $group_ids_by_monitor_id[$GM->MonitorId()] = array(); + $group_ids_by_monitor_id[$GM->MonitorId()][] = $GM->GroupId(); +} + $status_counts = array(); for ( $i = 0; $i < count($displayMonitors); $i++ ) { $monitor = &$displayMonitors[$i]; @@ -244,6 +252,7 @@ echo $table_head; for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { $monitor = $displayMonitors[$monitor_i]; $Monitor = new ZM\Monitor($monitor); + $Monitor->GroupIds(isset($group_ids_by_monitor_id[$Monitor->Id()]) ? $group_ids_by_monitor_id[$Monitor->Id()] : array()); include('function.php'); if ( $monitor_i and ( $monitor_i % 100 == 0 ) ) { echo ''; diff --git a/web/skins/classic/views/function.php b/web/skins/classic/views/function.php index 2fc53d812..7cfc4723c 100644 --- a/web/skins/classic/views/function.php +++ b/web/skins/classic/views/function.php @@ -35,14 +35,7 @@ if ( !canEdit('Monitors') ) {
- + Function(), array('id'=>'funcSelect-'.$monitor['Id'])) ?> Enabled() ?' checked="checked"' : '' ?>/>