浏览代码

FD3-629 Vista de puerto OLT

Maxi Schvindt 6 年之前
父节点
当前提交
64cdee3cd3

+ 2 - 2
src/StatsBundle/Admin/OnuAdmin.php

@@ -109,9 +109,9 @@ class OnuAdmin extends BaseAdmin
     {
 
         $actions = parent::configureActionButtons($action, $object);
-        if($action == "list") {
+        /* if($action == "list") {
             $actions['show_in_map'] = array('template' => 'StatsBundle:Onu:map_button.html.twig');
-        }
+        } */
         
         return $actions;
     }

+ 7 - 0
src/StatsBundle/Admin/PonPortAdmin.php

@@ -95,6 +95,12 @@ class PonPortAdmin extends BaseAdmin
      */
     protected function configureShowFields(ShowMapper $showMapper)
     {
+
+        $from = $this->getRequest()->get('from');
+        $to = $this->getRequest()->get('to');
+
+        $this->parameters = array('from' => $from, 'to' => $to);
+        /*
         $ponPort = $this->getSubject();
         $oltDeviceId = $ponPort->getOltDeviceId();
         $deviceServer = $ponPort->getDeviceServer();
@@ -147,6 +153,7 @@ class PonPortAdmin extends BaseAdmin
             ->add('temperature', 'string', array('template' => 'StatsBundle:Onu:field_temperature.html.twig', 'extend' => 'base_show_field.html.twig'))
             ->add('biasCurrent')
         ;
+        */
     }
 
     /**

+ 150 - 1
src/StatsBundle/Controller/StatsController.php

@@ -196,7 +196,7 @@ class StatsController extends Controller
             'gsHost'=> $gsHost,
             'gsPort'=> $gsPort
         ));
-   }
+    }
 
     /**
      * @Route("/admin/stats/onu/stats/api_feature_json", name="api_feature_json")
@@ -1483,4 +1483,153 @@ class StatsController extends Controller
         return $return;
     }
 
+    /* 546 */
+    public function showPonPortAction(Request $request)
+    {
+        $em = $this->get("doctrine.orm.entity_manager");
+
+        ($request->get('from'))? $from = $request->get('from') : $from = strtotime("-12 hour");
+        ($request->get('to'))? $to = $request->get('to') : $to = strtotime("now");
+        $range = array('from' => date("Y-m-d H:i:s", $from), 'to' => date("Y-m-d H:i:s", $to));
+        
+        $ponport = $request->get('object');
+        $index = $ponport->getIndex();
+        $olt = $ponport->getOltDeviceId();
+        $server = $ponport->getDeviceServer()->getId();
+
+        $_ponport = str_replace("/",".",$ponport->getPonPort());
+
+        $prefix = "d_{$olt}_s_{$server}";
+
+        $rxseries = $errors = $series = $targets = array();
+
+        $targets["in_bandwidth"] = array("target" => "{$prefix}_inbandwidth_pon_{$_ponport}");
+        $targets["out_bandwidth"] = array("target" => "{$prefix}_outbandwidth_pon_{$_ponport}");
+        $targets["tx"] = array("target" => "{$prefix}_pon_tx_{$_ponport}");
+        $targets["voltage"] = array("target" => "{$prefix}_pon_voltage_{$_ponport}");
+        $targets["temperature"] = array("target" => "{$prefix}_pon_temperature_{$_ponport}");
+        $targets["on"] = array("target" => "{$prefix}_pon_state_on_{$_ponport}");
+        $targets["off"] = array("target" => "{$prefix}_pon_state_off_{$_ponport}");
+        
+        $q = $em->getRepository("StatsBundle:Onu")->createQueryBuilder('o');
+        $onus = $q->where($q->expr()->like('o.ponPort', ':ponPort'))
+                ->andWhere('o.oltDeviceId = :oltDeviceId')
+                ->andWhere('o.deviceServer = :deviceServer')
+                ->setParameter('ponPort', "{$ponport->getPonPort()}%")
+                ->setParameter('oltDeviceId', $olt)
+                ->setParameter('deviceServer', $server)
+                ->getQuery()
+                ->getResult();
+
+        if($onus) {
+            foreach($onus as $index => $onu) {
+                $index = str_replace("/",".",$onu->getPonPort());
+                $rxseries[] = $onu->getPonSerialNumber();
+                $targets["rx_{$onu->getPonSerialNumber()}"] = array("target" => "{$prefix}_pon_rx_{$index}");
+            }
+        }
+
+        $search = array('targets' => $targets, 'maxDataPoints' => 500000, 'range' => $range);
+        $start = microtime(true);
+        $this->getSeries($series, $errors, $targets, $search, "ponport: {$ponport->getPonPort()}");
+        $end = microtime(true);
+
+        $deviceServer = $ponport->getDeviceServer();
+        $urls = $this->get('webservice')->getData($deviceServer->getUrl());
+        
+        $olt = $urlFtth = null;
+        if(isset($urls['url_ftth'])) {
+            $urlFtth = $urls['url_ftth'];
+        }
+        
+        $olt = $this->getOlt($ponport, $urlFtth);
+        
+        list($onus, $locations, $status) = $this->getPonportOnus($onus);
+
+        if ($request->isMethod('GET')) {
+            return $this->render('StatsBundle:Stats:show_ponport.html.twig', array(
+                'time' => $end - $start,
+                'ponport' => $ponport,
+                'series' => $series,
+                'olt' => $olt,
+                'onus' => $onus,
+                'location' => $this->setDefaultMap(),
+                'locations' => $locations,
+                'status' => $status,
+                'rxseries' => $rxseries,
+                'from' => $from,
+                'to' => $to
+            ));
+        }
+        
+        return new JsonResponse(array('series' => $series,));
+    }
+
+    private function getPonportOnus($onus) {
+        
+        $on = $off = 0;
+        $locations = $_onus = array();
+
+        foreach($onus as $onu) {
+            
+            $row = array();
+            $index = $onu->getIndex();
+            $row['psn'] = $psn = $onu->getPonSerialNumber();
+            $row['sn'] = $onu->getSerialNumber();
+            $row['port'] = $onu->getPonPort();
+            $row['index'] = $index;
+            $row['status'] = $status = $onu->getStatus();
+            $row['txPower'] = $tx = $onu->getTxPower();
+            $row['rxPower'] = $rx = $onu->getRxPower();
+            $row['voltage'] = $onu->getVoltage();
+            $row['temperature'] = $onu->getTemperature();
+            $row['rxPowerOlt'] = $onu->getRxPowerOlt();
+            $row['lat'] = $lat = $onu->getLat();
+            $row['lng'] = $lng = $onu->getLng();
+            $row['inOctets'] = $onu->getInOctets();
+            $row['outOctets'] = $onu->getOutOctets();
+
+            if($status) {
+                $on++;
+            } else {
+                $off++;
+            }
+
+            $_onus[$index] = $row;
+
+            if($lat && $lng) {
+                $locations[$index] = array('psn' => $psn, 'tx' => $tx, 'rx' => $rx, 'lat' => $lat, 'lng' => $lng, 'status' => $status);
+            }
+
+        }
+
+        $status = array('online' => $on, 'offline' => $off);
+
+        return array($_onus, $locations, $status);
+
+    }
+
+    private function getOlt($object, $url) {
+        $return = array('olt_name' => null, 'olt_host' => null, 'olt_model' => null, 'olt_mark' => null);
+        
+        if(is_null($url)) return $return;
+
+        $tenancyId = $object->getTenancyId();
+        $oltId = $object->getOltDeviceId();
+        $apiOlt = "{$url}/api/olts.json";
+        $filters = array("id" => $oltId, 'tenancyId' => $tenancyId);
+
+        $olt = $this->get('webservice')->getData($apiOlt, $filters);
+
+        if(is_null($olt)) return $return;
+
+        if(isset($olt[0]['name'])) $return['olt_name'] = $olt[0]['name'];
+        if(isset($olt[0]['ip'])) $return['olt_host'] = $olt[0]['ip'];
+        if(isset($olt[0]['model']['name'])) $return['olt_model'] = $olt[0]['model']['name'];
+        if(isset($olt[0]['model']['mark'])) $return['olt_mark'] = $olt[0]['model']['mark'];
+
+        return $return;
+        
+    }
+
 }

