diff --git a/README.md b/README.md index 76991d6..b8167d9 100644 --- a/README.md +++ b/README.md @@ -29,5 +29,9 @@ Actually known: Finally you should be able to get the new Dashboard calling the hostname of your hotspot and port 8000 (default) in your broser +## Credits + +*logtailer.py* is based on the work of http://shzhangji.com/blog/2017/07/15/log-tailer-with-websocket-and-python/ + ## Screenshots ![Screenshot of MMDVMDash Websocketboard](img/Screenshot.png "Screenshot of MMDVMDash Websocketboard") \ No newline at end of file diff --git a/html/index.html b/html/index.html index 3ff6c7b..a553987 100644 --- a/html/index.html +++ b/html/index.html @@ -49,6 +49,9 @@ + @@ -124,7 +127,27 @@ - +
+
+ +
Dapnet-Messages
+
+ +
+ + + + + + + + + +
Time (UTC)SlotRICMessage
+
+
+
+
@@ -145,8 +168,13 @@ var t_localh = $('#localHeard').DataTable( { "order": [[ 0, "desc" ]] } ); - var ws = new WebSocket("ws://" + window.location.hostname + ":5678"); - ws.onmessage = function (event) { + + var t_dapnet = $('#dapnetmessages').DataTable( { + "order": [[ 0, "desc" ]] + } ); + + var ws1 = new WebSocket("ws://" + window.location.hostname + ":5678/MMDVM"); + ws1.onmessage = function (event) { getLastHeard(document, event); getLocalHeard(document, event); }; @@ -170,6 +198,12 @@ $('#button').click( function () { t_qso.row('.selected').remove().draw( false ); } ); + + var ws2 = new WebSocket("ws://" + window.location.hostname + ":5678/DAPNET"); + ws2.onmessage = function (event) { + getDapnetMessages(document, event); + }; + t_dapnet.order( [ 0, 'desc' ] ).draw(); diff --git a/html/js/functions.js b/html/js/functions.js index 0824bfc..cc6a617 100644 --- a/html/js/functions.js +++ b/html/js/functions.js @@ -3,7 +3,7 @@ // M: 2020-11-01 21:33:27.454 YSF, received network data from DG2MAS to DG-ID 0 at DG2MAS // M: 2020-11-01 21:33:35.025 YSF, received network end of transmission from DG2MAS to DG-ID 0, 7.7 seconds, 0% packet loss, BER: 0.0% function getTimestamp(logline) { - return logline.substring(3,22); + return logline.substring(3,26); } function getMode(logline) { @@ -72,6 +72,58 @@ function getAddToQSO(logline) { retval = '
'; return retval; } +/* + +*/ +// 00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333 +// 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +// M: 2020-11-03 19:33:26.411 Sending message in slot 5 to 0000224, type 6, func Alphanumeric: "YYYYMMDDHHMMSS201103203300" +// M: 2020-11-03 19:36:00.124 Sending message in slot 13 to 0002504, type 5, func Numeric: "193600 031120" +// M: 2020-11-03 19:36:00.165 Sending message in slot 13 to 0000200, type 6, func Alphanumeric: "XTIME=1936031120XTIME=1936031120" +// M: 2020-11-03 19:36:00.216 Sending message in slot 13 to 0000216, type 6, func Alphanumeric: "YYYYMMDDHHMMSS201103193600" + +function getSlot(logline) { + return logline.substring(logline.indexOf("slot") + 5, logline.indexOf("to ")).trim(); +} + +function getRIC(logline) { + return logline.substring(logline.indexOf("to ") + 3, logline.indexOf(", type")).trim(); +} + +function getMessage(logline) { + message = logline.substring(logline.indexOf("ric:") + 6); + message = message.substring(0, message.length - 1); + if (4520 == parseInt(getRIC(logline))) { + message = rot1(message); + } + return message; +} + +function ord(str) { + return str.charCodeAt(0); +} + +function chr(n) { + return String.fromCharCode(n); +} + +function rot1(text) { + ric = 0; + slot = 0; + out = ""; + for (i = 0; i < text.length; i++) { + if (i == 0) { + ric = ord(text[i])-31; + } + if (i == 1) { + slot = ord(text[i])-32; + } + if (i > 1) { + out += chr(ord(text[i])-1); + } + } + return "Skyper-Rubric-No.: " + ric + ", Slot: " + slot + ", message: " + out; +} function clocktime() { var now = new Date(), @@ -106,60 +158,60 @@ function getLastHeard(document, event) { // M: 2020-11-01 21:33:27.454 YSF, received network data from DG2MAS to DG-ID 0 at DG2MAS // M: 2020-11-01 21:33:35.025 YSF, received network end of transmission from DG2MAS to DG-ID 0, 7.7 seconds, 0% packet loss, BER: 0.0% if (event.data.indexOf("Talker Alias") < 0 && event.data.indexOf("Downlink Activate") < 0 && event.data.indexOf("network watchdog") < 0 ) { - $(document).ready(function() { - var rowIndexes = [], - timestamp = getTimestamp(event.data), - mode = getMode(event.data), - callsign = getCallsign(event.data), - target = getTarget(event.data), - source = getSource(event.data), - duration = getDuration(event.data), - loss = getLoss(event.data), - ber = getBER(event.data), - addToQSO = getAddToQSO(event.data); - if (mode == "POCSAG") { - callsign = "POCSAG"; - target = ""; - source = ""; - duration = ""; - loss = ""; - ber = ""; - addToQSO = ""; - } - t_lh.rows( function ( idx, data, node ) { - if(data[2] === callsign){ - rowIndexes.push(idx); + $(document).ready(function() { + var rowIndexes = [], + timestamp = getTimestamp(event.data), + mode = getMode(event.data), + callsign = getCallsign(event.data), + target = getTarget(event.data), + source = getSource(event.data), + duration = getDuration(event.data), + loss = getLoss(event.data), + ber = getBER(event.data), + addToQSO = getAddToQSO(event.data); + if (mode == "POCSAG") { + callsign = "POCSAG"; + target = ""; + source = ""; + duration = ""; + loss = ""; + ber = ""; + addToQSO = ""; } - return false; - }); + t_lh.rows( function ( idx, data, node ) { + if(data[2] === callsign){ + rowIndexes.push(idx); + } + return false; + }); - if (rowIndexes[0]) { - newData = [ - timestamp, - mode, - callsign, - target, - source, - duration, - loss, - ber, - addToQSO - ] - t_lh.row(rowIndexes[0]).data( newData ).draw(); - } else { - t_lh.row.add( [ - timestamp, - mode, - callsign, - target, - source, - duration, - loss, - ber, - addToQSO - ] ).draw(); - } - }); + if (rowIndexes[0]) { + newData = [ + timestamp, + mode, + callsign, + target, + source, + duration, + loss, + ber, + addToQSO + ] + t_lh.row(rowIndexes[0]).data( newData ).draw(); + } else { + t_lh.row.add( [ + timestamp, + mode, + callsign, + target, + source, + duration, + loss, + ber, + addToQSO + ] ).draw(); + } + }); } } @@ -184,3 +236,23 @@ function getLocalHeard(document, event) { } }); } + +function getDapnetMessages(document, event) { + lines = event.data.split("\n"); + + //alert(line.indexOf("Sending") > 0); + $(document).ready(function() { + for (i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line.indexOf("Sending") > 0 ) { + t_dapnet.row.add( [ + getTimestamp(line), + getSlot(line), + getRIC(line), + getMessage(line) + ] ).draw(); + } + } + }); + +} diff --git a/logtailer.ini b/logtailer.ini index caa3bb9..fe889bb 100644 --- a/logtailer.ini +++ b/logtailer.ini @@ -7,3 +7,8 @@ Webport=8080 Logdir=/mnt/ramdisk/ Prefix=MMDVM Num_Lines=10000 + +[DAPNETGateway] +Logdir=/mnt/ramdisk/ +Prefix=DAPNETGateway + diff --git a/logtailer.py b/logtailer.py index 7f096ec..5723822 100644 --- a/logtailer.py +++ b/logtailer.py @@ -30,6 +30,12 @@ def view_log(websocket, path): logging.info('Connected, remote={}, path={}'.format(websocket.remote_address, path)) try: + try: + parse_result = urlparse(path) + except Exception: + raise ValueError('Fail to parse URL') + + path = os.path.abspath(parse_result.path) now = datetime.datetime.now() year = str(now.year) month = str(now.month) @@ -39,19 +45,22 @@ def view_log(websocket, path): if len(day) == 1: day = "0" + day - file_path = config['MMDVMHost']['Logdir']+config['MMDVMHost']['Prefix']+"-"+year+"-"+month+"-"+day+".log" - + file_path = "" + if path == "/MMDVM": + file_path = config['MMDVMHost']['Logdir']+config['MMDVMHost']['Prefix']+"-"+year+"-"+month+"-"+day+".log" + elif path == "/DAPNET": + file_path = config['DAPNETGateway']['Logdir']+config['DAPNETGateway']['Prefix']+"-"+year+"-"+month+"-"+day+".log" + logging.info(file_path) if not os.path.isfile(file_path): raise ValueError('Not found') - path = file_path - with open(file_path) as f: + with open(file_path, newline = '\n') as f: content = ''.join(deque(f, NUM_LINES)) content = conv.convert(content, full=False) lines = content.split("\n") for line in lines: - if line.find('received') >0 and not line.find('network watchdog') > 0: + if line.find('received') >0 or line.find('Sending') > 0: yield from websocket.send(line) while True: