Skip to content
This repository has been archived by the owner on Sep 26, 2018. It is now read-only.

Subscriber status and activation report #64

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions cloud/endagaweb/static/css/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -504,22 +504,3 @@ div.message {
opacity: 1;
}
}

/* Reports chart */
.nv-label, .nv-legend-text {
text-transform: capitalize;
}
.nvtooltip {
text-transform: capitalize;
}
.display td {
text-align: center;
}
.display td:nth-child(1) {
background-color: #eee;
font-weight: bold;
}
.display td:nth-child(2) {
background-color: #eee;
font-weight: bold;
}
61 changes: 47 additions & 14 deletions cloud/endagaweb/stats_app/stats_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@
SMS_KINDS = [
'local_sms', 'local_recv_sms', 'outside_sms', 'incoming_sms', 'free_sms',
'error_sms']
SUBSCRIBER_KINDS = ['Provisioned', 'deactivate_number']
ZERO_BALANCE_SUBSCRIBER = ['zero_balance_subscriber']
INACTIVE_SUBSCRIBER = ['expired', 'first_expired', 'blocked']
USAGE_EVENT_KINDS = CALL_KINDS + SMS_KINDS + ['gprs'] + SUBSCRIBER_KINDS
USAGE_EVENT_KINDS = CALL_KINDS + SMS_KINDS + ['gprs']
TIMESERIES_STAT_KEYS = [
'ccch_sdcch4_load', 'tch_f_max', 'tch_f_load', 'sdcch8_max', 'tch_f_pdch_load', 'tch_f_pdch_max', 'tch_h_load', 'tch_h_max', 'sdcch8_load', 'ccch_sdcch4_max',
'sdcch_load', 'sdcch_available', 'tchf_load', 'tchf_available',
Expand Down Expand Up @@ -117,14 +114,6 @@ def aggregate_timeseries(self, param, **kwargs):
elif param in TIMESERIES_STAT_KEYS:
objects = models.TimeseriesStat.objects
filters = Q(key=param)
elif param in ZERO_BALANCE_SUBSCRIBER:
objects = models.UsageEvent.objects
filters = Q(oldamt__gt=0, newamt__lte=0)
elif param in INACTIVE_SUBSCRIBER:
aggregation = 'valid_through'
objects = models.Subscriber.objects
filters = Q(state=param)

# Filter by infrastructure level.
if self.level == 'tower':
filters = filters & Q(bts__id=self.level_id)
Expand All @@ -147,8 +136,6 @@ def aggregate_timeseries(self, param, **kwargs):
elif aggregation == 'average_value':
queryset_stats = qsstats.QuerySetStats(
queryset, 'date', aggregate=aggregates.Avg('value'))
elif aggregation == 'valid_through':
queryset_stats = qsstats.QuerySetStats(queryset, 'valid_through')
else:
queryset_stats = qsstats.QuerySetStats(queryset, 'date')
timeseries = queryset_stats.time_series(start, end, interval=interval)
Expand Down Expand Up @@ -394,3 +381,49 @@ def timeseries(self, key=None, **kwargs):
kwargs['aggregation'] = 'average_value'
return self.aggregate_timeseries(key, **kwargs)

class BTSStatsClient(StatsClientBase):
"""Gathers data on BTSStats instances at a tower and network level"""

def __init__(self, *args, **kwargs):
super(BTSStatsClient, self).__init__(*args, **kwargs)

def timeseries(self, kind=None, **kwargs):
results, usage, bts_values = ([] for i in range(3))

start_time = datetime.fromtimestamp(kwargs['start_time_epoch'],
pytz.utc)

# Limit end time to 7 days.
kwargs['end_time'] = start_time + timedelta(days=7)

try:
previous_state = models.SystemEvent.objects.filter(
bts_id=self.level_id, date__lt=start_time).order_by('-date')[0]
previous_state = previous_state.type
except IndexError:
previous_state = 'bts up'

for call_kind in BTS_KINDS:
# bts up
usage = self.aggregate_timeseries(call_kind, **kwargs)
values = [u[1] for u in usage]
results.append(values)
dates = [u[0] for u in usage]
# Get last state
last_val = None
bts_status = [sum(v) for v in zip(*results)]
for value in bts_status:
if last_val is None:
if previous_state == 'bts up':
last_val = 1
elif previous_state == 'bts up':
last_val = 0
# last_val = value
if value > 0:
last_val = 1
elif value < 0:
last_val = 0
bts_values.append(last_val)
return zip(dates, bts_values)


8 changes: 1 addition & 7 deletions cloud/endagaweb/stats_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@
CALL_KINDS = stats_client.CALL_KINDS + ['call']
GPRS_KINDS = ['total_data', 'uploaded_data', 'downloaded_data']
TIMESERIES_STAT_KEYS = stats_client.TIMESERIES_STAT_KEYS
SUBSCRIBER_KINDS = stats_client.SUBSCRIBER_KINDS + \
stats_client.ZERO_BALANCE_SUBSCRIBER + \
stats_client.INACTIVE_SUBSCRIBER
VALID_STATS = SMS_KINDS + CALL_KINDS + GPRS_KINDS + TIMESERIES_STAT_KEYS + \
SUBSCRIBER_KINDS
VALID_STATS = SMS_KINDS + CALL_KINDS + GPRS_KINDS + TIMESERIES_STAT_KEYS
# Set valid intervals.
INTERVALS = ['years', 'months', 'weeks', 'days', 'hours', 'minutes']
# Set valid aggregation types.
Expand Down Expand Up @@ -139,8 +135,6 @@ def get(self, request, infrastructure_level):
client_type = stats_client.GPRSStatsClient
elif stat_type in TIMESERIES_STAT_KEYS:
client_type = stats_client.TimeseriesStatsClient
elif stat_type in SUBSCRIBER_KINDS:
client_type = stats_client.SubscriberStatsClient
# Instantiate the client at an infrastructure level.
if infrastructure_level == 'global':
client = client_type('global')
Expand Down
7 changes: 1 addition & 6 deletions cloud/endagaweb/templates/dashboard/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" type="text/css"/>
<link href="/static/css/dashboard.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css">

<!-- Custom styles for this template -->
{% block pagestyle %}
Expand Down Expand Up @@ -74,11 +74,6 @@
<li><a href="/dashboard/towers"><i class="fa fa-signal"></i> Towers</a></li>
<li><a href="/dashboard/subscribers"><i class="fa fa-users"></i> Subscribers</a></li>
<li><a href="/dashboard/network"><i class="fa fa-cogs"></i> Network</a></li>
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-area-chart"></i> Reports</a>
<ul class="dropdown-menu">
<li><a href="{% url 'subscriber-report' %}?filter=Subscriber">Subscriber</a></li>
</ul>
</li>
</ul>

<ul class="nav navbar-nav navbar-top-links navbar-right navbar-user">
Expand Down
52 changes: 0 additions & 52 deletions cloud/endagaweb/templates/dashboard/report/filter.html

This file was deleted.

19 changes: 0 additions & 19 deletions cloud/endagaweb/templates/dashboard/report/header.html

This file was deleted.

83 changes: 83 additions & 0 deletions cloud/endagaweb/templates/dashboard/report/health.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{% extends "dashboard/layout.html" %}
{% comment %}
Copyright (c) 2016-present, Facebook, Inc.
All rights reserved.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
{% endcomment %}
{% load apptags %}

{% block title %}
{% tmpl_const "SITENAME" %} | towers
{% endblock %}

{% block pagestyle %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.14.30/css/bootstrap-datetimepicker.min.css">
{% endblock %}

{% block content %}
{% include "dashboard/report/header.html" with header='Health' %}

<div class='row'>
{% include "dashboard/report/nav.html" with active_tab='health_reports' %}
<div class='content col-xs-12 col-sm-10 col-md-10'>
{% include "dashboard/report/health-filter-action.html" with action_url='/dashboard/reports/health' %}
{% if network_has_activity %}
<div class="row">
<div id='health-chart'></div>
</div>
{% include 'dashboard/timezone-notice.html' %}
{% else %}
<p>There is no network activity to display.</p>
{% endif %}
</div> <!-- /.col-md-4 -->
</div>

{% endblock %}
{% block js %}
<script>
$(function() {
setTimeout(function() {
$('.timezone-notice').fadeIn(500);
}, 800);
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.14.30/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment.min.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<script src="/static/js/dashboard/saveSvgAsPng.js"></script>
<script type="text/jsx" src="/static/js/dashboard/report-chart-components.js"></script>
<script type="text/jsx">
var currentTimeEpoch = {{ current_time_epoch }};
var timezoneOffset = {{ timezone_offset }};
React.render(
<TimeseriesChartWithButtonsAndDatePickers
title='BTS Status'
chartID='call-chart'
statTypes='health_state'
level='tower'
levelID='{{ level_id }}'
defaultButtonText='day'
aggregation='bts_status'
buttons={['day','week']}
yAxisLabel='STATE'
currentTimeEpoch={currentTimeEpoch}
timezoneOffset={timezoneOffset}
tooltipUnits=''
chartType='line-chart'
info='This report shows BTS health status in terms of BTS uptime and downtime for each BTS for selected time window.'
/>,
document.getElementById('health-chart')
);
</script>


{% endblock %}
17 changes: 0 additions & 17 deletions cloud/endagaweb/templates/dashboard/report/nav.html

This file was deleted.

9 changes: 0 additions & 9 deletions cloud/endagaweb/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,6 @@
# OAuth login TODO(omar): setup OAuth provider
url(r'^staff-login/', endagaweb.views.user.staff_login_view),
url(r'^accounts/', include('allauth.urls')),
# Subscriber report graph
url(r'^dashboard/reports/subscriber',
endagaweb.views.reports.SubscriberReportView.as_view(),
name='subscriber-report'),
# Download csv for graph
url(r'^report/downloadcsv',
endagaweb.views.reports.ReportGraphDownload.as_view(),
),

]


Expand Down
Loading