This commit is contained in:
Cort Buffington 2019-03-02 13:29:33 -06:00
commit 1cd5c601b7
5 changed files with 59 additions and 16 deletions

View File

@ -5,6 +5,7 @@ HBLINK_IP = '127.0.0.1' # HBlink's IP Address
HBLINK_PORT = 4321 # HBlink's TCP reporting socket HBLINK_PORT = 4321 # HBlink's TCP reporting socket
FREQUENCY = 10 # Frequency to push updates to web clients FREQUENCY = 10 # Frequency to push updates to web clients
WEB_SERVER_PORT = 8080 # Has to be above 1024 if you're not running as root WEB_SERVER_PORT = 8080 # Has to be above 1024 if you're not running as root
CLIENT_TIMEOUT = 300 # Clients are timed out after this many seconds, 0 to disable
# Files and stuff for loading alias files for mapping numbers to names # Files and stuff for loading alias files for mapping numbers to names
PATH = './' # MUST END IN '/' PATH = './' # MUST END IN '/'

View File

@ -71,6 +71,7 @@
<body style="font: 10pt arial, sans-serif"> <body style="font: 10pt arial, sans-serif">
<h1><center>HBlink Monitoring Server</center></h1> <h1><center>HBlink Monitoring Server</center></h1>
<h3><center><<<system_name>>></center></h3> <h3><center><<<system_name>>></center></h3>
<p><center><<<timeout_warning>>></center></p>
<hr> <hr>
<noscript>You must enable JavaScript</noscript> <noscript>You must enable JavaScript</noscript>
<style>table, td, th {border: .5px solid black; padding: 2px; border-collapse: collapse; text-align:center;}</style> <style>table, td, th {border: .5px solid black; padding: 2px; border-collapse: collapse; text-align:center;}</style>
@ -82,7 +83,7 @@
<hr> <hr>
<center> <center>
Copyright (c) 2016, 2017, 2018<br>The Founding Members of the K0USY Group. All rights reserved. Copyright (c) 2016, 2017, 2018, 2019<br>The Regents of the K0USY Group. All rights reserved.
<!-- THIS COPYRIGHT NOTICE MUST BE DISPLAYED AS A CONDITION OF THE LICENCE GRANT FOR THIS SOFTWARE. ALL DERIVATEIVES WORKS MUST CARRY THIS NOTICE --> <!-- THIS COPYRIGHT NOTICE MUST BE DISPLAYED AS A CONDITION OF THE LICENCE GRANT FOR THIS SOFTWARE. ALL DERIVATEIVES WORKS MUST CARRY THIS NOTICE -->
</body> </body>
</html> </html>

16
talkgroup_ids.json Normal file
View File

@ -0,0 +1,16 @@
{
"results": [
{
"id": "3120",
"callsign": "Kansas Statewide"
},
{
"id": "31201",
"callsign": "BYRG"
},
{
"id": "310",
"callsign": "Kerchunk 310"
}
]
}

View File

