mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-06 17:15:38 -08:00
Front 2.50
This commit is contained in:
373
front/css/pialert.css
Normal file
373
front/css/pialert.css
Normal file
@@ -0,0 +1,373 @@
|
||||
/*******************************************************************************
|
||||
* Pi.alert CSS
|
||||
*******************************************************************************/
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Global Variables
|
||||
----------------------------------------------------------------------------- */
|
||||
:root {
|
||||
--color-aqua: #00c0ef;
|
||||
--color-green: #00a65a;
|
||||
--color-yellow: #f39c12;
|
||||
--color-red: #dd4b39;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Text Classes
|
||||
----------------------------------------------------------------------------- */
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.text-gray50 {
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.text-aqua-20 {
|
||||
color: rgba(0,192,239,20%);
|
||||
}
|
||||
|
||||
.text-green-20 {
|
||||
color: rgba(0,166,90,20%);
|
||||
}
|
||||
|
||||
.text-yellow-20 {
|
||||
color: rgba(243,156,18,20%);
|
||||
}
|
||||
|
||||
.text-red-20 {
|
||||
color: rgba(221,75,57,20%);
|
||||
}
|
||||
|
||||
.no-border {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Main Sections
|
||||
----------------------------------------------------------------------------- */
|
||||
.content-header {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.content-header > .breadcrumb {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.box-body {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.main-footer {
|
||||
padding: 5px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Main Menu
|
||||
----------------------------------------------------------------------------- */
|
||||
.main-header .logo {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.main-header > .navbar {
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
.main-sidebar, .left-side {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.content-wrapper, .right-side, .main-footer {
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.main-header .logo {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.main-header .navbar {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.content-wrapper, .main-footer {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sidebar-open .content-wrapper, .sidebar-open .main-footer {
|
||||
-webkit-transform: translate(150px, 0);
|
||||
-ms-transform: translate(150px, 0);
|
||||
-o-transform: translate(150px, 0);
|
||||
transform: translate(150px, 0)
|
||||
}
|
||||
|
||||
|
||||
.skin-yellow-light .sidebar-menu > li > a:hover {
|
||||
background: #f0f0f0;
|
||||
border-left-color: rgb(243, 156, 18);
|
||||
}
|
||||
|
||||
.skin-yellow-light .sidebar-menu > li.active > a {
|
||||
background: #e0e0e0;
|
||||
border-left-color: rgb(243, 156, 18);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Boxes
|
||||
----------------------------------------------------------------------------- */
|
||||
.box-transparent {
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pa-small-box-2 .inner h3 {
|
||||
margin-left: 0em;
|
||||
margin-bottom: 1.3em;
|
||||
}
|
||||
|
||||
.pa-small-box-aqua {
|
||||
border-top: 3px solid #00c0ef;
|
||||
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.pa-small-box-aqua .inner {
|
||||
color: #00c0ef;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
|
||||
.pa-small-box-aqua .inner h3 {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.pa-small-box-aqua .icon {
|
||||
color: #00c0ef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
.pa-small-box-green {
|
||||
border-top: 3px solid #00a65a;
|
||||
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.pa-small-box-green .inner {
|
||||
color: #00a65a;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
|
||||
.pa-small-box-green .inner h3 {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.pa-small-box-green .icon {
|
||||
color: #00a65a;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
.pa-small-box-yellow {
|
||||
border-top: 3px solid #f39c12;
|
||||
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.pa-small-box-yellow .inner {
|
||||
color: #f39c12;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
|
||||
.pa-small-box-yellow .inner h3 {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.pa-small-box-yellow .icon {
|
||||
color: #f39c12;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
.pa-small-box-red {
|
||||
border-top: 3px solid #dd4b39;
|
||||
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.pa-small-box-red .inner {
|
||||
color: #dd4b39;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
|
||||
.pa-small-box-red .inner h3 {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.pa-small-box-red .icon {
|
||||
color: #dd4b39;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Box Borders
|
||||
----------------------------------------------------------------------------- */
|
||||
.box.box-aqua {
|
||||
border-top-color: #00c0ef;
|
||||
}
|
||||
|
||||
.box.box-green {
|
||||
border-top-color: #00a65a;
|
||||
}
|
||||
|
||||
.box.box-yellow {
|
||||
border-top-color: #f39c12;
|
||||
}
|
||||
|
||||
.box.box-red {
|
||||
border-top-color: #dd4b39;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Custom Border
|
||||
----------------------------------------------------------------------------- */
|
||||
.bottom-border-aqua {
|
||||
border-bottom-color: #00c0ef;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 3px
|
||||
}
|
||||
|
||||
.bottom-border-primary {
|
||||
border-bottom-color: #3c8dbc;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 3px
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Tabs
|
||||
----------------------------------------------------------------------------- */
|
||||
.nav-tabs-custom {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.nav > li > a {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Menu dropdown
|
||||
----------------------------------------------------------------------------- */
|
||||
.dropdown-menu {
|
||||
max-height: 250px;
|
||||
overflow-x: hidden;
|
||||
box-shadow: 0px 3px 20px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Default Table config
|
||||
----------------------------------------------------------------------------- */
|
||||
.table > tbody > tr > td {
|
||||
padding:4px;
|
||||
}
|
||||
|
||||
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
|
||||
background-color: #FFFFD0;
|
||||
}
|
||||
|
||||
.dataTables_info, .dataTables_paginate, .dataTables_length, .dataTables_filter {
|
||||
color: #B0B0B0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Customized Full Calendar
|
||||
----------------------------------------------------------------------------- */
|
||||
.fc h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.fc-weekend {
|
||||
background-color: #FFF0E0;
|
||||
}
|
||||
|
||||
.fc-normaldays {
|
||||
background-color: #FF0000;
|
||||
}
|
||||
|
||||
.fc-sat {
|
||||
background-color: #FFF0E0;
|
||||
}
|
||||
|
||||
.fc-sun {
|
||||
background-color: #FFF0E0;
|
||||
}
|
||||
|
||||
.fc-resized-row { height: 26px !important; }
|
||||
|
||||
.fc-transparent-border {
|
||||
border-Color: transparent !important;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
background-color: #606060;
|
||||
color: White;
|
||||
}
|
||||
|
||||
.tooltip.right .tooltip-arrow {
|
||||
border-right: 5px solid #606060;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Spin
|
||||
----------------------------------------------------------------------------- */
|
||||
.pa_semitransparent-panel {
|
||||
position: absolute;
|
||||
width: 100%; //calc (100% -40px);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: block;
|
||||
|
||||
opacity: 0.8;
|
||||
background-color: #fff;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.pa_spinner {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 20px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 15px;
|
||||
width: 200px;
|
||||
|
||||
background-color: #fff;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
957
front/deviceDetails.php
Normal file
957
front/deviceDetails.php
Normal file
@@ -0,0 +1,957 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
 <small>Quering device info...</small>
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb text-gray50">
|
||||
Sessions, Presence & Alerts period:
|
||||
|
||||
<select id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day">Today</option>
|
||||
<option value="7 days">Last Week</option>
|
||||
<option value="1 month" selected>Last Month</option>
|
||||
<option value="1 year">Last Year</option>
|
||||
<option value="100 years">All info</option>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: $('#tabDetails').trigger('click')">
|
||||
<div class="small-box bg-aqua pa-small-box-aqua">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Current Status</h4>
|
||||
<h3 id="deviceStatus" style="margin-left: 0em"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i id="deviceStatusIcon" class=""></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: $('#tabSessions').trigger('click');">
|
||||
<div class="small-box bg-green pa-small-box-green">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Sessions</h4>
|
||||
<h3 id="deviceSessions"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-plug"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: $('#tabPresence').trigger('click')">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow">
|
||||
<div class="inner">
|
||||
|
||||
<h4 id="deviceEventsTitle">
|
||||
<!-- Events / Presence -->Presence
|
||||
</h4>
|
||||
<h3 id="deviceEvents" style="margin-left: 0em"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div id="deviceEventsIcon" class="icon">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- small box ------------------------------------------------------------ -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: $('#tabEvents').trigger('click');">
|
||||
<div class="small-box bg-red pa-small-box-red">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Down Alerts</h4>
|
||||
<h3 id="deviceDownAlerts"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-warning"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
|
||||
<!-- tab control------------------------------------------------------------ -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-sm-12 col-xs-12">
|
||||
<!--
|
||||
<div class="box-transparent">
|
||||
-->
|
||||
|
||||
<div id="navDevice" class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs" style="font-size:16px;">
|
||||
<li><a id="tabDetails" href="#panDetails" data-toggle="tab">Details</a></li>
|
||||
<li><a id="tabSessions" href="#panSessions" data-toggle="tab">Sessions</a></li>
|
||||
<li class="active"><a id="tabPresence" href="#panPresence" data-toggle="tab">Presence</a></li>
|
||||
<li><a id="tabEvents" href="#panEvents" data-toggle="tab">Events</a></li>
|
||||
</ul>
|
||||
<div class="tab-content" style="min-height: 430px">
|
||||
|
||||
<!-- tab page -------------------------------------------------------------- -->
|
||||
<div class="tab-pane fade" id="panDetails">
|
||||
|
||||
<div class="row">
|
||||
<!-- Column 1 -->
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua">Main Info</h4>
|
||||
<div class="box-body form-horizontal">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">MAC</label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="txtMAC" type="text" readonly value="--">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Name</label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="txtName" type="text" value="--"'>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Owner</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtOwner" type="text" value="--">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
<ul id="dropdownOwner" class="dropdown-menu dropdown-menu-right">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Type</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtDeviceType" type="text" value="--">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"
|
||||
aria-expanded="false" >
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
<ul id="dropdownDeviceType" class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtDeviceType','Smartphone')">Smartphone</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtDeviceType','Laptop')">Laptop</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtDeviceType','PC')">PC</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtDeviceType','Others')">Others</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Vendor</label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="txtVendor" type="text" value="--">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Favorite</label>
|
||||
<div class="col-sm-9" style="padding-top:6px;">
|
||||
<input class="checkbox" id="chkFavorite" type="checkbox">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Group</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtGroup" type="text" value="--">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
<ul id="dropdownGroup" class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtGroup','Always On')">Always On</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtGroup','Friends')">Friends</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtGroup','Personal')">Personal</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtGroup','Others')">Others</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Comments</label>
|
||||
<div class="col-sm-9">
|
||||
<textarea class="form-control" rows="3" id="txtComments"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 2 -->
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua">Session Info</h4>
|
||||
|
||||
<div class="box-body form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Status</label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtStatus" type="text" readonly value="--">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">First Session</label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtFirstConnection" type="text" readonly value="--">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Last Session</label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtLastConnection" type="text" readonly value="--">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Last IP</label>
|
||||
<div class="col-sm-7">
|
||||
<input class="form-control" id="txtLastIP" type="text" readonly value="--">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Static IP</label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox" id="chkStaticIP" type="checkbox" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 3 -->
|
||||
<div class="col-lg-4 col-sm-6 col-xs-12">
|
||||
<h4 class="bottom-border-aqua">Events & Alerts config</h4>
|
||||
<div class="box-body form-horizontal">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Scan Cycle</label>
|
||||
<div class="col-sm-7">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtScanCycle" type="text" value="--"
|
||||
readonly style="background-color: #fff;">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"
|
||||
aria-expanded="false" id="dropdownButtonScanCycle">
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
<ul id="dropdownScanCycle" class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtScanCycle','1 min')">Scan 1' every 5'</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtScanCycle','15 min');">Scan 12' every 15'</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtScanCycle','0 min');">Don't Scan</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Alert All Events</label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox" id="chkAlertEvents" type="checkbox" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Alert Down</label>
|
||||
<div class="col-sm-7" style="padding-top:6px;">
|
||||
<input class="checkbox" id="chkAlertDown" type="checkbox" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label" style="padding-top: 0px; padding-left: 0px;">
|
||||
Skip repeated notifications during</label>
|
||||
<div class="col-sm-7">
|
||||
<div class="input-group">
|
||||
<input class="form-control" id="txtSkipRepeated" type="text" value="--"
|
||||
readonly style="background-color: #fff;">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"
|
||||
aria-expanded="false" id="dropdownButtonSkipRepeated">
|
||||
<span class="fa fa-caret-down"></span></button>
|
||||
<ul id="dropdownSkipRepeated" class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtSkipRepeated','0 h (notify all events)');">
|
||||
0 h (notify all events)</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtSkipRepeated','1 h');">1 h</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtSkipRepeated','8 h');">8 h</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtSkipRepeated','24 h');">24 h</a></li>
|
||||
<li><a href="javascript:void(0)"
|
||||
onclick="setTextValue('txtSkipRepeated','168 h (one week)');">
|
||||
168 h (one week)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12">
|
||||
<button class="btn btn-primary pull-right" style="min-width: 100px; margin-left:20px;" id="btnSave" onclick="saveDeviceData()"> Save </button>
|
||||
<button type="button" class="btn btn-default pull-right" style="min-width: 100px;" id="btnRestore" onclick="queryDeviceData(true)"> Restore </button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- tab page -------------------------------------------------------------- -->
|
||||
<div class="tab-pane fade table-responsive" id="panSessions">
|
||||
<table id="tableSessions" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order</th>
|
||||
<th>Connection</th>
|
||||
<th>Disconnection</th>
|
||||
<th>Duration</th>
|
||||
<th>IP</th>
|
||||
<th>Additional info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- tab page -------------------------------------------------------------- -->
|
||||
<div class="tab-pane fade table-responsive in active" id="panPresence" style="position: relative;">
|
||||
<!-- spinner -->
|
||||
<div id="loading" style="display: none">
|
||||
<div class="pa_semitransparent-panel"></div>
|
||||
<div class="panel panel-default pa_spinner">
|
||||
<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="calendar">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tab page -------------------------------------------------------------- -->
|
||||
<div class="tab-pane fade table-responsive" id="panEvents">
|
||||
|
||||
<div class="text-center">
|
||||
<label>
|
||||
<input class="checkbox" id="chkHideConnectionEvents" type="checkbox" checked>
|
||||
Hide Connection Events
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<table id="tableEvents" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Event type</th>
|
||||
<th>IP</th>
|
||||
<th>Additional info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.tab-content -->
|
||||
</div>
|
||||
<!-- nav-tabs-custom -->
|
||||
|
||||
<!--
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- iCkeck -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/plugins/iCheck/all.css">
|
||||
<script src="lib/AdminLTE/plugins/iCheck/icheck.min.js"></script>
|
||||
|
||||
<!-- Datatable -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||
|
||||
<!-- fullCalendar -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.min.css">
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.print.min.css" media="print">
|
||||
<script src="lib/AdminLTE/bower_components/moment/moment.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.min.js"></script>
|
||||
|
||||
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
var period = '';
|
||||
var mac = '';
|
||||
var skipRepeatedItems = ["0 h (notify all events)", "1 h", "8 h", "24 h", "168 h (one week)"];
|
||||
|
||||
// Initialize MAC
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has ('mac') == true) {
|
||||
mac = urlParams.get ('mac');
|
||||
} else {
|
||||
$('#pageTitle').html ('Device not found');
|
||||
}
|
||||
|
||||
// Initialize period
|
||||
if (urlParams.has ('period') == true) {
|
||||
document.getElementById('period').value = urlParams.get ('period');
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
$(function () {
|
||||
initializeiCheck();
|
||||
initializeAllCombos();
|
||||
initializeDatatable();
|
||||
initializeCalendar();
|
||||
|
||||
periodChanged();
|
||||
});
|
||||
|
||||
// Force re-render calendar on tab change (bugfix for render error at left panel)
|
||||
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (nav) {
|
||||
if ($(nav.target).attr('href') == '#panPresence') {
|
||||
$('#calendar').fullCalendar('rerenderEvents');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
$('input').on('ifToggled', function(event){
|
||||
if (event.currentTarget.id == 'chkHideConnectionEvents') {
|
||||
queryEvents();
|
||||
} else {
|
||||
activateSaveRestoreData();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
$(document).on('input', 'input:text', function() {
|
||||
activateSaveRestoreData();
|
||||
});
|
||||
|
||||
$(document).on('input', 'textarea', function() {
|
||||
activateSaveRestoreData();
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function periodChanged () {
|
||||
// Requery Device data
|
||||
queryDeviceData(true);
|
||||
querySessionsPresenceEvents();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeiCheck () {
|
||||
// Default
|
||||
$('input').iCheck({
|
||||
checkboxClass: 'icheckbox_flat-blue',
|
||||
radioClass: 'iradio_flat-blue',
|
||||
increaseArea: '20%'
|
||||
});
|
||||
|
||||
// // readonly
|
||||
// $('#panDetails input').iCheck({
|
||||
// checkboxClass: 'icheckbox_flat-blue',
|
||||
// radioClass: 'iradio_flat-blue',
|
||||
// increaseArea: '-100%'
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeAllCombos () {
|
||||
initializeCombo (document.getElementById("dropdownOwner"), 'queryOwners', 'txtOwner');
|
||||
initializeCombo (document.getElementById("dropdownDeviceType"), 'queryDeviceTypes', 'txtDeviceType');
|
||||
initializeCombo (document.getElementById("dropdownGroup"), 'queryGroups', 'txtGroup');
|
||||
initializeComboSkipRepeated ();
|
||||
}
|
||||
|
||||
function initializeCombo (HTMLelement, queryAction, txtDataField) {
|
||||
// get data from server
|
||||
$.get('php/server/devices.php?action='+queryAction, function(data) {
|
||||
var listData = JSON.parse(data);
|
||||
var order = 1;
|
||||
|
||||
HTMLelement.innerHTML = ""
|
||||
// for each item
|
||||
listData.forEach(function (item, index) {
|
||||
// insert line divisor
|
||||
if (order != item['order']) {
|
||||
HTMLelement.innerHTML += "<li class=\"divider\"></li>";
|
||||
order = item['order'];
|
||||
}
|
||||
|
||||
// add dropdown item
|
||||
HTMLelement.innerHTML +=
|
||||
" <li><a href=\"javascript:void(0)\" onclick=\"setTextValue('"+ txtDataField +"','"+ item['name'] +"')\">"
|
||||
+ item['name'] + "</a></li>"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function initializeComboSkipRepeated () {
|
||||
// find dropdown menu element
|
||||
HTMLelement = document.getElementById("dropdownSkipRepeated");
|
||||
HTMLelement.innerHTML = ""
|
||||
|
||||
// for each item
|
||||
skipRepeatedItems.forEach(function (item, index) {
|
||||
// add dropdown item
|
||||
HTMLelement.innerHTML += " <li><a href=\"javascript:void(0)\" " +
|
||||
" onclick=\"setTextValue('txtSkipRepeated','" + item + "');\">"+ item +"</a></li>";
|
||||
});
|
||||
}
|
||||
|
||||
function findSkipRepeated (value='0') {
|
||||
var itemSelected = skipRepeatedItems[0];
|
||||
|
||||
// for each item
|
||||
skipRepeatedItems.forEach(function (item, index) {
|
||||
if (item.split(" ")[0] == value) {
|
||||
itemSelected = item;
|
||||
}
|
||||
});
|
||||
return itemSelected;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeDatatable () {
|
||||
$('#tableSessions').DataTable({
|
||||
'paging' : true,
|
||||
'lengthChange': true,
|
||||
'searching' : true,
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
'order' : [[0,"desc"], [1,"desc"]],
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: [0]},
|
||||
|
||||
// Replace HTML codes
|
||||
{targets: [1,2,3,5],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html (translateHTMLcodes (cellData));
|
||||
} }
|
||||
],
|
||||
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
|
||||
emptyTable: 'No data'
|
||||
}
|
||||
});
|
||||
|
||||
$('#tableEvents').DataTable({
|
||||
'paging' : true,
|
||||
'lengthChange': true,
|
||||
'searching' : true,
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
'order' : [[0,"desc"]],
|
||||
|
||||
'columnDefs' : [
|
||||
// Replace HTML codes
|
||||
{targets: [0],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html (translateHTMLcodes (cellData));
|
||||
} }
|
||||
],
|
||||
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
|
||||
emptyTable: 'No data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeCalendar () {
|
||||
$('#calendar').fullCalendar({
|
||||
editable : false,
|
||||
droppable : false,
|
||||
defaultView : 'agendaMonth',
|
||||
|
||||
height : 'auto',
|
||||
firstDay : 1,
|
||||
allDaySlot : false,
|
||||
slotDuration : '02:00:00',
|
||||
slotLabelInterval : '04:00:00',
|
||||
slotLabelFormat : 'H:mm',
|
||||
timeFormat : 'H:mm',
|
||||
|
||||
header: {
|
||||
left : 'prev,next today',
|
||||
center : 'title',
|
||||
right : 'agendaYear,agendaMonth,agendaWeek'
|
||||
},
|
||||
|
||||
views: {
|
||||
agendaYear: {
|
||||
type : 'agenda',
|
||||
duration : { year: 1 },
|
||||
buttonText : 'year',
|
||||
columnHeaderFormat : ''
|
||||
},
|
||||
|
||||
agendaMonth: {
|
||||
type : 'agenda',
|
||||
duration : { month: 1 },
|
||||
buttonText : 'month',
|
||||
columnHeaderFormat : 'D'
|
||||
}
|
||||
},
|
||||
|
||||
viewRender: function(view) {
|
||||
if (view.name === 'agendaYear') {
|
||||
var listHeader = document.getElementsByClassName('fc-day-header');
|
||||
var listContent = document.getElementsByClassName('fc-widget-content');
|
||||
|
||||
for (i=0; i < listHeader.length-2 ; i++) {
|
||||
listHeader[i].style.borderColor = 'transparent';
|
||||
listContent[i+2].style.borderColor = 'transparent';
|
||||
|
||||
if (listHeader[i].innerHTML != '<span></span>') {
|
||||
if (i==0) {
|
||||
listHeader[i].style.borderLeftColor = '#808080';
|
||||
} else {
|
||||
listHeader[i-1].style.borderRightColor = '#808080';
|
||||
listContent[i+1].style.borderRightColor = '#808080';
|
||||
}
|
||||
listHeader[i].style.paddingLeft = '10px';
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
columnHeaderText: function(mom) {
|
||||
switch ($('#calendar').fullCalendar('getView').name) {
|
||||
case 'agendaYear':
|
||||
if (mom.date() == 1) {
|
||||
return mom.format('MMM');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
break;
|
||||
case 'agendaMonth':
|
||||
return mom.date();
|
||||
break;
|
||||
case 'agendaWeek':
|
||||
return mom.format ('ddd D');
|
||||
break;
|
||||
default:
|
||||
return mom.date();
|
||||
}
|
||||
},
|
||||
|
||||
eventRender: function (event, element) {
|
||||
$(element).tooltip({container: 'body', placement: 'right', title: event.tooltip});
|
||||
// element.attr ('title', event.tooltip); // Alternative tooltip
|
||||
},
|
||||
|
||||
loading: function( isLoading, view ) {
|
||||
if (isLoading) {
|
||||
$("#loading").show();
|
||||
} else {
|
||||
$("#loading").hide();
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryDeviceData (updatePanelData=false) {
|
||||
//debugTimer();
|
||||
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// period
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// get data from server
|
||||
$.get('php/server/devices.php?action=queryDeviceData&mac='+ mac +'&period='+ period, function(data) {
|
||||
var deviceData = JSON.parse(data);
|
||||
// check device exists
|
||||
if (deviceData['dev_MAC'] == null) {
|
||||
$('#pageTitle').html ('Device not found: <small>'+ mac +'</small>');
|
||||
return;
|
||||
}
|
||||
|
||||
// Name
|
||||
if (deviceData['dev_Owner'] == null || deviceData['dev_Owner'] == '' || (deviceData['dev_Name']).indexOf (deviceData['dev_Owner']) != -1 ) {
|
||||
$('#pageTitle').html (deviceData['dev_Name']);
|
||||
} else {
|
||||
$('#pageTitle').html (deviceData['dev_Name'] +' ('+ deviceData['dev_Owner'] +')');
|
||||
}
|
||||
|
||||
// Status
|
||||
$('#deviceStatus').html (deviceData['dev_Status']);
|
||||
switch (deviceData['dev_Status']) {
|
||||
case 'On-line':
|
||||
icon='fa fa-check';
|
||||
color='text-green';
|
||||
break;
|
||||
case 'Off-line':
|
||||
icon='fa fa-close';
|
||||
color='text-gray';
|
||||
break;
|
||||
case 'Down':
|
||||
icon='fa fa-warning';
|
||||
color='text-red';
|
||||
break;
|
||||
case null:
|
||||
$('#deviceStatus').html ('???');
|
||||
icon='fa fa-warning';
|
||||
color='text-red';
|
||||
break;
|
||||
default:
|
||||
icon='';
|
||||
color='';
|
||||
break;
|
||||
};
|
||||
document.getElementById('deviceStatus').className = color;
|
||||
document.getElementById('deviceStatusIcon').className = icon +' '+ color;
|
||||
|
||||
// Totals
|
||||
$('#deviceSessions').html (deviceData['dev_Sessions'].toLocaleString());
|
||||
$('#deviceDownAlerts').html (deviceData['dev_DownAlerts'].toLocaleString());
|
||||
|
||||
// Events - Presence (alwais presence)
|
||||
if (true) {
|
||||
$('#deviceEventsTitle').html ('Presence');
|
||||
$('#deviceEventsIcon').html ('<i class="fa fa-calendar">');
|
||||
if (deviceData['dev_PresenceHours'] == null) {
|
||||
$('#deviceEvents').html ('0 h.');
|
||||
} else {
|
||||
$('#deviceEvents').html (deviceData['dev_PresenceHours'].toLocaleString() +' h.');
|
||||
}
|
||||
} else {
|
||||
$('#deviceEventsTitle').html ('Events');
|
||||
$('#deviceEventsIcon').html ('<i class="fa fa-info-circle">');
|
||||
$('#deviceEvents').html (deviceData['dev_Events'].toLocaleString());
|
||||
};
|
||||
|
||||
// Device info
|
||||
if (updatePanelData) {
|
||||
document.getElementById('txtMAC').value = deviceData['dev_MAC'];
|
||||
document.getElementById('txtName').value = deviceData['dev_Name'];
|
||||
document.getElementById('txtOwner').value = deviceData['dev_Owner'];
|
||||
document.getElementById('txtDeviceType').value = deviceData['dev_DeviceType'];
|
||||
document.getElementById('txtVendor').value = deviceData['dev_Vendor'];
|
||||
if (deviceData['dev_Favorite'] == 1) {$('#chkFavorite').iCheck('check');}
|
||||
document.getElementById('txtGroup').value = deviceData['dev_Group'];
|
||||
document.getElementById('txtComments').value = deviceData['dev_Comments'];
|
||||
|
||||
document.getElementById('txtFirstConnection').value = deviceData['dev_FirstConnection'];
|
||||
document.getElementById('txtLastConnection').value = deviceData['dev_LastConnection'];
|
||||
document.getElementById('txtLastIP').value = deviceData['dev_LastIP'];
|
||||
document.getElementById('txtStatus').value = deviceData['dev_Status'];
|
||||
if (deviceData['dev_StaticIP'] == 1) {$('#chkStaticIP').iCheck('check');}
|
||||
|
||||
document.getElementById('txtScanCycle').value = deviceData['dev_ScanCycle'] +' min';
|
||||
// document.getElementById('chkAlertEvents').checked = deviceData['dev_AlertEvents'];
|
||||
// document.getElementById('chkAlertDown').checked = deviceData['dev_AlertDeviceDown'];
|
||||
if (deviceData['dev_AlertEvents'] == 1) {$('#chkAlertEvents').iCheck('check');}
|
||||
if (deviceData['dev_AlertDeviceDown'] == 1) {$('#chkAlertDown').iCheck('check');}
|
||||
|
||||
document.getElementById('txtSkipRepeated').value = findSkipRepeated (deviceData['dev_SkipRepeated']);
|
||||
deactivateSaveRestoreData ();
|
||||
}
|
||||
|
||||
// Timer for refresh data
|
||||
newTimerRefreshData (queryDeviceData);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function querySessionsPresenceEvents () {
|
||||
//$.get('php/server/events.php?action=devicePresence&end=2019-06-30&start=2019-06-01&mac='+ mac +'&period='+ period, function(data) {
|
||||
//alert (data)
|
||||
//});
|
||||
|
||||
|
||||
// Define new datasource URL and reload
|
||||
$('#tableSessions').DataTable().ajax.url('php/server/events.php?action=deviceSessions&mac=' + mac +'&period='+ period).load();
|
||||
|
||||
$('#calendar').fullCalendar('removeEventSources');
|
||||
$('#calendar').fullCalendar('addEventSource', { url: 'php/server/events.php?action=devicePresence&mac=' + mac +'&period='+ period });
|
||||
|
||||
queryEvents();
|
||||
}
|
||||
|
||||
function queryEvents () {
|
||||
hideConnections = document.getElementById('chkHideConnectionEvents').checked;
|
||||
$('#tableEvents').DataTable().ajax.url('php/server/events.php?action=deviceEvents&mac=' + mac +'&period='+ period +'&hideConnections='+ hideConnections).load();
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function activateSaveRestoreData () {
|
||||
document.getElementById("btnRestore").removeAttribute ('disabled');
|
||||
document.getElementById("btnSave").removeAttribute ('disabled');
|
||||
}
|
||||
|
||||
|
||||
function deactivateSaveRestoreData () {
|
||||
// document.getElementById("btnRestore").setAttribute ('disabled','');
|
||||
document.getElementById("btnSave").setAttribute ('disabled','');
|
||||
// document.getElementById("btnRestore").classList.add ('disabled');
|
||||
// document.getElementById("btnSave").classList.add ('disabled');
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function setTextValue (textElement, textValue) {
|
||||
document.getElementById(textElement).value = textValue;
|
||||
activateSaveRestoreData ();
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function saveDeviceData () {
|
||||
// Check MAC
|
||||
if (mac == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// update data to server
|
||||
$.get('php/server/devices.php?action=updateData&mac='+ mac
|
||||
+ '&name=' + document.getElementById('txtName').value
|
||||
+ '&owner=' + document.getElementById('txtOwner').value
|
||||
+ '&type=' + document.getElementById('txtDeviceType').value
|
||||
+ '&vendor=' + document.getElementById('txtVendor').value
|
||||
+ '&favorite=' + (document.getElementById('chkFavorite').checked * 1)
|
||||
+ '&group=' + document.getElementById('txtGroup').value
|
||||
+ '&comments=' + document.getElementById('txtComments').value
|
||||
+ '&staticIP=' + (document.getElementById('chkStaticIP').checked * 1)
|
||||
+ '&scancycle=' + document.getElementById('txtScanCycle').value.split(" ")[0]
|
||||
+ '&alertevents=' + (document.getElementById('chkAlertEvents').checked * 1)
|
||||
+ '&alertdown=' + (document.getElementById('chkAlertDown').checked * 1)
|
||||
+ '&skiprepeated=' + document.getElementById('txtSkipRepeated').value.split(" ")[0]
|
||||
, function(data) {
|
||||
|
||||
deactivateSaveRestoreData ();
|
||||
|
||||
// show return message
|
||||
alert (data)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
339
front/devices.php
Normal file
339
front/devices.php
Normal file
@@ -0,0 +1,339 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
Devices
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb text-gray50">
|
||||
New Devices period:
|
||||
<select id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day">Today</option>
|
||||
<option value="7 days">Last Week</option>
|
||||
<option value="1 month" selected>Last Month</option>
|
||||
<option value="1 year">Last Year</option>
|
||||
<option value="100 years">All info</option>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('all');">
|
||||
<div class="small-box bg-aqua pa-small-box-aqua">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Total Devices</h4>
|
||||
<h3 id="devicesAll"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-laptop"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('connected');">
|
||||
<div class="small-box bg-green pa-small-box-green">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Connected</h4>
|
||||
<h3 id="devicesConnected"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-plug"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('new');">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow">
|
||||
<div class="inner">
|
||||
|
||||
<h4>New Devices</h4>
|
||||
<h3 id="devicesNew"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-plus-round"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('down');">
|
||||
<div class="small-box bg-red pa-small-box-red">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Down Alerts</h4>
|
||||
<h3 id="devicesDown"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-warning"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- datatable ------------------------------------------------------------- -->
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div id="tableDevicesBox" class="box">
|
||||
<div class="box-header">
|
||||
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body table-responsive">
|
||||
<table id="tableDevices" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Owner</th>
|
||||
<th>Device type</th>
|
||||
<th>Favorite</th>
|
||||
<th>Group</th>
|
||||
<th>First Session</th>
|
||||
<th>Last Session</th>
|
||||
<th>Last IP</th>
|
||||
<th>Status</th>
|
||||
<th>MAC</th>
|
||||
<th>Last IP Order</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Datatable -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||
|
||||
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
var deviceStatus = '';
|
||||
var period = '';
|
||||
|
||||
// Initialize MAC
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has ('status') == true) {
|
||||
deviceStatus = urlParams.get ('status');
|
||||
} else {
|
||||
deviceStatus = 'all';
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
$(function () {
|
||||
initializeDatatable();
|
||||
periodChanged();
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function periodChanged () {
|
||||
// Requery totals and list
|
||||
queryTotals();
|
||||
queryList (deviceStatus);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeDatatable () {
|
||||
$('#tableDevices').DataTable({
|
||||
'paging' : true,
|
||||
'lengthChange': true,
|
||||
'searching' : true,
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
'order' : [[3,"desc"], [0,"asc"]],
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: [9, 10] },
|
||||
{className: 'text-center', targets: [3, 8] },
|
||||
{width: '0px', targets: 8 },
|
||||
{orderData: [10], targets: 7 },
|
||||
|
||||
// Device Name
|
||||
{targets: [0],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Favorite
|
||||
{targets: [3],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData == 1){
|
||||
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
|
||||
// Dates
|
||||
{targets: [5, 6],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html (translateHTMLcodes (cellData));
|
||||
} },
|
||||
|
||||
// Status color
|
||||
{targets: [8],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
switch (cellData) {
|
||||
case 'Down':
|
||||
color='red'; break;
|
||||
case 'New':
|
||||
color='yellow'; break;
|
||||
case 'On-line':
|
||||
color='green'; break;
|
||||
case 'Off-line':
|
||||
color='gray text-white'; break;
|
||||
default:
|
||||
color='aqua'; break;
|
||||
};
|
||||
|
||||
$(td).html ('<a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="badge bg-'+ color +'">'+ cellData +'</a>');
|
||||
} },
|
||||
],
|
||||
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
|
||||
emptyTable: 'No data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryTotals () {
|
||||
// debugTimer();
|
||||
|
||||
// stop timer
|
||||
stopTimerRefreshData();
|
||||
|
||||
// period
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// get totals and put in boxes
|
||||
$.get('php/server/devices.php?action=totals&period='+ period, function(data) {
|
||||
var totalsDevices = JSON.parse(data);
|
||||
|
||||
$('#devicesAll').html (totalsDevices[0].toLocaleString());
|
||||
$('#devicesConnected').html (totalsDevices[1].toLocaleString());
|
||||
$('#devicesNew').html (totalsDevices[2].toLocaleString());
|
||||
$('#devicesDown').html (totalsDevices[3].toLocaleString());
|
||||
});
|
||||
|
||||
// Timer for refresh data
|
||||
newTimerRefreshData (queryTotals);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryList (status) {
|
||||
// Save status and period selected
|
||||
deviceStatus = status;
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// Defini color & title for the status selected
|
||||
switch (deviceStatus) {
|
||||
case 'all':
|
||||
tableTitle = 'Total Devices';
|
||||
color = 'aqua';
|
||||
break;
|
||||
case 'connected':
|
||||
tableTitle = 'Connected Devices';
|
||||
color = 'green';
|
||||
break;
|
||||
case 'new':
|
||||
tableTitle = 'New Devices';
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 'down':
|
||||
tableTitle = 'Down Alerts';
|
||||
color = 'red';
|
||||
break;
|
||||
case 'favorites':
|
||||
tableTitle = 'Favorites';
|
||||
color = 'yellow';
|
||||
break;
|
||||
default:
|
||||
tableTitle = 'Devices';
|
||||
boxClass = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
document.getElementById('tableDevicesTitle').className = 'box-title text-' + color;
|
||||
document.getElementById('tableDevicesBox').className = 'box box-' + color;
|
||||
$('#tableDevicesTitle').html (tableTitle);
|
||||
|
||||
// Define new datasource URL and reload
|
||||
$('#tableDevices').DataTable().ajax.url('php/server/devices.php?action=list&status=' + deviceStatus +'&period='+ period ).load();
|
||||
};
|
||||
|
||||
</script>
|
||||
366
front/events.php
Normal file
366
front/events.php
Normal file
@@ -0,0 +1,366 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
Events
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb text-gray50">
|
||||
Events period:
|
||||
<select id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day">Today</option>
|
||||
<option value="7 days">Last Week</option>
|
||||
<option value="1 month" selected>Last Month</option>
|
||||
<option value="1 year">Last Year</option>
|
||||
<option value="100 years">All info</option>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-2 col-sm-4 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('all');">
|
||||
<div class="small-box bg-aqua pa-small-box-aqua pa-small-box-2">
|
||||
<div class="inner">
|
||||
|
||||
<h3 id="eventsAll"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-bolt text-aqua-20"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
All events <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-2 col-sm-4 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('sessions');">
|
||||
<div class="small-box bg-green pa-small-box-green pa-small-box-2">
|
||||
<div class="inner">
|
||||
|
||||
<h3 id="eventsSessions"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-plug text-green-20"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Sessions <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-2 col-sm-4 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('missing');">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2">
|
||||
<div class="inner">
|
||||
|
||||
<h3 id="eventsMissing"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-exchange text-yellow-20"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Missing Sessions <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-2 col-sm-4 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('voided');">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2">
|
||||
<div class="inner">
|
||||
|
||||
<h3 id="eventsVoided"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon text-aqua-20">
|
||||
<i class="fa fa-exclamation-circle text-yellow-20"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Voided Sessions <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-2 col-sm-4 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('new');">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow pa-small-box-2">
|
||||
<div class="inner">
|
||||
|
||||
<h3 id="eventsNewDevices"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-plus-round text-yellow-20"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
New Devices <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-2 col-sm-4 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('down');">
|
||||
<div class="small-box bg-red pa-small-box-red pa-small-box-2">
|
||||
<div class="inner">
|
||||
|
||||
<h3 id="eventsDown"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-warning text-red-20"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Down Alerts <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- datatable ------------------------------------------------------------- -->
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div id="tableEventsBox" class="box">
|
||||
<div class="box-header">
|
||||
<h3 id="tableEventsTitle" class="box-title text-gray">Events</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body table-responsive">
|
||||
<table id="tableEvents" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order</th>
|
||||
<th>Device</th>
|
||||
<th>Owner</th>
|
||||
<th>Date</th>
|
||||
<th>Event Type</th>
|
||||
<th>Connection</th>
|
||||
<th>Disconnection</th>
|
||||
<th>Duration</th>
|
||||
<th>Duration Order</th>
|
||||
<th>IP</th>
|
||||
<th>IP Order</th>
|
||||
<th>Additional Info</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Datatable -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||
|
||||
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
var eventsType = '';
|
||||
var period = '';
|
||||
|
||||
// Initialize MAC
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has ('status') == true) {
|
||||
eventsType = urlParams.get ('type');
|
||||
} else {
|
||||
eventsType = 'all';
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
$(function () {
|
||||
initializeDatatable();
|
||||
periodChanged();
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function periodChanged () {
|
||||
// Requery totals and list
|
||||
queryTotals();
|
||||
queryList (eventsType);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeDatatable () {
|
||||
$('#tableEvents').DataTable({
|
||||
'paging' : true,
|
||||
'lengthChange': true,
|
||||
'searching' : true,
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
'order' : [[0,"desc"], [3,"desc"], [5,"desc"]],
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: [0,5,6,7,8,10] },
|
||||
{className: 'text-center', targets: [] },
|
||||
{orderData: [8], targets: 7 },
|
||||
{orderData: [10], targets: 9 },
|
||||
|
||||
// Device Name
|
||||
{targets: [1],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[13]+ '&period='+ period +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Replace HTML codes
|
||||
{targets: [3,4,5,6,7],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html (translateHTMLcodes (cellData));
|
||||
} }
|
||||
],
|
||||
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
|
||||
emptyTable: 'No data'
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryTotals () {
|
||||
// debugTimer();
|
||||
// stop timer
|
||||
stopTimerRefreshData();
|
||||
|
||||
// period
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// get totals and put in boxes
|
||||
$.get('php/server/events.php?action=totals&period='+ period, function(data) {
|
||||
var totalsEvents = JSON.parse(data);
|
||||
|
||||
$('#eventsAll').html (totalsEvents[0].toLocaleString());
|
||||
$('#eventsSessions').html (totalsEvents[1].toLocaleString());
|
||||
$('#eventsMissing').html (totalsEvents[2].toLocaleString());
|
||||
$('#eventsVoided').html (totalsEvents[3].toLocaleString());
|
||||
$('#eventsNewDevices').html (totalsEvents[4].toLocaleString());
|
||||
$('#eventsDown').html (totalsEvents[5].toLocaleString());
|
||||
});
|
||||
|
||||
// Timer for refresh data
|
||||
newTimerRefreshData (queryTotals);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryList (p_eventsType) {
|
||||
// Save status and period selected
|
||||
eventsType = p_eventsType;
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// Define color & title for the status selected
|
||||
sesionCols = false;
|
||||
switch (eventsType) {
|
||||
case 'all':
|
||||
tableTitle = 'All Events';
|
||||
color = 'aqua';
|
||||
break;
|
||||
case 'sessions':
|
||||
tableTitle = 'Sessions';
|
||||
color = 'green';
|
||||
sesionCols = true;
|
||||
break;
|
||||
case 'missing':
|
||||
tableTitle = 'Missing Events';
|
||||
color = 'yellow';
|
||||
sesionCols = true;
|
||||
break;
|
||||
case 'voided':
|
||||
tableTitle = 'Voided Events';
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 'new':
|
||||
tableTitle = 'New Devices Events';
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 'down':
|
||||
tableTitle = 'Down Alerts';
|
||||
color = 'red';
|
||||
break;
|
||||
default:
|
||||
tableTitle = 'Events';
|
||||
boxClass = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
document.getElementById('tableEventsTitle').className = 'box-title text-' + color;
|
||||
document.getElementById('tableEventsBox').className = 'box box-' + color;
|
||||
$('#tableEventsTitle').html (tableTitle);
|
||||
|
||||
// Coluumns Visibility
|
||||
$('#tableEvents').DataTable().column(3).visible (!sesionCols);
|
||||
$('#tableEvents').DataTable().column(4).visible (!sesionCols);
|
||||
$('#tableEvents').DataTable().column(5).visible (sesionCols);
|
||||
$('#tableEvents').DataTable().column(6).visible (sesionCols);
|
||||
$('#tableEvents').DataTable().column(7).visible (sesionCols);
|
||||
|
||||
// Define new datasource URL and reload
|
||||
$('#tableEvents').DataTable().clear();
|
||||
$('#tableEvents').DataTable().draw();
|
||||
$('#tableEvents').DataTable().order ([0,"desc"], [3,"desc"], [5,"desc"]);
|
||||
$('#tableEvents').DataTable().ajax.url('php/server/events.php?action=list&type=' + eventsType +'&period='+ period ).load();
|
||||
};
|
||||
|
||||
</script>
|
||||
BIN
front/img/backgroud.png
Normal file
BIN
front/img/backgroud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 139 KiB |
BIN
front/img/pialertLogoBlack.png
Normal file
BIN
front/img/pialertLogoBlack.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
BIN
front/img/pialertLogoGray50.png
Normal file
BIN
front/img/pialertLogoGray50.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
front/img/pialertLogoGray80.png
Normal file
BIN
front/img/pialertLogoGray80.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
BIN
front/img/pialertLogoOrange.png
Normal file
BIN
front/img/pialertLogoOrange.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
BIN
front/img/pialertLogoWhite.png
Normal file
BIN
front/img/pialertLogoWhite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
339
front/index.php
Normal file
339
front/index.php
Normal file
@@ -0,0 +1,339 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
Devices
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb text-gray50">
|
||||
New Devices period:
|
||||
<select id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day">Today</option>
|
||||
<option value="7 days">Last Week</option>
|
||||
<option value="1 month" selected>Last Month</option>
|
||||
<option value="1 year">Last Year</option>
|
||||
<option value="100 years">All info</option>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('all');">
|
||||
<div class="small-box bg-aqua pa-small-box-aqua">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Total Devices</h4>
|
||||
<h3 id="devicesAll"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-laptop"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('connected');">
|
||||
<div class="small-box bg-green pa-small-box-green">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Connected</h4>
|
||||
<h3 id="devicesConnected"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-plug"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('new');">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow">
|
||||
<div class="inner">
|
||||
|
||||
<h4>New Devices</h4>
|
||||
<h3 id="devicesNew"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-plus-round"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryList('down');">
|
||||
<div class="small-box bg-red pa-small-box-red">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Down Alerts</h4>
|
||||
<h3 id="devicesDown"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-warning"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- datatable ------------------------------------------------------------- -->
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div id="tableDevicesBox" class="box">
|
||||
<div class="box-header">
|
||||
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body table-responsive">
|
||||
<table id="tableDevices" class="table table-bordered table-hover table-striped ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Owner</th>
|
||||
<th>Device type</th>
|
||||
<th>Favorite</th>
|
||||
<th>Group</th>
|
||||
<th>First Session</th>
|
||||
<th>Last Session</th>
|
||||
<th>Last IP</th>
|
||||
<th>Status</th>
|
||||
<th>MAC</th>
|
||||
<th>Last IP Order</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- Datatable -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||
|
||||
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
var deviceStatus = '';
|
||||
var period = '';
|
||||
|
||||
// Initialize MAC
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has ('status') == true) {
|
||||
deviceStatus = urlParams.get ('status');
|
||||
} else {
|
||||
deviceStatus = 'all';
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
$(function () {
|
||||
initializeDatatable();
|
||||
periodChanged();
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function periodChanged () {
|
||||
// Requery totals and list
|
||||
queryTotals();
|
||||
queryList (deviceStatus);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeDatatable () {
|
||||
$('#tableDevices').DataTable({
|
||||
'paging' : true,
|
||||
'lengthChange': true,
|
||||
'searching' : true,
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
'order' : [[3,"desc"], [0,"asc"]],
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: [9, 10] },
|
||||
{className: 'text-center', targets: [3, 8] },
|
||||
{width: '0px', targets: 8 },
|
||||
{orderData: [10], targets: 7 },
|
||||
|
||||
// Device Name
|
||||
{targets: [0],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Favorite
|
||||
{targets: [3],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData == 1){
|
||||
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
|
||||
// Dates
|
||||
{targets: [5, 6],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
$(td).html (translateHTMLcodes (cellData));
|
||||
} },
|
||||
|
||||
// Status color
|
||||
{targets: [8],
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
switch (cellData) {
|
||||
case 'Down':
|
||||
color='red'; break;
|
||||
case 'New':
|
||||
color='yellow'; break;
|
||||
case 'On-line':
|
||||
color='green'; break;
|
||||
case 'Off-line':
|
||||
color='gray text-white'; break;
|
||||
default:
|
||||
color='aqua'; break;
|
||||
};
|
||||
|
||||
$(td).html ('<a href="deviceDetails.php?mac='+ rowData[9]+ '&period='+ period +'" class="badge bg-'+ color +'">'+ cellData +'</a>');
|
||||
} },
|
||||
],
|
||||
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
processing: '<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>',
|
||||
emptyTable: 'No data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryTotals () {
|
||||
// debugTimer();
|
||||
|
||||
// stop timer
|
||||
stopTimerRefreshData();
|
||||
|
||||
// period
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// get totals and put in boxes
|
||||
$.get('php/server/devices.php?action=totals&period='+ period, function(data) {
|
||||
var totalsDevices = JSON.parse(data);
|
||||
|
||||
$('#devicesAll').html (totalsDevices[0].toLocaleString());
|
||||
$('#devicesConnected').html (totalsDevices[1].toLocaleString());
|
||||
$('#devicesNew').html (totalsDevices[2].toLocaleString());
|
||||
$('#devicesDown').html (totalsDevices[3].toLocaleString());
|
||||
});
|
||||
|
||||
// Timer for refresh data
|
||||
newTimerRefreshData (queryTotals);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryList (status) {
|
||||
// Save status and period selected
|
||||
deviceStatus = status;
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// Defini color & title for the status selected
|
||||
switch (deviceStatus) {
|
||||
case 'all':
|
||||
tableTitle = 'Total Devices';
|
||||
color = 'aqua';
|
||||
break;
|
||||
case 'connected':
|
||||
tableTitle = 'Connected Devices';
|
||||
color = 'green';
|
||||
break;
|
||||
case 'new':
|
||||
tableTitle = 'New Devices';
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 'down':
|
||||
tableTitle = 'Down Alerts';
|
||||
color = 'red';
|
||||
break;
|
||||
case 'favorites':
|
||||
tableTitle = 'Favorites';
|
||||
color = 'yellow';
|
||||
break;
|
||||
default:
|
||||
tableTitle = 'Devices';
|
||||
boxClass = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
document.getElementById('tableDevicesTitle').className = 'box-title text-' + color;
|
||||
document.getElementById('tableDevicesBox').className = 'box box-' + color;
|
||||
$('#tableDevicesTitle').html (tableTitle);
|
||||
|
||||
// Define new datasource URL and reload
|
||||
$('#tableDevices').DataTable().ajax.url('php/server/devices.php?action=list&status=' + deviceStatus +'&period='+ period ).load();
|
||||
};
|
||||
|
||||
</script>
|
||||
39
front/js/pialert_common.js
Normal file
39
front/js/pialert_common.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Pi.Alert Common Javascript functions
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
var timerRefreshData = ''
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function translateHTMLcodes (text) {
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
var text2 = text.replace(new RegExp(' ', 'g'), " ");
|
||||
text2 = text2.replace(new RegExp('<', 'g'), "<");
|
||||
return text2;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function stopTimerRefreshData () {
|
||||
try {
|
||||
clearTimeout (timerRefreshData);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function newTimerRefreshData (refeshFunction) {
|
||||
timerRefreshData = setTimeout (function() {
|
||||
refeshFunction();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function debugTimer () {
|
||||
document.getElementById ('pageTitle').innerHTML = (new Date().getSeconds());
|
||||
}
|
||||
52
front/php/server/db.php
Normal file
52
front/php/server/db.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
//------------------------------------------------------------------------------
|
||||
// PHP Open DB
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// DB File Path
|
||||
$DBFILE = 'pialert.db';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Connect DB
|
||||
//------------------------------------------------------------------------------
|
||||
function SQLite3_connect ($trytoreconnect) {
|
||||
global $DBFILE;
|
||||
try
|
||||
{
|
||||
// connect to database
|
||||
// return new SQLite3($DBFILE, SQLITE3_OPEN_READONLY);
|
||||
return new SQLite3($DBFILE, SQLITE3_OPEN_READWRITE);
|
||||
}
|
||||
catch (Exception $exception)
|
||||
{
|
||||
// sqlite3 throws an exception when it is unable to connect
|
||||
// try to reconnect one time after 3 seconds
|
||||
if($trytoreconnect)
|
||||
{
|
||||
sleep(3);
|
||||
return SQLite3_connect(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Open DB
|
||||
//------------------------------------------------------------------------------
|
||||
function OpenDB () {
|
||||
global $DBFILE;
|
||||
global $db;
|
||||
|
||||
if(strlen($DBFILE) == 0)
|
||||
{
|
||||
die ('No database available');
|
||||
}
|
||||
|
||||
$db = SQLite3_connect(true);
|
||||
if(!$db)
|
||||
{
|
||||
die ('Error connecting to database');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
377
front/php/server/devices.php
Normal file
377
front/php/server/devices.php
Normal file
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
|
||||
// External files
|
||||
require 'db.php';
|
||||
require 'util.php';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action selector
|
||||
//------------------------------------------------------------------------------
|
||||
// Set maximum execution time to 1 minute
|
||||
ini_set ('max_execution_time','60');
|
||||
|
||||
// Open DB
|
||||
OpenDB();
|
||||
|
||||
// Action functions
|
||||
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
|
||||
$action = $_REQUEST['action'];
|
||||
switch ($action) {
|
||||
case 'totals': queryTotals(); break;
|
||||
case 'list': queryList(); break;
|
||||
case 'queryDeviceData': queryDeviceData(); break;
|
||||
case 'updateData': updateDeviceData(); break;
|
||||
case 'calendar': queryCalendarList(); break;
|
||||
case 'queryOwners': queryOwners(); break;
|
||||
case 'queryDeviceTypes': queryDeviceTypes(); break;
|
||||
case 'queryGroups': queryGroups(); break;
|
||||
default: logServerConsole ('Action: '. $action); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query total numbers of Devices by status
|
||||
//------------------------------------------------------------------------------
|
||||
function queryTotals() {
|
||||
global $db;
|
||||
|
||||
// All
|
||||
$result = $db->query('SELECT COUNT(*) FROM Devices ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$devices = $row[0];
|
||||
|
||||
// Connected
|
||||
$result = $db->query('SELECT COUNT(*) FROM Devices ' . getDeviceCondition ('connected') );
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$connected = $row[0];
|
||||
|
||||
// New
|
||||
$result = $db->query('SELECT COUNT(*) FROM Devices ' . getDeviceCondition ('new') );
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$newDevices = $row[0];
|
||||
|
||||
// Down Alerts
|
||||
$result = $db->query('SELECT COUNT(*) FROM Devices ' . getDeviceCondition ('down'));
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$devicesDownAlert = $row[0];
|
||||
|
||||
echo (json_encode (array ($devices, $connected, $newDevices, $devicesDownAlert)));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of devices in a determined Status
|
||||
//------------------------------------------------------------------------------
|
||||
function queryList() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
// SQL
|
||||
$condition = getDeviceCondition ($_REQUEST['status']);
|
||||
|
||||
$result = $db->query('SELECT *,
|
||||
CASE WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down"
|
||||
WHEN dev_FirstConnection >= ' . $periodDate . ' THEN "New"
|
||||
WHEN dev_PresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line"
|
||||
END AS dev_Status
|
||||
FROM Devices ' . $condition);
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$tableData['data'][] = array ($row['dev_Name'],
|
||||
$row['dev_Owner'],
|
||||
$row['dev_DeviceType'],
|
||||
$row['dev_Favorite'],
|
||||
$row['dev_Group'],
|
||||
formatDate ($row['dev_FirstConnection']),
|
||||
formatDate ($row['dev_LastConnection']),
|
||||
$row['dev_LastIP'],
|
||||
$row['dev_Status'],
|
||||
$row['dev_MAC'], // MAC (hidden)
|
||||
formatIPlong ($row['dev_LastIP']) // IP orderable
|
||||
);
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
if (empty($tableData['data'])) {
|
||||
$tableData['data'] = '';
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of Owners
|
||||
//------------------------------------------------------------------------------
|
||||
function queryOwners() {
|
||||
global $db;
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT DISTINCT 1 as dev_Order, dev_Owner
|
||||
FROM Devices
|
||||
WHERE dev_Owner <> "(unknown)" AND dev_Owner <> ""
|
||||
AND dev_Favorite = 1
|
||||
UNION
|
||||
SELECT DISTINCT 2 as dev_Order, dev_Owner
|
||||
FROM Devices
|
||||
WHERE dev_Owner <> "(unknown)" AND dev_Owner <> ""
|
||||
AND dev_Favorite = 0
|
||||
AND dev_Owner NOT IN (SELECT dev_Owner FROM Devices WHERE dev_Favorite = 1)
|
||||
ORDER BY 1,2 ');
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$tableData[] = array ('order' => $row['dev_Order'],
|
||||
'name' => $row['dev_Owner']);
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of types
|
||||
//------------------------------------------------------------------------------
|
||||
function queryDeviceTypes() {
|
||||
global $db;
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT DISTINCT 9 as dev_Order, dev_DeviceType
|
||||
FROM Devices
|
||||
WHERE dev_DeviceType NOT IN ("",
|
||||
"Smartphone", "Tablet",
|
||||
"Laptop", "Mini PC", "PC", "Printer", "Server",
|
||||
"Game Console", "SmartTV", "TV Decoder", "Virtual Assistance",
|
||||
"Clock", "House Appliance", "Phone", "Radio",
|
||||
"AP", "NAS", "PLC", "Router")
|
||||
|
||||
UNION SELECT 1 as dev_Order, "Smartphone"
|
||||
UNION SELECT 1 as dev_Order, "Tablet"
|
||||
|
||||
UNION SELECT 2 as dev_Order, "Laptop"
|
||||
UNION SELECT 2 as dev_Order, "Mini PC"
|
||||
UNION SELECT 2 as dev_Order, "PC"
|
||||
UNION SELECT 2 as dev_Order, "Printer"
|
||||
UNION SELECT 2 as dev_Order, "Server"
|
||||
|
||||
UNION SELECT 3 as dev_Order, "Game Console"
|
||||
UNION SELECT 3 as dev_Order, "SmartTV"
|
||||
UNION SELECT 3 as dev_Order, "TV Decoder"
|
||||
UNION SELECT 3 as dev_Order, "Virtual Assistance"
|
||||
|
||||
UNION SELECT 4 as dev_Order, "Clock"
|
||||
UNION SELECT 4 as dev_Order, "House Appliance"
|
||||
UNION SELECT 4 as dev_Order, "Phone"
|
||||
UNION SELECT 4 as dev_Order, "Radio"
|
||||
|
||||
UNION SELECT 5 as dev_Order, "AP"
|
||||
UNION SELECT 5 as dev_Order, "NAS"
|
||||
UNION SELECT 5 as dev_Order, "PLC"
|
||||
UNION SELECT 5 as dev_Order, "Router"
|
||||
|
||||
UNION SELECT 10 as dev_Order, "Other"
|
||||
|
||||
ORDER BY 1,2 ');
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$tableData[] = array ('order' => $row['dev_Order'],
|
||||
'name' => $row['dev_DeviceType']);
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of groups
|
||||
//------------------------------------------------------------------------------
|
||||
function queryGroups() {
|
||||
global $db;
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT DISTINCT 1 as dev_Order, dev_Group
|
||||
FROM Devices
|
||||
WHERE dev_Group <> "(unknown)" AND dev_Group <> "Others" AND dev_Group <> ""
|
||||
UNION SELECT 1 as dev_Order, "Always on"
|
||||
UNION SELECT 1 as dev_Order, "Friends"
|
||||
UNION SELECT 1 as dev_Order, "Personal"
|
||||
UNION SELECT 2 as dev_Order, "Others"
|
||||
ORDER BY 1,2 ');
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$tableData[] = array ('order' => $row['dev_Order'],
|
||||
'name' => $row['dev_Group']);
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of devices for calendar
|
||||
//------------------------------------------------------------------------------
|
||||
function queryCalendarList() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
// SQL
|
||||
$condition = getDeviceCondition ($_REQUEST['status']);
|
||||
$result = $db->query('SELECT * FROM Devices ' . $condition);
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
if ($row['dev_Favorite'] == 1) {
|
||||
$row['dev_Name'] = '<span class="text-yellow">★</span> '. $row['dev_Name'];
|
||||
}
|
||||
|
||||
$tableData[] = array ('id' => $row['dev_MAC'],
|
||||
'title' => $row['dev_Name'],
|
||||
'favorite' => $row['dev_Favorite']);
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query Device Data
|
||||
//------------------------------------------------------------------------------
|
||||
function queryDeviceData() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$periodDate = getDateFromPeriod();
|
||||
$mac = $_REQUEST['mac'];
|
||||
|
||||
// Device Data
|
||||
$result = $db->query('SELECT *,
|
||||
CASE WHEN dev_AlertDeviceDown=1 AND dev_PresentLastScan=0 THEN "Down"
|
||||
WHEN dev_PresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line" END as dev_Status
|
||||
FROM Devices
|
||||
WHERE dev_MAC="' . $mac .'"');
|
||||
|
||||
$row = $result -> fetchArray (SQLITE3_ASSOC);
|
||||
$deviceData = $row;
|
||||
$deviceData['dev_FirstConnection'] = formatDate ($row['dev_FirstConnection']); // Date formated
|
||||
$deviceData['dev_LastConnection'] = formatDate ($row['dev_LastConnection']); // Date formated
|
||||
|
||||
// Count Totals
|
||||
$condicion = ' WHERE eve_MAC="' . $mac .'" AND eve_DateTime >= ' . $periodDate;
|
||||
|
||||
// Connections
|
||||
$result = $db->query('SELECT COUNT(*) FROM Sessions
|
||||
WHERE ses_MAC="' . $mac .'"
|
||||
AND ( ses_DateTimeConnection >= ' . $periodDate . '
|
||||
OR ses_DateTimeDisconnection >= ' . $periodDate . '
|
||||
OR ses_StillConnected = 1 ) ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_Sessions'] = $row[0];
|
||||
|
||||
// Events
|
||||
$result = $db->query('SELECT COUNT(*) FROM Events ' . $condicion . ' AND eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_Events'] = $row[0];
|
||||
|
||||
// Donw Alerts
|
||||
$result = $db->query('SELECT COUNT(*) FROM Events ' . $condicion . ' AND eve_EventType = "Device Down"');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_DownAlerts'] = $row[0];
|
||||
|
||||
// Presence hours
|
||||
$result = $db->query('SELECT SUM (julianday (IFNULL (ses_DateTimeDisconnection, DATETIME("now")))
|
||||
- julianday (CASE WHEN ses_DateTimeConnection < ' . $periodDate . ' THEN ' . $periodDate . '
|
||||
ELSE ses_DateTimeConnection END)) *24
|
||||
FROM Sessions
|
||||
WHERE ses_MAC="' . $mac .'"
|
||||
AND ses_DateTimeConnection IS NOT NULL
|
||||
AND (ses_DateTimeDisconnection IS NOT NULL OR ses_StillConnected = 1 )
|
||||
AND ( ses_DateTimeConnection >= ' . $periodDate . '
|
||||
OR ses_DateTimeDisconnection >= ' . $periodDate . '
|
||||
OR ses_StillConnected = 1 ) ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_PresenceHours'] = round ($row[0]);
|
||||
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($deviceData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Status Where conditions
|
||||
//------------------------------------------------------------------------------
|
||||
function getDeviceCondition ($deviceStatus) {
|
||||
// Request Parameters
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
switch ($deviceStatus) {
|
||||
case 'all':
|
||||
return '';
|
||||
case 'connected':
|
||||
return 'WHERE dev_PresentLastScan=1';
|
||||
case 'new':
|
||||
return 'WHERE dev_FirstConnection >= ' . $periodDate;
|
||||
case 'down':
|
||||
return 'WHERE dev_AlertDeviceDown=1 AND dev_PresentLastScan=0';
|
||||
case 'favorites':
|
||||
return 'WHERE dev_Favorite=1';
|
||||
default:
|
||||
return 'WHERE 1=0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Update Device Data
|
||||
//------------------------------------------------------------------------------
|
||||
function updateDeviceData() {
|
||||
global $db;
|
||||
|
||||
// sql
|
||||
$sql = 'UPDATE Devices SET
|
||||
dev_Name = "'. $_REQUEST['name'] .'",
|
||||
dev_Owner = "'. $_REQUEST['owner'] .'",
|
||||
dev_DeviceType = "'. $_REQUEST['type'] .'",
|
||||
dev_Vendor = "'. $_REQUEST['vendor'] .'",
|
||||
dev_Favorite = "'. $_REQUEST['favorite'] .'",
|
||||
dev_Group = "'. $_REQUEST['group'] .'",
|
||||
dev_Comments = "'. $_REQUEST['comments'] .'",
|
||||
dev_StaticIP = "'. $_REQUEST['staticIP'] .'",
|
||||
dev_ScanCycle = "'. $_REQUEST['scancycle'] .'",
|
||||
dev_AlertEvents = "'. $_REQUEST['alertevents'] .'",
|
||||
dev_AlertDeviceDown = "'. $_REQUEST['alertdown'] .'",
|
||||
dev_SkipRepeated = "'. $_REQUEST['skiprepeated'] .'"
|
||||
WHERE dev_MAC="' . $_REQUEST['mac'] .'"';
|
||||
// update Data
|
||||
$result = $db->query($sql);
|
||||
|
||||
// check result
|
||||
if ($result == TRUE) {
|
||||
echo "Device updated successfully";
|
||||
} else {
|
||||
echo "Error updating device\n\n". $sql .'\n\n' . $db->lastErrorMsg();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
429
front/php/server/events.php
Normal file
429
front/php/server/events.php
Normal file
@@ -0,0 +1,429 @@
|
||||
<?php
|
||||
|
||||
// External files
|
||||
require 'db.php';
|
||||
require 'util.php';
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Action selector
|
||||
//------------------------------------------------------------------------------
|
||||
// Set maximum execution time to 1 minute
|
||||
ini_set ('max_execution_time','60');
|
||||
|
||||
// Open DB
|
||||
OpenDB();
|
||||
|
||||
// Action functions
|
||||
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
|
||||
$action = $_REQUEST['action'];
|
||||
switch ($action) {
|
||||
case 'totals': queryTotals(); break;
|
||||
case 'list': queryList(); break;
|
||||
case 'deviceSessions': queryDeviceSessions(); break;
|
||||
case 'devicePresence': queryDevicePresence(); break;
|
||||
case 'deviceEvents': queryDeviceEvents(); break;
|
||||
case 'calendarPresence': queryCalendarPresence(); break;
|
||||
default: logServerConsole ('Action: '. $action); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query total numbers of Events
|
||||
//------------------------------------------------------------------------------
|
||||
function queryTotals() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
// SQL
|
||||
$SQL1 = 'SELECT Count(*)
|
||||
FROM Events
|
||||
WHERE eve_DateTime >= '. $periodDate;
|
||||
|
||||
$SQL2 = 'SELECT Count(*)
|
||||
FROM Sessions ';
|
||||
|
||||
// All
|
||||
$result = $db->query($SQL1);
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$eventsAll = $row[0];
|
||||
|
||||
// Sessions
|
||||
$result = $db->query($SQL2. ' WHERE ( ses_DateTimeConnection >= '. $periodDate .'
|
||||
OR ses_DateTimeDisconnection >= '. $periodDate .'
|
||||
OR ses_StillConnected = 1 ) ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$eventsSessions = $row[0];
|
||||
|
||||
// Missing
|
||||
$result = $db->query($SQL2. ' WHERE (ses_DateTimeConnection IS NULL AND ses_DateTimeDisconnection >= '. $periodDate .' )
|
||||
OR (ses_DateTimeDisconnection IS NULL AND ses_StillConnected = 0 AND ses_DateTimeConnection >= '. $periodDate .' )' );
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$eventsMissing = $row[0];
|
||||
|
||||
// Voided
|
||||
$result = $db->query($SQL1. ' AND eve_EventType LIKE "VOIDED%" ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$eventsVoided = $row[0];
|
||||
|
||||
// New
|
||||
$result = $db->query($SQL1. ' AND eve_EventType LIKE "New Device" ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$eventsNew = $row[0];
|
||||
|
||||
// Down
|
||||
$result = $db->query($SQL1. ' AND eve_EventType LIKE "Device Down" ');
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$eventsDown = $row[0];
|
||||
|
||||
// Return json
|
||||
echo (json_encode (array ($eventsAll, $eventsSessions, $eventsMissing, $eventsVoided, $eventsNew, $eventsDown)));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query the List of events
|
||||
//------------------------------------------------------------------------------
|
||||
function queryList() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$type = $_REQUEST ['type'];
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
// SQL
|
||||
$SQL1 = 'SELECT eve_DateTime AS eve_DateTimeOrder, dev_name, dev_owner, eve_DateTime, eve_EventType, NULL, NULL, NULL, NULL, eve_IP, NULL, eve_AdditionalInfo, NULL, Dev_MAC
|
||||
FROM Events_Devices
|
||||
WHERE eve_DateTime >= '. $periodDate;
|
||||
|
||||
$SQL2 = 'SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder,
|
||||
dev_name, dev_owner, Null, Null, ses_DateTimeConnection, ses_DateTimeDisconnection, NULL, NULL, ses_IP, NULL, ses_AdditionalInfo, ses_StillConnected, Dev_MAC
|
||||
FROM Sessions_Devices ';
|
||||
|
||||
// SQL Variations for status
|
||||
switch ($type) {
|
||||
case 'all':
|
||||
$SQL = $SQL1;
|
||||
break;
|
||||
case 'sessions':
|
||||
$SQL = $SQL2 . ' WHERE ( ses_DateTimeConnection >= '. $periodDate .'
|
||||
OR ses_DateTimeDisconnection >= '. $periodDate .'
|
||||
OR ses_StillConnected = 1 ) ';
|
||||
break;
|
||||
case 'missing':
|
||||
$SQL = $SQL2 . ' WHERE (ses_DateTimeConnection IS NULL AND ses_DateTimeDisconnection >= '. $periodDate .' )
|
||||
OR (ses_DateTimeDisconnection IS NULL AND ses_StillConnected = 0 AND ses_DateTimeConnection >= '. $periodDate .' )';
|
||||
break;
|
||||
case 'voided':
|
||||
$SQL = $SQL1 .' AND eve_EventType LIKE "VOIDED%" ';
|
||||
break;
|
||||
case 'new':
|
||||
$SQL = $SQL1 .' AND eve_EventType = "New Device" ';
|
||||
break;
|
||||
case 'down':
|
||||
$SQL = $SQL1 .' AND eve_EventType = "Device Down" ';
|
||||
break;
|
||||
default:
|
||||
$SQL = $SQL1 .' AND 1==0 ';
|
||||
break;
|
||||
}
|
||||
|
||||
// Query
|
||||
$result = $db->query($SQL);
|
||||
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_NUM)) {
|
||||
if ($type == 'sessions' || $type == 'missing' ) {
|
||||
// Duration
|
||||
if (!empty ($row[5]) && !empty($row[6]) ) {
|
||||
$row[7] = formatDateDiff ($row[5], $row[6]);
|
||||
$row[8] = abs(strtotime($row[6]) - strtotime($row[5]));
|
||||
} elseif ($row[12] == 1) {
|
||||
$row[7] = formatDateDiff ($row[5], '');
|
||||
$row[8] = abs(strtotime("now") - strtotime($row[5]));
|
||||
} else {
|
||||
$row[7] = '...';
|
||||
$row[8] = 0;
|
||||
}
|
||||
|
||||
// Connection
|
||||
if (!empty ($row[5]) ) {
|
||||
$row[5] = formatDate ($row[5]);
|
||||
} else {
|
||||
$row[5] = '<missing event>';
|
||||
}
|
||||
|
||||
// Disconnection
|
||||
if (!empty ($row[6]) ) {
|
||||
$row[6] = formatDate ($row[6]);
|
||||
} elseif ($row[12] == 0) {
|
||||
$row[6] = '<missing event>';
|
||||
} else {
|
||||
$row[6] = '...';
|
||||
}
|
||||
|
||||
} else {
|
||||
// Event Date
|
||||
$row[3] = formatDate ($row[3]);
|
||||
}
|
||||
|
||||
// IP Order
|
||||
$row[10] = formatIPlong ($row[9]);
|
||||
$tableData['data'][] = $row;
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
if (empty($tableData['data'])) {
|
||||
$tableData['data'] = '';
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query Device Sessions
|
||||
//------------------------------------------------------------------------------
|
||||
function queryDeviceSessions() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$mac = $_REQUEST['mac'];
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder,
|
||||
ses_EventTypeConnection, ses_DateTimeConnection,
|
||||
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_StillConnected,
|
||||
ses_IP, ses_AdditionalInfo
|
||||
FROM Sessions
|
||||
WHERE ses_MAC="' . $mac .'"
|
||||
AND ( ses_DateTimeConnection >= '. $periodDate .'
|
||||
OR ses_DateTimeDisconnection >= '. $periodDate .'
|
||||
OR ses_StillConnected = 1 ) ');
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// Connection DateTime
|
||||
if ($row['ses_EventTypeConnection'] == '<missing event>') {
|
||||
$ini = $row['ses_EventTypeConnection'];
|
||||
} else {
|
||||
$ini = formatDate ($row['ses_DateTimeConnection']);
|
||||
}
|
||||
|
||||
// Disconnection DateTime
|
||||
if ($row['ses_StillConnected'] == true) {
|
||||
$end = '...';
|
||||
} elseif ($row['ses_EventTypeDisconnection'] == '<missing event>') {
|
||||
$end = $row['ses_EventTypeDisconnection'];
|
||||
} else {
|
||||
$end = formatDate ($row['ses_DateTimeDisconnection']);
|
||||
}
|
||||
|
||||
// Duration
|
||||
if ($row['ses_EventTypeConnection'] == '<missing event>' || $row['ses_EventTypeDisconnection'] == '<missing event>') {
|
||||
$dur = '...';
|
||||
} elseif ($row['ses_StillConnected'] == true) {
|
||||
$dur = formatDateDiff ($row['ses_DateTimeConnection'], ''); //*******************************************************************************************
|
||||
} else {
|
||||
$dur = formatDateDiff ($row['ses_DateTimeConnection'], $row['ses_DateTimeDisconnection']);
|
||||
}
|
||||
|
||||
// Additional Info
|
||||
$info = $row['ses_AdditionalInfo'];
|
||||
if ($row['ses_EventTypeConnection'] == 'New Device' ) {
|
||||
$info = $row['ses_EventTypeConnection'] .': '. $info;
|
||||
}
|
||||
|
||||
// Push row data
|
||||
$tableData['data'][] = array($row['ses_DateTimeOrder'], $ini, $end, $dur, $row['ses_IP'], $info);
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
if (empty($tableData['data'])) {
|
||||
$tableData['data'] = '';
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query Device Presence Calendar
|
||||
//------------------------------------------------------------------------------
|
||||
function queryDevicePresence() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$mac = $_REQUEST['mac'];
|
||||
$periodDate = getDateFromPeriod();
|
||||
$startDate = '"'. formatDateISO ($_REQUEST ['start']) .'"';
|
||||
$endDate = '"'. formatDateISO ($_REQUEST ['end']) .'"';
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT ses_EventTypeConnection, ses_DateTimeConnection,
|
||||
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_IP, ses_AdditionalInfo,
|
||||
|
||||
CASE WHEN ses_EventTypeConnection = "<missing event>" THEN
|
||||
IFNULL ((SELECT MAX(ses_DateTimeDisconnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeDisconnection < SES1.ses_DateTimeDisconnection), DATETIME(ses_DateTimeDisconnection, "-1 hour"))
|
||||
ELSE ses_DateTimeConnection
|
||||
END AS ses_DateTimeConnectionCorrected,
|
||||
|
||||
CASE WHEN ses_EventTypeDisconnection = "<missing event>" THEN
|
||||
(SELECT MIN(ses_DateTimeConnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeConnection > SES1.ses_DateTimeConnection)
|
||||
ELSE ses_DateTimeDisconnection
|
||||
END AS ses_DateTimeDisconnectionCorrected
|
||||
|
||||
FROM Sessions AS SES1
|
||||
WHERE ses_MAC="' . $mac .'"
|
||||
AND (ses_DateTimeConnectionCorrected <= date('. $endDate .')
|
||||
AND (ses_DateTimeDisconnectionCorrected >= date('. $startDate .') OR ses_StillConnected = 1 ))
|
||||
');
|
||||
|
||||
// arrays of rows
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// Event color
|
||||
if ($row['ses_EventTypeConnection'] == '<missing event>' || $row['ses_EventTypeDisconnection'] == '<missing event>') {
|
||||
$color = '#f39c12';
|
||||
} else {
|
||||
$color = '#0073b7';
|
||||
}
|
||||
|
||||
// tooltip
|
||||
$tooltip = 'Connection: ' . formatEventDate ($row['ses_DateTimeConnection'], $row['ses_EventTypeConnection']) . chr(13) .
|
||||
'Disconnection: ' . formatEventDate ($row['ses_DateTimeDisconnection'], $row['ses_EventTypeDisconnection']) . chr(13) .
|
||||
'IP: ' . $row['ses_IP'];
|
||||
|
||||
// Save row data
|
||||
// 'start' => formatDateISO ($row['ses_DateTimeConnectionCorrected']),
|
||||
// 'end' => formatDateISO ($row['ses_DateTimeDisconnectionCorrected']),
|
||||
// 'start' => $row['ses_DateTimeConnectionCorrected'],
|
||||
// 'end' => $row['ses_DateTimeDisconnectionCorrected'],
|
||||
$tableData[] = array(
|
||||
'title' => '',
|
||||
'start' => formatDateISO ($row['ses_DateTimeConnectionCorrected']),
|
||||
'end' => formatDateISO ($row['ses_DateTimeDisconnectionCorrected']),
|
||||
'color' => $color,
|
||||
'tooltip' => $tooltip
|
||||
);
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
if (empty($tableData)) {
|
||||
$tableData = '';
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query Presence Calendar for all Devices
|
||||
//------------------------------------------------------------------------------
|
||||
function queryCalendarPresence() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$periodDate = getDateFromPeriod();
|
||||
$startDate = '"'. $_REQUEST ['start'] .'"';
|
||||
$endDate = '"'. $_REQUEST ['end'] .'"';
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT ses_MAC, ses_EventTypeConnection, ses_DateTimeConnection,
|
||||
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_IP, ses_AdditionalInfo,
|
||||
|
||||
CASE WHEN ses_EventTypeConnection = "<missing event>" THEN
|
||||
IFNULL ((SELECT MAX(ses_DateTimeDisconnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeDisconnection < SES1.ses_DateTimeDisconnection), DATETIME(ses_DateTimeDisconnection, "-1 hour"))
|
||||
ELSE ses_DateTimeConnection
|
||||
END AS ses_DateTimeConnectionCorrected,
|
||||
|
||||
CASE WHEN ses_EventTypeDisconnection = "<missing event>" THEN
|
||||
(SELECT MIN(ses_DateTimeConnection) FROM Sessions AS SES2 WHERE SES2.ses_MAC = SES1.ses_MAC AND SES2.ses_DateTimeConnection > SES1.ses_DateTimeConnection)
|
||||
ELSE ses_DateTimeDisconnection
|
||||
END AS ses_DateTimeDisconnectionCorrected
|
||||
|
||||
FROM Sessions AS SES1
|
||||
WHERE ( ses_DateTimeConnectionCorrected <= Date('. $endDate .')
|
||||
AND (ses_DateTimeDisconnectionCorrected >= Date('. $startDate .') OR ses_StillConnected = 1 ))
|
||||
');
|
||||
|
||||
// arrays of rows
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
// Event color
|
||||
if ($row['ses_EventTypeConnection'] == '<missing event>' || $row['ses_EventTypeDisconnection'] == '<missing event>') {
|
||||
$color = '#f39c12';
|
||||
} else {
|
||||
$color = '#0073b7';
|
||||
}
|
||||
|
||||
// tooltip
|
||||
$tooltip = 'Connection: ' . formatEventDate ($row['ses_DateTimeConnection'], $row['ses_EventTypeConnection']) . chr(13) .
|
||||
'Disconnection: ' . formatEventDate ($row['ses_DateTimeDisconnection'], $row['ses_EventTypeDisconnection']) . chr(13) .
|
||||
'IP: ' . $row['ses_IP'];
|
||||
|
||||
// Save row data
|
||||
$tableData[] = array(
|
||||
'resourceId' => $row['ses_MAC'],
|
||||
'title' => '',
|
||||
'start' => formatDateISO ($row['ses_DateTimeConnectionCorrected']),
|
||||
'end' => formatDateISO ($row['ses_DateTimeDisconnectionCorrected']),
|
||||
'color' => $color,
|
||||
'tooltip' => $tooltip,
|
||||
'className' => 'no-border'
|
||||
);
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
if (empty($tableData)) {
|
||||
$tableData = '';
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode($tableData));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Query Device events
|
||||
//------------------------------------------------------------------------------
|
||||
function queryDeviceEvents() {
|
||||
global $db;
|
||||
|
||||
// Request Parameters
|
||||
$mac = $_REQUEST['mac'];
|
||||
$periodDate = getDateFromPeriod();
|
||||
$hideConnections = $_REQUEST ['hideConnections'];
|
||||
|
||||
// SQL
|
||||
$result = $db->query('SELECT eve_DateTime, eve_EventType, eve_IP, eve_AdditionalInfo
|
||||
FROM Events
|
||||
WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate .'
|
||||
AND ( (eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" AND
|
||||
eve_EventType <> "VOIDED - Connected" AND eve_EventType <> "VOIDED - Disconnected")
|
||||
OR "'. $hideConnections .'" = "false" )
|
||||
');
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_NUM)) {
|
||||
$row[0] = formatDate ($row[0]);
|
||||
$tableData['data'][] = $row;
|
||||
}
|
||||
|
||||
// Control no rows
|
||||
if (empty($tableData['data'])) {
|
||||
$tableData['data'] = '';
|
||||
}
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($tableData));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
48
front/php/server/util.php
Normal file
48
front/php/server/util.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Formatting data functions
|
||||
//------------------------------------------------------------------------------
|
||||
function formatDate ($date1) {
|
||||
return date_format (new DateTime ($date1) , 'Y-m-d H:i');
|
||||
}
|
||||
|
||||
function formatDateDiff ($date1, $date2) {
|
||||
return date_diff (new DateTime ($date1), new DateTime ($date2 ) )-> format ('%ad %H:%I');
|
||||
}
|
||||
|
||||
function formatDateISO ($date1) {
|
||||
return date_format (new DateTime ($date1),'c');
|
||||
}
|
||||
|
||||
function formatEventDate ($date1, $eventType) {
|
||||
if (!empty ($date1) ) {
|
||||
$ret = formatDate ($date1);
|
||||
} elseif ($eventType == '<missing event>') {
|
||||
$ret = '<missing event>';
|
||||
} else {
|
||||
$ret = '<Still Connected>';
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function formatIPlong ($IP) {
|
||||
return sprintf('%u', ip2long($IP) );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Others functions
|
||||
//------------------------------------------------------------------------------
|
||||
function getDateFromPeriod () {
|
||||
$period = $_REQUEST['period'];
|
||||
return '"'. date ('Y-m-d', strtotime ('+1 day -'.$period) ) .'"';
|
||||
}
|
||||
|
||||
function logServerConsole ($text) {
|
||||
$x = array();
|
||||
$y = $x['__________'. $text .'__________'];
|
||||
}
|
||||
|
||||
?>
|
||||
41
front/php/templates/footer.php
Normal file
41
front/php/templates/footer.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- Main Footer -->
|
||||
<footer class="main-footer">
|
||||
<!-- Default to the left -->
|
||||
© 2020 Puche
|
||||
<!-- To the right -->
|
||||
<div class="pull-right no-hidden-xs">
|
||||
Pi.alert  2.50  <small>(2019-12-30)</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Control Sidebar -->
|
||||
<!-- DELETED -->
|
||||
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
|
||||
<!-- REQUIRED JS SCRIPTS -->
|
||||
|
||||
<!-- jQuery 3 -->
|
||||
<script src="lib/AdminLTE/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<!-- Bootstrap 3.3.7 -->
|
||||
<script src="lib/AdminLTE/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
<!-- AdminLTE App -->
|
||||
<script src="lib/AdminLTE/dist/js/adminlte.min.js"></script>
|
||||
|
||||
<!-- Optionally, you can add Slimscroll and FastClick plugins.
|
||||
Both of these plugins are recommended to enhance the
|
||||
user experience. -->
|
||||
|
||||
<!-- SlimScroll -->
|
||||
<script src="lib/AdminLTE/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script>
|
||||
<!-- FastClick -->
|
||||
<script src="lib/AdminLTE/bower_components/fastclick/lib/fastclick.js"></script>
|
||||
|
||||
<!-- Pi.Alert -------------------------------------------------------------- -->
|
||||
<script src="js/pialert_common.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
275
front/php/templates/header.php
Normal file
275
front/php/templates/header.php
Normal file
@@ -0,0 +1,275 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Pi.alert</title>
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<!-- Bootstrap 3.3.7 -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/font-awesome/css/font-awesome.min.css">
|
||||
<!-- Ionicons -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/Ionicons/css/ionicons.min.css">
|
||||
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/dist/css/AdminLTE.min.css">
|
||||
<!-- AdminLTE Skins. We have chosen the skin-blue for this starter
|
||||
page. However, you can choose any other skin. Make sure you
|
||||
apply the skin class to the body tag so the changes take effect. -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/dist/css/skins/skin-yellow-light.min.css">
|
||||
|
||||
|
||||
<!-- Pi.alert CSS -->
|
||||
<link rel="stylesheet" href="css/pialert.css">
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Google Font -->
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
|
||||
|
||||
<!-- Page Icon -->
|
||||
<link rel="icon" type="image/png" sizes="160x160" href="img/pialertLogoGray80.png" />
|
||||
</head>
|
||||
|
||||
<!-- Layout Boxed Yellow -->
|
||||
<body class="hold-transition skin-yellow-light layout-boxed sidebar-mini" style="background-image: url('img/backgroud.png');">
|
||||
<!-- Site wrapper -->
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- Main Header -->
|
||||
<header class="main-header">
|
||||
|
||||
<!-- Logo -->
|
||||
<a href="/" class="logo">
|
||||
<!-- mini logo for sidebar mini 50x50 pixels -->
|
||||
<span class="logo-mini">P<b>a</b></span>
|
||||
<!-- logo for regular state and mobile devices -->
|
||||
<span class="logo-lg">Pi<b>.alert</b></span>
|
||||
</a>
|
||||
|
||||
<!-- Header Navbar -->
|
||||
<nav class="navbar navbar-static-top" role="navigation">
|
||||
<!-- Sidebar toggle button-->
|
||||
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
</a>
|
||||
<!-- Navbar Right Menu -->
|
||||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<!-- Server Name -->
|
||||
<li><a style="pointer-events:none;"><?php echo gethostname(); ?></a></li>
|
||||
|
||||
<!-- Header right info -->
|
||||
<li class="dropdown user user-menu">
|
||||
<!-- Menu Toggle Button -->
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<!-- The user image in the navbar-->
|
||||
<img src="img/pialertLogoWhite.png" class="user-image" style="border-radius: initial" alt="Pi.alert Logo">
|
||||
<!-- hidden-xs hides the username on small devices so only the image appears. -->
|
||||
<span class="hidden-xs">Pi.alert</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<!-- The user image in the menu -->
|
||||
<li class="user-header">
|
||||
<img src="img/pialertLogoWhite.png" class="img-circle" alt="Pi.alert Logo" style="border-color:transparent">
|
||||
|
||||
<p>
|
||||
Open Source Network Guard
|
||||
<small>Designed for Raspberry Pi</small>
|
||||
</p>
|
||||
</li>
|
||||
<!-- Menu Body -->
|
||||
<li class="user-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-4 text-center">
|
||||
<a href="https://github.com/pucherot/Pi.Alert">GitHub</a>
|
||||
</div>
|
||||
<div class="col-xs-4 text-center">
|
||||
<a href="https://github.com/pucherot/Pi.Alert">Pi.Alert</a>
|
||||
<!-- <a href="#">Website</a> -->
|
||||
</div>
|
||||
<div class="col-xs-4 text-center">
|
||||
<a href="#">Updates</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- Left side column. contains the logo and sidebar -->
|
||||
<aside class="main-sidebar">
|
||||
|
||||
<!-- sidebar: style can be found in sidebar.less -->
|
||||
<section class="sidebar">
|
||||
|
||||
<!-- Sidebar user panel (optional) -->
|
||||
<div class="user-panel">
|
||||
<a href="/" class="logo">
|
||||
<img src="img/pialertLogoGray80.png" class="img-responsive" alt="Pi.alert Logo"/>
|
||||
</a>
|
||||
<div class="pull-left image">
|
||||
<!--
|
||||
<br><img src="img/pialertLogoBlack.png" class="img-responsive" alt="Pi.alert Logo" style="display: table; table-layout: fixed;" />
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="pull-left info" style="display: none">
|
||||
<p>Status</p>
|
||||
<?php
|
||||
|
||||
$pistatus = exec('sudo pihole status web');
|
||||
$pistatus=1;
|
||||
$FTL=true;
|
||||
$celsius=56.7;
|
||||
$temperatureunit='C';
|
||||
$nproc=2;
|
||||
$loaddata=array();
|
||||
$loaddata[]=1.1;
|
||||
$loaddata[]=1.2;
|
||||
$loaddata[]=1.3;
|
||||
$memory_usage=0.452;
|
||||
if ($pistatus == "1") {
|
||||
echo '<a id="status"><i class="fa fa-circle" style="color:#7FFF00"></i> Active</a>';
|
||||
} elseif ($pistatus == "0") {
|
||||
echo '<a id="status"><i class="fa fa-circle" style="color:#FF0000"></i> Offline</a>';
|
||||
} elseif ($pistatus == "-1") {
|
||||
echo '<a id="status"><i class="fa fa-circle" style="color:#FF0000"></i> DNS service not running</a>';
|
||||
} else {
|
||||
echo '<a id="status"><i class="fa fa-circle" style="color:#ff9900"></i> Unknown</a>';
|
||||
}
|
||||
|
||||
// CPU Temp
|
||||
if($FTL)
|
||||
{
|
||||
if ($celsius >= -273.15) {
|
||||
echo "<a id=\"temperature\"><i class=\"fa fa-fire\" style=\"color:";
|
||||
if ($celsius > 60) {
|
||||
echo "#FF0000";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "#3366FF";
|
||||
}
|
||||
echo "\"></i> Temp: ";
|
||||
if($temperatureunit === "F")
|
||||
{
|
||||
echo round($fahrenheit,1) . " °F";
|
||||
}
|
||||
elseif($temperatureunit === "K")
|
||||
{
|
||||
echo round($kelvin,1) . " K";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo round($celsius,1) . " °C";
|
||||
}
|
||||
echo "</a>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<a id=\"temperature\"><i class="fa fa-circle" style="color:#FF0000"></i> FTL offline</a>';
|
||||
}
|
||||
?>
|
||||
<br/>
|
||||
<?php
|
||||
echo "<a title=\"Detected $nproc cores\"><i class=\"fa fa-circle\" style=\"color:";
|
||||
if ($loaddata[0] > $nproc) {
|
||||
echo "#FF0000";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "#7FFF00";
|
||||
}
|
||||
echo "\"></i> Load: " . $loaddata[0] . " " . $loaddata[1] . " ". $loaddata[2] . "</a>";
|
||||
?>
|
||||
<br/>
|
||||
<?php
|
||||
echo "<a><i class=\"fa fa-circle\" style=\"color:";
|
||||
if ($memory_usage > 0.75 || $memory_usage < 0.0) {
|
||||
echo "#FF0000";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "#7FFF00";
|
||||
}
|
||||
if($memory_usage > 0.0)
|
||||
{
|
||||
echo "\"></i> Memory usage: " . sprintf("%.1f",100.0*$memory_usage) . " %</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "\"></i> Memory usage: N/A</a>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- search form (Optional) -->
|
||||
<!--
|
||||
<form action="#" method="get" class="sidebar-form">
|
||||
<div class="input-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search...">
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
-->
|
||||
<!-- /.search form -->
|
||||
|
||||
<!-- Sidebar Menu -->
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
<!--
|
||||
<li class="header">MAIN MENU</li>
|
||||
-->
|
||||
|
||||
<!-- Optionally, you can add icons to the links -->
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('devices.php', 'deviceDetails.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="devices.php"><i class="fa fa-laptop"></i> <span>Devices</span></a>
|
||||
</li>
|
||||
|
||||
<!--
|
||||
<li><a href="devices.php?status=favorites"><i class="fa fa-star"></i> <span>Favorites Devices</span></a></li>
|
||||
-->
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('presence.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="presence.php"><i class="fa fa-calendar"></i> <span>Presence</span></a>
|
||||
</li>
|
||||
|
||||
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('events.php') ) ){ echo 'active'; } ?>">
|
||||
<a href="events.php"><i class="fa fa-bolt"></i> <span>Events</span></a>
|
||||
</li>
|
||||
|
||||
<!--
|
||||
<li class="treeview">
|
||||
<a href="#"><i class="fa fa-link"></i> <span>Config</span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li><a href="#">Scan Cycles</a></li>
|
||||
<li><a href="#">Cron Status</a></li>
|
||||
<li><a href="#">Current IP</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
<!-- /.sidebar-menu -->
|
||||
</section>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
413
front/presence.php
Normal file
413
front/presence.php
Normal file
@@ -0,0 +1,413 @@
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/header.php';
|
||||
?>
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content header--------------------------------------------------------- -->
|
||||
<section class="content-header">
|
||||
<h1 id="pageTitle">
|
||||
Presence by Devices
|
||||
</h1>
|
||||
|
||||
<!-- period selector -->
|
||||
<span class="breadcrumb text-gray50">
|
||||
New Devices period:
|
||||
<select id="period" onchange="javascript: periodChanged();">
|
||||
<option value="1 day">Today</option>
|
||||
<option value="7 days">Last Week</option>
|
||||
<option value="1 month" selected>Last Month</option>
|
||||
<option value="1 year">Last Year</option>
|
||||
<option value="100 years">All info</option>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
</section>
|
||||
|
||||
<!-- Main content ---------------------------------------------------------- -->
|
||||
<section class="content">
|
||||
<div class="row">
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryPresence('all');">
|
||||
<div class="small-box bg-aqua pa-small-box-aqua">
|
||||
<div class="inner">
|
||||
|
||||
<h4>All Devices</h4>
|
||||
<h3 id="devicesAll"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-laptop"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryPresence('connected');">
|
||||
<div class="small-box bg-green pa-small-box-green">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Connected</h4>
|
||||
<h3 id="devicesConnected"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-plug"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryPresence('new');">
|
||||
<div class="small-box bg-yellow pa-small-box-yellow">
|
||||
<div class="inner">
|
||||
|
||||
<h4>New Devices</h4>
|
||||
<h3 id="devicesNew"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-plus-round"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- top small box --------------------------------------------------------- -->
|
||||
<div class="col-lg-3 col-sm-6 col-xs-6">
|
||||
<a href="#" onclick="javascript: queryPresence('down');">
|
||||
<div class="small-box bg-red pa-small-box-red">
|
||||
<div class="inner">
|
||||
|
||||
<h4>Down Alerts</h4>
|
||||
<h3 id="devicesDown"> -- </h3>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-warning"></i>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
Details <i class="fa fa-arrow-circle-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- Calendar -------------------------------------------------------------- -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-sm-12 col-xs-12">
|
||||
<div id="tableDevicesBox" class="box" style="min-height: 500px">
|
||||
<div class="box-header">
|
||||
<h3 id="tableDevicesTitle" class="box-title text-gray">Devices</h3>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="box-body table-responsive">
|
||||
<!-- spinner -->
|
||||
<div id="loading" style="display: none">
|
||||
<div class="pa_semitransparent-panel"></div>
|
||||
<div class="panel panel-default pa_spinner">
|
||||
<table><td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="calendar"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
<!-- iCkeck -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/plugins/iCheck/all.css">
|
||||
<script src="lib/AdminLTE/plugins/iCheck/icheck.min.js"></script>
|
||||
|
||||
<!-- Datatable -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||
|
||||
<!-- fullCalendar -->
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.min.css">
|
||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.print.min.css" media="print">
|
||||
<script src="lib/AdminLTE/bower_components/moment/moment.js"></script>
|
||||
<script src="lib/AdminLTE/bower_components/fullcalendar/dist/fullcalendar.min.js"></script>
|
||||
|
||||
<!-- fullCalendar Scheduler -->
|
||||
<link href="lib/fullcalendar-scheduler/scheduler.min.css" rel="stylesheet">
|
||||
<script src="lib/fullcalendar-scheduler/scheduler.min.js"></script>
|
||||
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
var deviceStatus = '';
|
||||
var period = '';
|
||||
|
||||
// Initialize MAC
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has ('status') == true) {
|
||||
deviceStatus = urlParams.get ('status');
|
||||
} else {
|
||||
deviceStatus = 'all';
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
$(function () {
|
||||
initializeiCheck();
|
||||
initializeCalendar();
|
||||
periodChanged();
|
||||
});
|
||||
|
||||
// Force re-render calendar on tab change (bugfix for render error at left panel)
|
||||
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (nav) {
|
||||
if ($(nav.target).attr('href') == '#panPresence') {
|
||||
$('#calendar').fullCalendar('rerenderEvents');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function periodChanged () {
|
||||
// Requery totals and list
|
||||
queryTotals();
|
||||
queryPresence(deviceStatus);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeiCheck () {
|
||||
// Default
|
||||
$('input').iCheck({
|
||||
checkboxClass: 'icheckbox_flat-blue',
|
||||
radioClass: 'iradio_flat-blue',
|
||||
increaseArea: '20%'
|
||||
});
|
||||
|
||||
// readonly
|
||||
$('#readonlyblock input').iCheck({
|
||||
checkboxClass: 'icheckbox_flat-blue',
|
||||
radioClass: 'iradio_flat-blue',
|
||||
increaseArea: '-100%'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeCalendar () {
|
||||
$('#calendar').fullCalendar({
|
||||
|
||||
header: {
|
||||
left : 'prev,next today',
|
||||
center : 'title',
|
||||
right : 'timelineYear,timelineMonth,timelineWeek'
|
||||
},
|
||||
|
||||
defaultView : 'timelineMonth',
|
||||
height : 'auto',
|
||||
firstDay : 1,
|
||||
allDaySlot : false,
|
||||
timeFormat : 'H:mm',
|
||||
|
||||
resourceLabelText : 'Devices',
|
||||
resourceAreaWidth : '160px',
|
||||
slotWidth : '1px',
|
||||
|
||||
resourceOrder : '-favorite,title',
|
||||
|
||||
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
|
||||
// schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
|
||||
|
||||
views: {
|
||||
timelineYear: {
|
||||
type : 'timeline',
|
||||
duration : { year: 1 },
|
||||
buttonText : 'year',
|
||||
slotLabelFormat : 'MMM',
|
||||
// Hack to show partial day events not as fullday events
|
||||
slotDuration : {minutes: 44641}
|
||||
},
|
||||
|
||||
timelineQuarter: {
|
||||
type : 'timeline',
|
||||
duration : { month: 3 },
|
||||
buttonText : 'quarter',
|
||||
slotLabelFormat : 'MMM',
|
||||
// Hack to show partial day events not as fullday events
|
||||
slotDuration : {minutes: 44641}
|
||||
},
|
||||
|
||||
timelineMonth: {
|
||||
type : 'timeline',
|
||||
duration : { month: 1 },
|
||||
buttonText : 'month',
|
||||
slotLabelFormat : 'D',
|
||||
// Hack to show partial day events not as fullday events
|
||||
slotDuration : '24:00:01'
|
||||
},
|
||||
|
||||
timelineWeek: {
|
||||
type : 'timeline',
|
||||
duration : { week: 1 },
|
||||
buttonText : 'week',
|
||||
slotLabelFormat : 'D',
|
||||
slotDuration : '24:00:01'
|
||||
}
|
||||
},
|
||||
|
||||
// Needed due hack partial day events 23:59:59
|
||||
dayRender: function (date, cell) {
|
||||
if ($('#calendar').fullCalendar('getView').name == 'timelineYear') {
|
||||
cell.removeClass('fc-sat');
|
||||
cell.removeClass('fc-sun');
|
||||
return;
|
||||
}
|
||||
|
||||
if (date.day() == 0) {
|
||||
cell.addClass('fc-sun'); };
|
||||
|
||||
if (date.day() == 6) {
|
||||
cell.addClass('fc-sat'); };
|
||||
|
||||
if (date.format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')) {
|
||||
cell.addClass ('fc-today'); };
|
||||
},
|
||||
|
||||
resourceRender: function (resourceObj, labelTds, bodyTds) {
|
||||
labelTds.find('span.fc-cell-text').html ('<b><a href="deviceDetails.php?mac='+ resourceObj.id+ '&period='+ period +'" class="">'+ resourceObj.title +'</a></b>');
|
||||
|
||||
// Resize heihgt
|
||||
// $(".fc-content table tbody tr .fc-widget-content div").addClass('fc-resized-row');
|
||||
},
|
||||
|
||||
eventRender: function (event, element, view) {
|
||||
$(element).tooltip({container: 'body', placement: 'right', title: event.tooltip});
|
||||
// element.attr ('title', event.tooltip); // Alternative tooltip
|
||||
},
|
||||
|
||||
loading: function( isLoading, view ) {
|
||||
if (isLoading) {
|
||||
$("#loading").show();
|
||||
} else {
|
||||
$("#loading").hide();
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryTotals () {
|
||||
// debugTimer();
|
||||
|
||||
// stop timer
|
||||
stopTimerRefreshData();
|
||||
|
||||
// period
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
// get totals and put in boxes
|
||||
$.get('php/server/devices.php?action=totals&period='+ period, function(data) {
|
||||
var totalsDevices = JSON.parse(data);
|
||||
|
||||
$('#devicesAll').html (totalsDevices[0].toLocaleString());
|
||||
$('#devicesConnected').html (totalsDevices[1].toLocaleString());
|
||||
$('#devicesNew').html (totalsDevices[2].toLocaleString());
|
||||
$('#devicesDown').html (totalsDevices[3].toLocaleString());
|
||||
});
|
||||
|
||||
// Timer for refresh data
|
||||
newTimerRefreshData (queryTotals);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function queryPresence (status) {
|
||||
// Save status and period selected
|
||||
deviceStatus = status;
|
||||
period = document.getElementById('period').value;
|
||||
|
||||
|
||||
// Defini color & title for the status selected
|
||||
switch (deviceStatus) {
|
||||
case 'all':
|
||||
tableTitle = 'Total Devices';
|
||||
color = 'aqua';
|
||||
break;
|
||||
case 'connected':
|
||||
tableTitle = 'Connected Devices';
|
||||
color = 'green';
|
||||
break;
|
||||
case 'new':
|
||||
tableTitle = 'New Devices';
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 'down':
|
||||
tableTitle = 'Down Alerts';
|
||||
color = 'red';
|
||||
break;
|
||||
case 'favorites':
|
||||
tableTitle = 'Favorites';
|
||||
color = 'yellow';
|
||||
break;
|
||||
default:
|
||||
tableTitle = 'Devices';
|
||||
boxClass = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set title and color
|
||||
document.getElementById('tableDevicesTitle').className = 'box-title text-' + color;
|
||||
document.getElementById('tableDevicesBox').className = 'box box-' + color;
|
||||
$('#tableDevicesTitle').html (tableTitle);
|
||||
|
||||
$('#calendar').fullCalendar ('option', 'resources', 'php/server/devices.php?action=calendar&status='+ deviceStatus +'&period='+ period);
|
||||
$('#calendar').fullCalendar ('refetchResources');
|
||||
// Query calendar
|
||||
// resources : 'https://fullcalendar.io/demo-resources.json',
|
||||
// events : 'https://fullcalendar.io/demo-events.json?with-resources',
|
||||
|
||||
$('#calendar').fullCalendar('removeEventSources');
|
||||
$('#calendar').fullCalendar('addEventSource', { url: 'php/server/events.php?action=calendarPresence&period='+ period });
|
||||
};
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user