+ 1 - 1
src/StatsBundle/Resources/config/services.yml

@@ -38,7 +38,7 @@ services:
             - { name: sonata.admin, manager_type: orm, group: List, label: PonPort, label_catalogue: StatsBundle, label_translator_strategy: sonata.admin.label.strategy.underscore }
         calls:
             - [setTranslationDomain, [StatsBundle]]
-            - [setTemplate, ['show','StatsBundle:PonPort:base_show.html.twig']]
+            - [setTemplate, ['show','StatsBundle:PonPort:base_show_v2.html.twig']]
             - [setTemplate, ['list','StatsBundle:PonPort:base_list.html.twig']]
 
     stats.report.manager:

+ 17 - 1
src/StatsBundle/Resources/translations/StatsBundle.es.yml

@@ -125,6 +125,11 @@ show:
     label_signal_cmts: SNR Ups
     label_microreflection_cmts: Microreflection Ups
     label_rx_power_olt: RX Power Port
+    label_port: Port
+    label_olt_name: Nombre
+    label_olt_host: Host
+    label_olt_model: Modelo
+
 
 list:
     label_name: Nombre
@@ -238,6 +243,14 @@ list:
     label_sla_numbers: SLA Números
     label_latency: Latency
     label_jitter: Jitter
+    label_port: Port
+    label_olt_name: Nombre
+    label_olt_host: Host
+    label_olt_model: Modelo
+    label_tx_power_average: TX Power AVG
+    label_psn: Pon Serial Number
+    label_sn: Serial Number
+
 
 
     