@ -83,7 +83,7 @@
<tr> <tr>
<td style="font-weight:bold"> {{ _openbridge}} </td> <td style="font-weight:bold"> {{ _openbridge}} </td>
<td>{{ _table['OPENBRIDGES'][_openbridge]['NETWORK_ID'] }}<br><div style="font: 8pt arial, sans-serif">{{ _table['OPENBRIDGES'][_openbridge]['TARGET_IP'] }}:{{ _table['OPENBRIDGES'][_openbridge]['TARGET_PORT'] }}</div></td> <td>{{ _table['OPENBRIDGES'][_openbridge]['NETWORK_ID'] }}<br><div style="font: 8pt arial, sans-serif">{{ _table['OPENBRIDGES'][_openbridge]['TARGET_IP'] }}:{{ _table['OPENBRIDGES'][_openbridge]['TARGET_PORT'] }}</div></td>
<td>{% for entry in _table['OPENBRIDGES'][_openbridge]['STREAMS'] %}({{ _table['OPENBRIDGES'][_openbridge]['STREAMS'][entry][0] }} >> {{ _table['OPENBRIDGES'][_openbridge]['STREAMS'][entry][1] }}) {% endfor %}</td> <td>{% for entry in _table['OPENBRIDGES'][_openbridge]['STREAMS'] %}({{ _table['OPENBRIDGES'][_openbridge]['STREAMS'][entry][0] }} | {{ _table['OPENBRIDGES'][_openbridge]['STREAMS'][entry][1] }} >> {{ _table['OPENBRIDGES'][_openbridge]['STREAMS'][entry][2] }}) {% endfor %}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# #
############################################################################### ###############################################################################
# Copyright (C) 2016 Cortney T. Buffington, N0MJS <n0mjs@me.com> # Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS <n0mjs@me.com>
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -50,9 +50,8 @@ from jinja2 import Environment, PackageLoader, select_autoescape
# Utilities from K0USY Group sister project # Utilities from K0USY Group sister project
from dmr_utils.utils import int_id, get_alias, try_download, mk_full_id_dict, hex_str_4 from dmr_utils.utils import int_id, get_alias, try_download, mk_full_id_dict, hex_str_4
# Configuration variables and IPSC constants # Configuration variables and constants
from config import * from config import *
#from ipsc_const import *
# Opcodes for reporting protocol to HBlink # Opcodes for reporting protocol to HBlink
OPCODE = { OPCODE = {
@ -341,6 +340,21 @@ def build_stats():
dashboard_server.broadcast(table) dashboard_server.broadcast(table)
build_time = now build_time = now
def timeout_clients():
now = time()
try:
for client in dashboard_server.clients:
if dashboard_server.clients[client] + CLIENT_TIMEOUT < now:
logger.info('TIMEOUT: disconnecting client %s', dashboard_server.clients[client])
try:
dashboard.sendClose(client)
except Exception as e:
logger.error('Exception caught parsing client timeout %s', e)
except:
logger.info('CLIENT TIMEOUT: List does not exist, skipping. If this message persists, contact the developer')
def rts_update(p): def rts_update(p):
callType = p[0] callType = p[0]
action = p[1] action = p[1]
@ -380,7 +394,7 @@ def rts_update(p):
if system in CTABLE['OPENBRIDGES']: if system in CTABLE['OPENBRIDGES']:
if action == 'START': if action == 'START':
CTABLE['OPENBRIDGES'][system]['STREAMS'][streamId] = (alias_call(sourceSub, subscriber_ids), destination) CTABLE['OPENBRIDGES'][system]['STREAMS'][streamId] = (trx, alias_call(sourceSub, subscriber_ids), destination)
if action == 'END': if action == 'END':
if streamId in CTABLE['OPENBRIDGES'][system]['STREAMS']: if streamId in CTABLE['OPENBRIDGES'][system]['STREAMS']:
del CTABLE['OPENBRIDGES'][system]['STREAMS'][streamId] del CTABLE['OPENBRIDGES'][system]['STREAMS'][streamId]
@ -539,22 +553,21 @@ class dashboard(WebSocketServerProtocol):
def onClose(self, wasClean, code, reason): def onClose(self, wasClean, code, reason):
logging.info('WebSocket connection closed: %s', reason) logging.info('WebSocket connection closed: %s', reason)
class dashboardFactory(WebSocketServerFactory): class dashboardFactory(WebSocketServerFactory):
def __init__(self, url): def __init__(self, url):
WebSocketServerFactory.__init__(self, url) WebSocketServerFactory.__init__(self, url)
self.clients = [] self.clients = {}
def register(self, client): def register(self, client):
if client not in self.clients: if client not in self.clients:
logging.info('registered client %s', client.peer) logging.info('registered client %s', client.peer)
self.clients.append(client) self.clients[client] = time()
def unregister(self, client): def unregister(self, client):
if client in self.clients: if client in self.clients:
logging.info('unregistered client %s', client.peer) logging.info('unregistered client %s', client.peer)
self.clients.remove(client) del self.clients[client]
def broadcast(self, msg): def broadcast(self, msg):
logging.debug('broadcasting message to: %s', self.clients) logging.debug('broadcasting message to: %s', self.clients)
@ -581,21 +594,25 @@ if __name__ == '__main__':
logging.basicConfig( logging.basicConfig(
level=logging.INFO, level=logging.INFO,
filename = (LOG_PATH + LOG_NAME), filename = (LOG_PATH + LOG_NAME),
filemode='a' filemode='a',
format='%(asctime)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
) )
console = logging.StreamHandler() console = logging.StreamHandler()
console.setLevel(logging.INFO) console.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console) logging.getLogger('').addHandler(console)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logging.info('web_tables.py starting up') logging.info('web_tables.py starting up')
logger.info('\n\nCopyright (c) 2017, 2018\n\tThe Founding Members of the K0USY Group. All rights reserved.\n') logger.info('\n\nCopyright (c) 2016, 2017, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n')
# Download alias files # Download alias files
result = try_download(PATH, 'peer_ids.csv', PEER_URL, (FILE_RELOAD * 86400)) result = try_download(PATH, PEER_FILE, PEER_URL, (FILE_RELOAD * 86400))
logging.info(result) logging.info(result)
result = try_download(PATH, 'subscriber_ids.csv', SUBSCRIBER_URL, (FILE_RELOAD * 86400)) result = try_download(PATH, SUBSCRIBER_FILE, SUBSCRIBER_URL, (FILE_RELOAD * 86400))
logging.info(result) logging.info(result)
# Make Alias Dictionaries # Make Alias Dictionaries
@ -633,11 +650,19 @@ if __name__ == '__main__':
# Create Static Website index file # Create Static Website index file
index_html = get_template(PATH + 'index_template.html') index_html = get_template(PATH + 'index_template.html')
index_html = index_html.replace('<<<system_name>>>', REPORT_NAME) index_html = index_html.replace('<<<system_name>>>', REPORT_NAME)
if CLIENT_TIMEOUT > 0:
index_html = index_html.replace('<<<timeout_warning>>>', 'Continuous connections not allowed. Connections time out in {} seconds'.format(CLIENT_TIMEOUT))
else:
index_html = index_html.replace('<<<timeout_warning>>>', '')
# Start update loop # Start update loop
update_stats = task.LoopingCall(build_stats) update_stats = task.LoopingCall(build_stats)
update_stats.start(FREQUENCY) update_stats.start(FREQUENCY)
# Start a timout loop
timeout = task.LoopingCall(timeout_clients)
timeout.start(10)
# Connect to HBlink # Connect to HBlink
reactor.connectTCP(HBLINK_IP, HBLINK_PORT, reportClientFactory()) reactor.connectTCP(HBLINK_IP, HBLINK_PORT, reportClientFactory())