diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-09-24 19:42:01 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-09-24 20:47:08 +0200 |
commit | 5ad01f6415710521173e7a612b32c982847eada4 (patch) | |
tree | 4d4c8ca0a7ce0ff0f81702ee7bfad0b57c899929 /gui | |
parent | 5bb71419937a4d8919ef33df088f73e6c705b028 (diff) | |
download | dabmod-5ad01f6415710521173e7a612b32c982847eada4.tar.gz dabmod-5ad01f6415710521173e7a612b32c982847eada4.tar.bz2 dabmod-5ad01f6415710521173e7a612b32c982847eada4.zip |
gui: use json for all API answers
Diffstat (limited to 'gui')
-rw-r--r-- | gui/README.md | 2 | ||||
-rwxr-xr-x | gui/api/__init__.py | 24 | ||||
-rwxr-xr-x | gui/run.py | 16 | ||||
-rw-r--r-- | gui/static/js/odr-modulator.js | 52 | ||||
-rw-r--r-- | gui/static/js/odr-predistortion.js | 40 | ||||
-rw-r--r-- | gui/static/js/odr-rcvalues.js | 31 | ||||
-rw-r--r-- | gui/static/js/odr.js | 109 | ||||
-rw-r--r-- | gui/templates/modulator.html | 80 | ||||
-rw-r--r-- | gui/templates/predistortion.html | 38 |
9 files changed, 209 insertions, 183 deletions
diff --git a/gui/README.md b/gui/README.md index 0094a8d..ec55bc9 100644 --- a/gui/README.md +++ b/gui/README.md @@ -13,7 +13,7 @@ Make it easier to discover the tuning possibilities of the modulator. Install ------- -Install dependencies: cherrypy and jinja2 python modules +Install dependencies: cherrypy, jinja2, scipy, matplotlib, zmq python modules Run --- diff --git a/gui/api/__init__.py b/gui/api/__init__.py index 6c04a64..74f5feb 100755 --- a/gui/api/__init__.py +++ b/gui/api/__init__.py @@ -30,6 +30,12 @@ import os import io import datetime +def send_ok(data): + return json.dumps({'status' : 'ok', 'data': data}).encode() + +def send_error(data, reason=""): + return json.dumps({'status' : 'error', 'reason': reason}).encode() + class API: def __init__(self, mod_rc, dpd): self.mod_rc = mod_rc @@ -42,7 +48,7 @@ class API: @cherrypy.expose def rc_parameters(self): cherrypy.response.headers["Content-Type"] = "application/json" - return json.dumps(self.mod_rc.get_modules()).encode() + return send_ok(self.mod_rc.get_modules()) @cherrypy.expose def parameter(self, **kwargs): @@ -55,24 +61,24 @@ class API: self.mod_rc.set_param_value(params['controllable'], params['param'], params['value']) except ValueError as e: cherrypy.response.status = 400 - return "{}".format(e) - return json.dumps("ok").encode() + return send_error(str(e)) + return send_ok(None) else: cherrypy.response.headers["Content-Type"] = "application/json" cherrypy.response.status = 400 - return json.dumps("POST only").encode() + return send_error("POST only") @cherrypy.expose def trigger_capture(self, **kwargs): if cherrypy.request.method == 'POST': - cherrypy.response.headers["Content-Type"] = "text/plain" - return self.dpd.capture_samples() + cherrypy.response.headers["Content-Type"] = "application/json" + return send_ok(self.dpd.capture_samples()) else: - cherrypy.response.headers["Content-Type"] = "text/plain" + cherrypy.response.headers["Content-Type"] = "application/json" cherrypy.response.status = 400 - return "POST only" + return send_error("POST only") @cherrypy.expose def dpd_status(self, **kwargs): cherrypy.response.headers["Content-Type"] = "application/json" - return json.dumps(self.dpd.status()).encode() + return send_ok(self.dpd.status()) @@ -32,6 +32,8 @@ import dpd env = Environment(loader=FileSystemLoader('templates')) +base_js = ["js/odr.js"] + class Root: def __init__(self, config_file): self.config_file = config_file @@ -47,31 +49,29 @@ class Root: @cherrypy.expose def about(self): tmpl = env.get_template("about.html") - js = [] - return tmpl.render(tab='about', js=js, is_login=False) + return tmpl.render(tab='about', js=base_js, is_login=False) @cherrypy.expose def home(self): tmpl = env.get_template("home.html") - js = [] - return tmpl.render(tab='home', js=js, is_login=False) + return tmpl.render(tab='home', js=base_js, is_login=False) @cherrypy.expose def rcvalues(self): tmpl = env.get_template("rcvalues.html") - js = ["js/odr-rcvalues.js"] + js = base_js + ["js/odr-rcvalues.js"] return tmpl.render(tab='rcvalues', js=js, is_login=False) @cherrypy.expose def modulator(self): tmpl = env.get_template("modulator.html") - js = ["js/odr-modulator.js"] + js = base_js + ["js/odr-modulator.js"] return tmpl.render(tab='modulator', js=js, is_login=False) @cherrypy.expose def predistortion(self): tmpl = env.get_template("predistortion.html") - js = ["js/odr-predistortion.js"] + js = base_js + ["js/odr-predistortion.js"] return tmpl.render(tab='predistortion', js=js, is_login=False) if __name__ == '__main__': @@ -93,10 +93,10 @@ if __name__ == '__main__': errorlog = os.path.realpath(os.path.join(config.config['global']['logs_directory'], 'error.log')) cherrypy.config.update({ + 'engine.autoreload.on': True, 'server.socket_host': config.config['global']['host'], 'server.socket_port': int(config.config['global']['port']), 'request.show_tracebacks' : True, - 'environment': 'production', 'tools.sessions.on': False, 'tools.encode.on': True, 'tools.encode.encoding': "utf-8", diff --git a/gui/static/js/odr-modulator.js b/gui/static/js/odr-modulator.js index 273d9f7..8538645 100644 --- a/gui/static/js/odr-modulator.js +++ b/gui/static/js/odr-modulator.js @@ -18,48 +18,6 @@ // You should have received a copy of the GNU General Public License // along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. -function set_rc(controllable, param, value, callback) { - $.ajax({ - type: "POST", - url: "/api/parameter", - contentType: 'application/json', - dataType: 'json', - data: JSON.stringify({ - controllable: controllable, - param: param, - value: value - }), - - error: function(data) { - $.gritter.add({ - title: 'RC set', - text: "ERROR", - image: '/fonts/warning.png', - sticky: true, - }); - }, - success: callback - }); -} - -function getRc(callback) { - $.ajax({ - type: "GET", - url: "/api/rc_parameters", - contentType: 'application/json', - dataType: 'json', - - error: function(data) { - $.gritter.add({ - title: 'RC info', - text: "ERROR: ", - image: '/fonts/warning.png', - sticky: true, - }); - }, - success: callback - }); -} function requestAllParams(callback) { getRc(function(data) { @@ -86,21 +44,21 @@ $(function(){ requestAllParams(); $('#setdigitalgain').click(function() { - set_rc("gain", "digital", $('#digitalgain').val(), + setRc("gain", "digital", $('#digitalgain').val(), requestAllParams); }); $('#setwindowlength').click(function() { - set_rc("guardinterval", "windowlen", $('#windowlength').val(), + setRc("guardinterval", "windowlen", $('#windowlength').val(), requestAllParams); }); $('#setclip').click(function() { - set_rc("ofdm", "clip", $('#cfrclip').val(), + setRc("ofdm", "clip", $('#cfrclip').val(), requestAllParams); - set_rc("ofdm", "errorclip", $('#cfrerrorclip').val(), + setRc("ofdm", "errorclip", $('#cfrerrorclip').val(), requestAllParams); - set_rc("ofdm", "cfr", + setRc("ofdm", "cfr", ($('#cfrenable').prop("checked") ? "1" : "0"), requestAllParams); }); diff --git a/gui/static/js/odr-predistortion.js b/gui/static/js/odr-predistortion.js index dce3922..13dac7a 100644 --- a/gui/static/js/odr-predistortion.js +++ b/gui/static/js/odr-predistortion.js @@ -20,46 +20,14 @@ $(function(){ $('#capturebutton').click(function() { - $.ajax({ - type: "POST", - url: "/api/trigger_capture", - contentType: 'text/plain', - dataType: '', - data: '', - - error: function(data) { - $.gritter.add({ - title: 'Capture trigger', - text: "ERROR", - image: '/fonts/warning.png', - sticky: true, - }); - }, - success: function(data) { - $('#capturestatus').val(data); - }, + doApiRequestPOST("/api/trigger_capture", {}, function(data) { + $('#capturestatus').val(data); }); }); $('#dpdstatusbutton').click(function() { - $.ajax({ - type: "GET", - url: "/api/dpd_status", - contentType: 'application/json', - dataType: '', - data: '', - - error: function(data) { - $.gritter.add({ - title: 'DPD Status Update', - text: "ERROR", - image: '/fonts/warning.png', - sticky: true, - }); - }, - success: function(data) { - $('#dpdstatus').val(data); - }, + doApiRequestGET("/api/dpd_status", function(data) { + $('#dpdstatus').val(data); }); }); }); diff --git a/gui/static/js/odr-rcvalues.js b/gui/static/js/odr-rcvalues.js index 6d53e8d..f40279d 100644 --- a/gui/static/js/odr-rcvalues.js +++ b/gui/static/js/odr-rcvalues.js @@ -21,30 +21,15 @@ function requestStatus(callback) { $('#rctable > tbody').empty(); - $.ajax({ - type: "GET", - url: "/api/rc_parameters", - contentType: 'application/json', - dataType: 'json', - - error: function(data) { - $.gritter.add({ - title: 'RC info', - text: "ERROR: ", - image: '/fonts/warning.png', - sticky: true, - }); - }, - success: function(data) { - $.each( data, function( key1, controllable ) { - $.each( controllable, function( key2, param ) { - $('#rctable > tbody:last').append( - '<tr><td>'+key1+'.'+key2+'</td>'+ - '<td>'+param['value']+'</td>'+ - '<td>'+param['help']+'</td></tr>'); - }); + doApiRequestGET("/api/rc_parameters", function(data) { + $.each( data, function( key1, controllable ) { + $.each( controllable, function( key2, param ) { + $('#rctable > tbody:last').append( + '<tr><td>'+key1+'.'+key2+'</td>'+ + '<td>'+param['value']+'</td>'+ + '<td>'+param['help']+'</td></tr>'); }); - } + }); }); } diff --git a/gui/static/js/odr.js b/gui/static/js/odr.js new file mode 100644 index 0000000..ecb02c5 --- /dev/null +++ b/gui/static/js/odr.js @@ -0,0 +1,109 @@ +// Copyright (C) 2018 +// Matthias P. Braendli, matthias.braendli@mpb.li +// +// http://www.opendigitalradio.org +// +// This file is part of ODR-DabMod. +// +// ODR-DabMod is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// ODR-DabMod 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 ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. + + +function doApiRequestGET(uri, callback) { + $.ajax({ + type: "GET", + url: uri, + contentType: 'application/json', + dataType: 'json', + + error: function(data) { + if (data.status == 500) { + var errorWindow = window.open("", "_self"); + errorWindow.document.write(data.responseText); + } + else { + $.gritter.add({ title: 'API', + text: "AJAX failed: " + data.statusText, + image: '/fonts/warning.png', + sticky: true, + }); + } + }, + success: function(data) { + if (data.status == 'ok') { + callback(data.data); + } + else { + $.gritter.add({ + title: 'API', + text: "API ERROR: " + data.reason, + image: '/fonts/warning.png', + sticky: true, + }); + } + } + }); +} + +function doApiRequestPOST(uri, data, callback) { + $.ajax({ + type: "POST", + url: uri, + contentType: 'application/json', + dataType: 'json', + data: JSON.stringify(data), + + error: function(data) { + if (data.status == 500) { + var errorWindow = window.open("", "_self"); + errorWindow.document.write(data.responseText); + } + else { + $.gritter.add({ + title: 'API', + text: "AJAX failed: " + data.statusText, + image: '/fonts/warning.png', + sticky: true, + }); + } + }, + + success: function(data_in) { + if (data_in.status == 'ok') { + callback(data_in.data); + } + else { + $.gritter.add({ + title: 'API', + text: "API ERROR: " + data_in.reason, + image: '/fonts/warning.png', + sticky: true, + }); + } + } + }); +} + +function setRc(controllable, param, value, callback) { + var data = { + controllable: controllable, + param: param, + value: value + }; + doApiRequestPOST("/api/parameter/", data, callback); +} + +function getRc(callback) { + doApiRequestGET("/api/rc_parameters", callback); +} + diff --git a/gui/templates/modulator.html b/gui/templates/modulator.html index 07e7a82..6deffb1 100644 --- a/gui/templates/modulator.html +++ b/gui/templates/modulator.html @@ -24,50 +24,50 @@ along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. {% include 'head.html' %} <body> - {% include 'body-nav.html' %} + {% include 'body-nav.html' %} - <div class="container-fluid"> - <div class="panel-group"> - <div class="panel panel-default"> - <div class="panel-body"> - <h3>Gain</h3> - <div class="form-group"> - <label for="digitalgain">Digital Gain:</label> - <input type="text" class="form-control" id="digitalgain"> - <button type="button" class="btn btn-sm btn-info" id="setdigitalgain">Set</button> - </div> - </div> - <div class="panel-body"> - <h3>OFDM Windowing</h3> - <div class="form-group"> - <label for="windowlength">Window length:</label> - <input type="text" class="form-control" id="windowlength"> - <button type="button" class="btn btn-sm btn-info" id="setwindowlength">Set</button> - </div> - </div> - <div class="panel-body"> - <h3>CFR</h3> - <div class="form-group"> - <div class="checkbox"> - <label><input type="checkbox" value="1" id="cfrenable">Enable</label> - </div> - - <label for="cfrclip">clip:</label> - <input type="text" class="form-control" id="cfrclip"> - - <label for="errorclip">error clip:</label> - <input type="text" class="form-control" id="cfrerrorclip"> - <input type="text" readonly class="form-control" id="cfrstats"> - <input type="text" readonly class="form-control" id="paprstats"> - <button type="button" class="btn btn-sm btn-info" id="setclip"> - Set - </button> - </div> - </div> + <div class="container-fluid"> + <div class="panel-group"> + <div class="panel panel-default"> + <div class="panel-body"> + <h3>Gain</h3> + <div class="form-group"> + <label for="digitalgain">Digital Gain:</label> + <input type="text" class="form-control" id="digitalgain"> + <button type="button" class="btn btn-sm btn-info" id="setdigitalgain">Set</button> + </div> + </div> + <div class="panel-body"> + <h3>OFDM Windowing</h3> + <div class="form-group"> + <label for="windowlength">Window length:</label> + <input type="text" class="form-control" id="windowlength"> + <button type="button" class="btn btn-sm btn-info" id="setwindowlength">Set</button> + </div> + </div> + <div class="panel-body"> + <h3>CFR</h3> + <div class="form-group"> + <div class="checkbox"> + <label><input type="checkbox" value="1" id="cfrenable">Enable</label> </div> + <label for="cfrclip">clip:</label> + <input type="text" class="form-control" id="cfrclip"> + + <label for="errorclip">error clip:</label> + <input type="text" class="form-control" id="cfrerrorclip"> + <input type="text" readonly class="form-control" id="cfrstats"> + <input type="text" readonly class="form-control" id="paprstats"> + <button type="button" class="btn btn-sm btn-info" id="setclip"> + Set + </button> + </div> </div> - <button type="button" class="btn btn-sm btn-info" id="refresh">Refresh</button> + </div> + </div> + <button type="button" class="btn btn-sm btn-info" id="refresh">Refresh</button> + </div> </body> </html> diff --git a/gui/templates/predistortion.html b/gui/templates/predistortion.html index ef20a16..316c43d 100644 --- a/gui/templates/predistortion.html +++ b/gui/templates/predistortion.html @@ -24,26 +24,26 @@ along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. {% include 'head.html' %} <body> - {% include 'body-nav.html' %} - - <div class="container-fluid"> - <div class="panel-group"> - <div class="panel panel-default"> - <div class="panel-body"> - <h3>Capture</h3> - <div class="form-group"> - <label for="capturestatus">Capture status:</label> - <input type="text" class="form-control" id="capturestatus"> - <button type="button" class="btn btn-sm btn-info" id="capturebutton">Capture</button> - </div> + {% include 'body-nav.html' %} + + <div class="container-fluid"> + <div class="panel-group"> + <div class="panel panel-default"> + <div class="panel-body"> + <h3>Capture</h3> + <div class="form-group"> + <label for="capturestatus">Capture status:</label> + <input type="text" class="form-control" id="capturestatus"> + <button type="button" class="btn btn-sm btn-info" id="capturebutton">Capture</button> + </div> + </div> + <div class="panel-body"> + <h3>Status</h3> + <button type="button" class="btn btn-sm btn-info" id="dpdstatusbutton">Update</button> + <div id="dpdstatus"></div> + </div> + </div> </div> - <div class="panel-body"> - <h3>Status</h3> - <button type="button" class="btn btn-sm btn-info" id="dpdstatusbutton">Update</button> - <div id="dpdstatus"></div> - </div> - </div> </div> - </div> </body> </html> |