diff --git a/confbridge.py b/confbridge.py index b24c498..cca39db 100755 --- a/confbridge.py +++ b/confbridge.py @@ -49,6 +49,7 @@ from twisted.internet import task from binascii import b2a_hex as ahex from time import time from importlib import import_module +from cPickle import dump as pickle_dump import sys @@ -72,7 +73,7 @@ TS_CLEAR_TIME = .2 # Build the conference bridging structure from the bridge file. # -def make_bridges(_confbridge_rules): +def make_bridge_config(_confbridge_rules): try: bridge_file = import_module(_confbridge_rules) logger.info('Bridge configuration file found and imported') @@ -97,7 +98,7 @@ def make_bridges(_confbridge_rules): _system['TIMEOUT'] = _system['TIMEOUT']*60 _system['TIMER'] = time() + _system['TIMEOUT'] - return bridge_file.BRIDGES + return {'BRIDGE_CONF': bridge_file.BRIDGE_CONF, 'BRIDGES': bridge_file.BRIDGES} # Import subscriber ACL @@ -169,6 +170,14 @@ def rule_timer_loop(): else: logger.debug('Conference Bridge NO ACTION: System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID'])) + if BRIDGE_CONF['REPORT']: + try: + with open(CONFIG['REPORTS']['REPORT_PATH']+'confbridge_stats.pickle', 'wb') as file: + pickle_dump(BRIDGES, file, 2) + file.close() + except IOError as detail: + _logger.error('I/O Error: %s', detail) + class confbridgeIPSC(IPSC): def __init__(self, _name, _config, _logger): @@ -410,8 +419,10 @@ if __name__ == '__main__': if talkgroup_ids: logger.info('ID ALIAS MAPPER: talkgroup_ids dictionary is available') - # Build the routing rules file - BRIDGES = make_bridges('confbridge_rules') + # Build the routing rules and other configuration + CONFIG_DICT = make_bridge_config('confbridge_rules') + BRIDGE_CONF = CONFIG_DICT['BRIDGE_CONF'] + BRIDGES = CONFIG_DICT['BRIDGES'] # Build the Access Control List ACL = build_acl('sub_acl') diff --git a/confbridge_rules_SAMPLE.py b/confbridge_rules_SAMPLE.py index 2c0a82e..022f2ef 100644 --- a/confbridge_rules_SAMPLE.py +++ b/confbridge_rules_SAMPLE.py @@ -28,6 +28,16 @@ configuration file. ''' +# CONFIGURATION ITEMS SPECIFICALLY FOR confbridge.py +# +# REPORT: +# True or False. True if you want to write a pickle file of the current rule file +# state. This is useful (and necessary) for reporting features to be active. +# The path follows the reporting path in the main dmrlink.cfg file. +BRIDGE_CONF = { + 'REPORT': True, + } + BRIDGES = { 'WORLDWIDE': [ {'SYSTEM': 'MASTER-1', 'TS': 1, 'TGID': 1, 'ACTIVE': True, 'TIMEOUT': 2, 'TO_TYPE': 'ON', 'ON': [2,], 'OFF': [9,10]}, diff --git a/html_confbridge_stats.py b/html_confbridge_stats.py new file mode 100755 index 0000000..1065ad2 --- /dev/null +++ b/html_confbridge_stats.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +############################################################################### +# Copyright (C) 2017 Cortney T. Buffington, N0MJS +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of tde GNU General Public License as published by +# the Free Software Foundation; eitder version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +############################################################################### + +from __future__ import print_function +from cPickle import load +from pprint import pprint +from time import ctime +from twisted.internet import reactor +from twisted.internet import task +from binascii import b2a_hex as h +from dmr_utils.utils import int_id, get_alias + +__autdor__ = 'Cortney T. Buffington, N0MJS' +__copyright__ = 'Copyright (c) 2017 Cortney T. Buffington, N0MJS' +__license__ = 'GNU GPLv3' +__maintainer__ = 'Cort Buffington, N0MJS' +__email__ = 'n0mjs@me.com' + + +# This is the only user-configuration necessary +# Tell the program where the pickle file is +# Tell the program where to write the html table file +# Tell the program how often to print a report -- should match dmrlink report period +stat_file = '../confbridge_stats.pickle' +html_table_file = '../confbridge_stats.html' +frequency = 30 + +def read_dict(): + try: + with open(stat_file, 'rb') as file: + NETWORK = load(file) + return NETWORK + except IOError as detail: + print('I/O Error: {}'.format(detail)) + except EOFError: + print('EOFError') + +def write_file(_string): + try: + with open(html_table_file, 'w') as file: + file.write(_string) + file.close() + except IOError as detail: + print('I/O Error: {}'.format(detail)) + except EOFError: + print('EOFError') + +def build_table(): + NETWORK = read_dict() + if NETWORK != 'None': + stuff = 'Last Update: {}'.format(ctime()) + stuff += '' + + for ipsc in NETWORK: + stat = NETWORK[ipsc]['MASTER']['STATUS'] + master = NETWORK[ipsc]['LOCAL']['MASTER_PEER'] + + stuff += '

' + + stuff += '\ + \ + \ + \ + \ + \ + \ + \ + ' + + stuff += '
{} '.format(ipsc) + if master: + stuff += '(master)' + else: + stuff += '(peer)' + stuff +='