@@ -308,4 +321,7 @@ picker_find: Buscar
 rx_tx_title: Niveles de Rx / Tx
 cablemodems_with_lat_lng: cablemodems geolocalizados
 interface_cms_map_title: RX de cablemodems en la Interface
-consumption_subtitle: Consumo mensual acumulado
+consumption_subtitle: Consumo mensual acumulado
+ponport_onu_map_title: RX de onus en el PonPort
+onus_with_lat_lng: onus geolocalizadas
+tx_title: TX Power

+ 2 - 2
src/StatsBundle/Resources/views/PonPort/base_list_field_rx.html.twig

@@ -9,13 +9,13 @@
         <div class="ponport_div_rx_power">
         <table>
         <tr>
-            <td class="ponport_td_rx_power">
+            {# <td class="ponport_td_rx_power">
                 <span style="font-size:14px;">
                     <a class="sonata-action-element" href="{{ path('ponport_stats_map',{'id':object.getId()}) }}" title="{{ 'link_action_show_ponport_in_map'|trans({}, 'StatsBundle') }}">
                         <i class="fa fa-map-marker" aria-hidden="true"></i>
                     </a>
                 </span>
-            </td>
+            </td> #}
         {% for key,value in rx %}
             {% set style = "rx_ftth_bordo" %}
             {% if value < -30 %}

+ 11 - 0
src/StatsBundle/Resources/views/PonPort/base_show_v2.html.twig

@@ -0,0 +1,11 @@
+{% extends 'SonataAdminBundle:CRUD:base_show.html.twig' %}
+
+{% block show %}
+    <link rel="stylesheet" type="text/css" href="{{ asset('bundles/stats/css/style.css') }}">
+    {% include 'LeafletBundle:Leaflet:resources_only_leaflet.html.twig' %}
+    <script src="{{ asset('bundles/stats/highcharts/code/highcharts.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ asset('bundles/stats/highcharts/highchartsConfig.js') }}" type="text/javascript" charset="utf-8"></script>
+
+    {{ render(controller('StatsBundle:Stats:showPonPort', { 'object': object ,'from':admin.parameters.from, 'to':admin.parameters.to})) }}
+    
+{% endblock %}

+ 45 - 0
src/StatsBundle/Resources/views/Stats/Template/ponport_info_1.html.twig

@@ -0,0 +1,45 @@
+<div class="box box-widget">
+    <div class="box-body">
+        <table class="table table-hover table-condensed table-striped table-bordered">
+        <thead><th colspan=2>{{ 'list.label_port'|trans({}, 'StatsBundle') }}</th></thead>
+        <tbody>
+            <tr>
+                <td style="white-space: nowrap;">{{ 'list.label_port'|trans({}, 'StatsBundle') }}</td>
+                <td>
+                    {{ ponport.getPonPort|upper }}
+                </td>
+            </tr>
+            <tr>
+                <td style="white-space: nowrap;">{{ 'list.label_index'|trans({}, 'StatsBundle') }}</td>
+                <td>
+                    {% if ponport.getIndex is not null %}
+                        {{ponport.getIndex}}
+                    {% else %}
+                        <span class="no_defined">{{ 'no_defined'|trans({}, 'StatsBundle') }}</span>
+                    {% endif %}
+                </td>
+            </tr>
+        </table>
+        <br />
+       
+        <table class="table table-hover table-condensed table-striped table-bordered">
+        <thead><th colspan=2>{{ 'list.label_olt'|trans({}, 'StatsBundle') }}</th></thead>
+        <tbody>
+            {% for index, value in olt %}
+            {% set label = "list.label_" ~ index %}
+            <tr>
+                <td style="white-space: nowrap;">{{ label|trans({}, 'StatsBundle') }}</td>
+                <td>
+                    {% if value is not null %}
+                        {{value}}
+                    {% else %}
+                        <span class="no_defined">{{ 'no_defined'|trans({}, 'StatsBundle') }}</span>
+                    {% endif %}
+                </td>
+            </tr>
+            {% endfor %}    
+        </tbody>
+        </table>
+    </div>
+</div>
+

+ 42 - 0
src/StatsBundle/Resources/views/Stats/Template/ponport_onus.html.twig

@@ -0,0 +1,42 @@
+
+<table class="table">
+    <tbody>
+    {% if onus|length > 0 %}
+        <tr class="sonata-ba-view-container">
+            <th>{{ 'list.label_psn'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_sn'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_port'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_status'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_index'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_rx_power'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_tx_power'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_rx_power_olt'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_temperature'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_voltage'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_inOctets'|trans({},'StatsBundle') }}</th>
+            <th>{{ 'list.label_outOctets'|trans({},'StatsBundle') }}</th>
+        </tr>
+        {% for onu in onus %}
+            {% set style = 'opacity:0.5' %}
+            {% if onu['status'] %}
+                {% set style = 'opacity:1' %}
+            {% endif %}
+            <tr class="sonata-ba-view-container" style="{{style}}">
+                <td>{{onu['psn']}}</td>
+                <td>{{onu['sn']}}</td>
+                <td>{{onu['port']}}</td>
+                <td>{{onu['index']}}</td>
+                <td>{% include 'StatsBundle:Templates:macro_status.html.twig' with {'value': onu['status']} only %}</td>
+                <td>{% include 'StatsBundle:Templates:onu_field_rx.html.twig' with {'value': onu['rxPower']} only %}</td>
+                <td>{% include 'StatsBundle:Templates:onu_field_tx.html.twig' with {'value': onu['txPower']} only %}</td>
+                <td>{% include 'StatsBundle:Templates:onu_field_rx.html.twig' with {'value': onu['rxPowerOlt']} only %}</td>
+                <td>{{ onu['temperature']|number_format(2, '.', ',')}}</span> <span class="text_column_stats">ºC</span></td>
+                <td>{{ onu['voltage']|number_format(2, '.', ',')}}</span> <span class="text_column_stats">V</span></td>
+                <td>{% include '@Stats/Stats/Template/field_octets.html.twig' with {'value': onu['inOctets']} only %}</td>
+                <td>{% include '@Stats/Stats/Template/field_octets.html.twig' with {'value': onu['outOctets']} only %}</td>
+            </tr>
+        {% endfor %}
+    {% endif %}
+    </tbody>
+</table>
+    

+ 69 - 0
src/StatsBundle/Resources/views/Stats/Template/ponport_onus_location.html.twig

@@ -0,0 +1,69 @@
+<div style="padding: 10px">
+    <div style="text-align: center">
+    <span class="no_defined nas_data_origen">{{ 'ponport_onu_map_title'|trans({}, 'StatsBundle') }}
+    &nbsp;&nbsp;({{locations|length}} {{ 'onus_with_lat_lng'|trans({}, 'StatsBundle') }})
+    </span>
+    </div>
+    <div id="map"></div>
+</div>
+
+<br />
+
+<div class="col-sm-8">
+{% include '@Stats/Stats/picker.html.twig' %}
+</div>
+
+
+<script>
+
+/* --------------------- PROGRAMA PRINCIPAL ------------------------- */
+initializeMap();
+/* ------------------- FIN PROGRAMA PRINCIPAL ----------------------- */
+
+/* --------------------- Carga Mapa -------------------------------- */
+
+function initializeMap() {
+
+    
+    window.map = new L.Map('map', { center: new L.LatLng({{location['lat']}}, {{location['lng']}}), zoom: {{location['zoom']}} });
+
+    var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
+    var osmAttrib = '&copy; OpenStreetMap';
+    var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib });
+
+    var controlLayers = L.control.layers({
+        'OSM': osm.addTo(window.map),
+        "Google": L.tileLayer('http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}', {zIndex:1, attribution: '&copy; Google'})
+    }, {}, { position: 'topleft', collapsed: false });
+
+    
+    bounds = [];
+    
+    {% for mark in locations %}
+        var value = {{mark['rx']}};
+        var style = "firebrick";
+
+        if(value <= -30)
+            style = "firebrick";
+        else if(value > -30 && value < -28)
+            style = "red";
+        else if(value > -28 && value < -26)
+            style = "yellow";
+        else if(value > -26 && value < -20)
+            style = "green";
+        else if(value > -20 && value < -15)
+            style = "yellow";
+        else if(value > -15 && value < -13)
+            style = "red";
+        else {
+            style = "firebrick";
+        }
+
+        L.circleMarker([{{mark['lat']}}, {{mark['lng']}}], {color: style, fillOpacity: 0.6,radius: 8}).bindTooltip("{{mark['rx']}}", {permanent: true}).openTooltip().addTo(map)
+        bounds.push([{{mark['lat']}}, {{mark['lng']}}]);
+    {% endfor %}
+
+    map.fitBounds(bounds);
+}
+
+</script>

