mirror of
https://github.com/ShaYmez/HBmonitor.git
synced 2024-11-21 15:41:52 -05:00
Merge branch 'master' of https://github.com/n0mjs710/HBmonitor
This commit is contained in:
commit
1cd5c601b7
@ -1,10 +1,11 @@
|
|||||||
REPORT_NAME = 'system.domain.name' # Name of the monitored HBlink system
|
REPORT_NAME = 'system.domain.name' # Name of the monitored HBlink system
|
||||||
CONFIG_INC = True # Include HBlink stats
|
CONFIG_INC = True # Include HBlink stats
|
||||||
BRIDGES_INC = True # Include Bridge stats (confbrige.py)
|
BRIDGES_INC = True # Include Bridge stats (confbrige.py)
|
||||||
HBLINK_IP = '127.0.0.1' # HBlink's IP Address
|
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 '/'
|
||||||
|
@ -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
16
talkgroup_ids.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": "3120",
|
||||||
|
"callsign": "Kansas Statewide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "31201",
|
||||||
|
"callsign": "BYRG"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "310",
|
||||||
|
"callsign": "Kerchunk 310"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -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 %}
|
||||||
|
@ -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())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user