+ 25 - 0
src/StatsBundle/Resources/views/Stats/Template/ponport_tx_info.html.twig

@@ -0,0 +1,25 @@
+<table class="table table-condensed table-bordered" style="margin-top:57px; border-top:2px solid #3c8dbc;">
+<thead>
+    <th>
+    {{ 'list.label_tx_power_average'|trans({}, 'StatsBundle') }}
+    </th>
+</thead>
+<tbody>
+    {% if series['tx']['avg'] is not null and  series['tx']['avg'] > 0 %}
+    <tr>
+        <td>
+            <div>
+                <span style="font-weight: bold; font-size: 50px">
+                    {{ series['tx']['avg']|number_format(2,'.','') }} dBm
+                </span>
+            </div>
+        </td>
+    </tr>
+    {% else %}
+    <tr>
+        <td style="text-align:center">
+            <span class="no_defined">{{ 'no_defined'|trans({}, 'StatsBundle') }}</span>
+        </td>
+    </tr>
+    {% endif %}
+</table>

+ 236 - 0
src/StatsBundle/Resources/views/Stats/show_ponport.html.twig

@@ -0,0 +1,236 @@
+<div class="box box-primary">
+    <br />
+    <div class="box-body">
+        <div class="col-sm-12">
+            <div class="nav-tabs-custom">
+                <ul class="nav nav-tabs">
+                    <li class="active">
+                        <a href="#tab_1" data-toggle="tab">{{ 'Description'|trans({}, 'StatsBundle') }}</a>
+                    </li>
+                    <li>
+                        <a href="#tab_2" data-toggle="tab">{{ 'ONUs'|trans({}, 'StatsBundle') }} <span class="no_defined nas_data_origen">({{onus|length}})</span></a>
+                    </li>
+                    <li>
+                        <a href="#tab_3" data-toggle="tab">{{ 'Optical'|trans({}, 'StatsBundle') }} <span class="no_defined nas_data_origen"></span></a>
+                    </li>
+                </ul>
+
+                <div class="tab-content clearfix">
+                    
+                    {# TAB Description #}
+                    <div class="tab-pane active" id="tab_1">
+                        <div class="clearfix">
+                            <div class="col-sm-4">
+                                {% include '@Stats/Stats/Template/ponport_info_1.html.twig' %}
+                            </div>
+                            <div class="col-sm-8">
+                                {% include '@Stats/Stats/Template/ponport_onus_location.html.twig' %}
+                            </div>
+                            
+                        </div>
+                        <br />
+                        <div class="clearfix">
+                            <div class="col-sm-9" style="text-align:center">
+                                <div id="ponport_bandwidth" style="height: 400px;"></div>
+                            </div>
+                            <div class="col-sm-3">
+                                {% include '@Stats/Stats/Template/interface_bandwidth_info.html.twig' %}
+                            </div>
+                        </div>
+                        <br />
+                        
+                        <div class="clearfix">
+                            <div class="col-sm-9" style="text-align:center">
+                                <div id="ponport_tx" style="height: 400px;"></div>
+                            </div>
+                            <div class="col-sm-3">
+                                {% include '@Stats/Stats/Template/ponport_tx_info.html.twig' %}
+                            </div>
+                        </div>
+                        <br />
+                        
+                        <div class="clearfix">
+                            <div class="col-sm-9" style="text-align:center">
+                                <div id="ponport_onu" style="height: 400px;"></div>
+                            </div>
+                            <div class="col-sm-3">
+                                <div id="onu_count" style="width:75%; margin:0 auto"></div>
+                            </div>
+                        </div>
+                        <br />
+                        
+                    </div>
+
+
+                    {# TAB ONUs #}
+                    <div class="tab-pane" id="tab_2">
+                        {% include '@Stats/Stats/Template/ponport_onus.html.twig' %}
+                    </div>
+
+                    {# TAB Optical #}
+                    <div class="tab-pane" id="tab_3">
+                        <div class="clearfix">
+                        
+                            <div class="col-sm-12" style="text-align:center">
+                                <div id="ponport_rx" style="height: 400px; width: 100%"></div>
+                            </div>
+                            <br />
+                            <div class="col-sm-12">
+                                <div id="ponport_voltage" style="height: 400px; width: 100%"></div>
+                            </div>
+                            <br />
+                            <div class="col-sm-12">
+                                <div id="ponport_temperature" style="height: 400px; width: 100%"></div>
+                            </div>
+                        </div>
+                    </div>
+
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+<script type="text/javascript">
+
+var from = {{from}};
+var to = {{to}};
+var markerEnable = false;
+if((to - from) <= 21600) {
+    markerEnable = true;
+}
+
+
+Highcharts.chart('ponport_bandwidth', {
+    chart: {type: 'spline'},
+    title: {text: 'Bandwidth PonPort'},
+    subtitle: {text: 'IN Bandwidth / OUT Bandwidth'},
+    xAxis: {type: 'datetime',dateTimeLabelFormats: {month: '%e. %b',year: '%b'},title: {text: 'Date'}},
+    yAxis: {labels: {formatter: bandwidthAxisLabel,align: 'left'},min: 0},
+    tooltip: {formatter: bandwidthTooltip},
+    plotOptions: {series: {marker: {enabled: markerEnable}}, spline: {marker: {enabled: true}}},
+    series: [{
+        name: "IN Bandwidth",
+        data: {{series['in_bandwidth']['data']|json_encode}},
+        color: '#3f6833'
+        },{
+        name: "OUT Bandwidth",
+        data: {{series['out_bandwidth']['data']|json_encode}},
+        color: '#e24d42'
+    }]
+});
+
+Highcharts.chart('ponport_onu', {
+    chart: {type: 'area'},
+    title: {text: 'Onus'},
+    subtitle: {text: 'Online / Offline'},
+    xAxis: {type: 'datetime',dateTimeLabelFormats: {month: '%e. %b',year: '%b'},title: {text: 'Date'}},
+    yAxis: {min: 0,stackLabels: {enabled: false,style: {fontWeight: 'bold',color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'}}},
+    tooltip: {valueSuffix: ' onu',valueDecimals: 0},
+    plotOptions: {series: {marker: {enabled: markerEnable}}, area: {stacking: 'normal', dataLabels: {enabled: false, color: '#666666'}}},
+    series: [{
+        name: 'Online',
+        data: {{series['on']['data']|json_encode}},
+        color: '#3f6833'
+    }, {
+        name: 'Offline',
+        data: {{series['off']['data']|json_encode}},
+        color: '#e24d42'
+    }]
+});
+
+Highcharts.chart('onu_count', {
+    chart: {type: 'pie'},
+    title: {},
+    tooltip: {pointFormat: '{series.name}: <b>{point.y:.0f}</b>({point.percentage:.1f}%)'},
+    plotOptions: {pie: {allowPointSelect: true,cursor: 'pointer',dataLabels: {enabled: true,format: '<b>{point.name}</b>: {point.y:.0f} ({point.percentage:.1f} %)',style: {color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'}}}},
+    series: [{
+        name: 'Onus',
+        colorByPoint: true,
+        data: [{
+            name: 'Online',
+            y: {{status['online']}},
+            sliced: true,
+            selected: true,
+            color: '#3f6833'
+        }, {
+            name: 'Offline',
+            y: {{status['offline']}},
+            color: '#e24d42'
+        }]
+    }]
+});
+
+Highcharts.chart('ponport_tx', {
+    chart: {type: 'area'},
+    title: {text: '{{ 'tx_title'|trans({}, 'StatsBundle') }}'},
+    subtitle: {},
+    xAxis: {type: 'datetime',dateTimeLabelFormats: {month: '%e. %b',year: '%b'},title: {text: 'Date'}},
+    yAxis: {labels: {format: '{value} dBm'},min: null},
+    tooltip: {valueSuffix: ' dBm',valueDecimals: 2},
+    plotOptions: {series: {marker: {enabled: markerEnable}}, spline: {marker: {enabled: true}}},
+    legend: {enabled: false},
+    series: [{
+        name: "TX Power",
+        data: {{series['tx']['data']|json_encode}},
+        color: '#6ed0e0',
+        fillOpacity: 0.2
+    }]
+});
+
+Highcharts.chart('ponport_voltage', {
+    chart: {type: 'area'},
+    title: {text: 'Voltage'},
+    subtitle: {},
+    xAxis: {type: 'datetime',dateTimeLabelFormats: {month: '%e. %b',year: '%b'},title: {text: 'Date'}},
+    yAxis: {labels: {format: '{value} V'},min: 0},
+    tooltip: {valueSuffix: ' V',valueDecimals: 2},
+    plotOptions: {series: {marker: {enabled: markerEnable}}, spline: {marker: {enabled: true}}},
+    legend: {enabled: false},
+    series: [{
+        name: "Voltage",
+        data: {{series['voltage']['data']|json_encode}},
+        color: '#4841AD',
+        fillOpacity: 0.2
+    }]
+});
+
+Highcharts.chart('ponport_temperature', {
+    chart: {type: 'area'},
+    title: {text: 'Temperature'},
+    subtitle: {},
+    xAxis: {type: 'datetime',dateTimeLabelFormats: {month: '%e. %b',year: '%b'},title: {text: 'Date'}},
+    yAxis: {labels: {format: '{value} ºC'},min: 0},
+    tooltip: {valueSuffix: ' ºC',valueDecimals: 2},
+    plotOptions: {series: {marker: {enabled: markerEnable}}, spline: {marker: {enabled: true}}},
+    legend: {enabled: false},
+    series: [{
+        name: "Temperature",
+        data: {{series['temperature']['data']|json_encode}},
+        color: '#B75426',
+        fillOpacity: 0.2
+    }]
+});
+
+Highcharts.chart('ponport_rx', {
+    chart: {type: 'spline'},
+    title: {text: 'RX Power'},
+    subtitle: {},
+    xAxis: {type: 'datetime',dateTimeLabelFormats: {month: '%e. %b',year: '%b'},title: {text: 'Date'}},
+    yAxis: {labels: {format: '{value} dBm'},min: null},
+    tooltip: {valueSuffix: ' dBm',valueDecimals: 2},
+    plotOptions: {series: {marker: {enabled: markerEnable}}, spline: {marker: {enabled: true}}},
+    series: [
+        {% for sn in rxseries %}
+        {
+            name: "ONU {{sn}}",
+            data: {{series['rx_' ~ sn]['data']|json_encode}}
+        },
+        {% endfor %}
+    ]
+});
+
+
+
+</script>