diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2019-01-09 15:44:06 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2019-01-09 15:44:06 +0100 |
commit | b717160a90279c21c068d39673c6aafad66dfcae (patch) | |
tree | 01aaf768ebae270cd5f58261d777b374ee1152e6 /python/gui | |
parent | 75ba4f064a65ebad77d130f160b9469418e49c9f (diff) | |
download | dabmod-b717160a90279c21c068d39673c6aafad66dfcae.tar.gz dabmod-b717160a90279c21c068d39673c6aafad66dfcae.tar.bz2 dabmod-b717160a90279c21c068d39673c6aafad66dfcae.zip |
GUI: Add status to home page
Diffstat (limited to 'python/gui')
-rwxr-xr-x | python/gui/api.py | 20 | ||||
-rw-r--r-- | python/gui/static/css/odr.css | 14 | ||||
-rw-r--r-- | python/gui/static/js/odr-home.js | 132 | ||||
-rw-r--r-- | python/gui/templates/home.html | 38 |
4 files changed, 192 insertions, 12 deletions
diff --git a/python/gui/api.py b/python/gui/api.py index c0effde..f9e0ad0 100755 --- a/python/gui/api.py +++ b/python/gui/api.py @@ -80,8 +80,18 @@ class API: return send_error(str(e)) return send_ok() else: - cherrypy.response.status = 400 - return send_error("POST only") + if all(p in kwargs for p in ('controllable', 'param')): + try: + return send_ok(self.mod_rc.get_param_value(kwargs['controllable'], kwargs['param'])) + except IOError as e: + cherrypy.response.status = 503 + return send_error(str(e)) + except ValueError as e: + cherrypy.response.status = 503 + return send_error(str(e)) + else: + cherrypy.response.status = 400 + return send_error("missing 'controllable' or 'param' GET parameters") def _wrap_dpd(self, method, data=None): try: @@ -89,12 +99,12 @@ class API: return send_ok(reply) except ValueError as e: cherrypy.response.status = 503 - return send_error("YAML-RPC call error: {}".format(e)) + return send_error("DPDCE remote procedure call error: {}".format(e)) except TimeoutError as e: cherrypy.response.status = 503 - return send_error("YAML-RPC timeout: {}".format(e)) + return send_error("DPDCE remote procedure call timed out") cherrypy.response.status = 500 - return send_error("YAML-RPC unknown error") + return send_error("Unknown DPDCE remote procedure error error") @cherrypy.expose @cherrypy.tools.json_out() diff --git a/python/gui/static/css/odr.css b/python/gui/static/css/odr.css new file mode 100644 index 0000000..1710464 --- /dev/null +++ b/python/gui/static/css/odr.css @@ -0,0 +1,14 @@ +.glyphicon-refresh-animate { + -animation: spin 1.8s infinite linear; + -webkit-animation: spin2 1.8s infinite linear; +} + +@-webkit-keyframes spin2 { + from { -webkit-transform: rotate(0deg);} + to { -webkit-transform: rotate(360deg);} +} + +@keyframes spin { + from { transform: scale(1) rotate(0deg);} + to { transform: scale(1) rotate(360deg);} +} diff --git a/python/gui/static/js/odr-home.js b/python/gui/static/js/odr-home.js new file mode 100644 index 0000000..11aed8e --- /dev/null +++ b/python/gui/static/js/odr-home.js @@ -0,0 +1,132 @@ +// Copyright (C) 2019 +// 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 apiRequestChain(uri, get_data, success_callback, fail_callback) { + $.ajax({ + type: "GET", + url: uri, + data: get_data, + contentType: 'application/json', + dataType: 'json', + + error: function(data) { + console.log("GET " + JSON.stringify(get_data) + " error: " + data.responseText); + fail_callback(data.responseText); + }, + success: function(data) { + console.log("GET " + JSON.stringify(get_data) + " success: " + JSON.stringify(data)); + if (data.status == 'ok') { + success_callback(data.data); + } + else { + fail_callback(data.data); + } + }, + }); +} + +function mark_pending(id) { + document.getElementById(id).className = "glyphicon glyphicon-refresh glyphicon-refresh-animate"; +} + +function mark_ok(id, comment) { + document.getElementById(id).className = "glyphicon glyphicon-ok"; + + if (comment) { + document.getElementById(id + "_comment").innerHTML = comment; + } +} + +function mark_fail(id, reason) { + var el = document.getElementById(id); + el.className = "glyphicon glyphicon-remove"; + el.style.color = "#FF3333"; + + document.getElementById(id + "_comment").innerHTML = reason; + + var overall = document.getElementById("overall_state"); + overall.style.color = "#FF8833"; + overall.className = "glyphicon glyphicon-alert"; +} + +function check_rc() { + mark_pending('is_rc_ok'); + apiRequestChain("/api/parameter", + {controllable: 'sdr', param: 'freq'}, + function(data) { + mark_ok('is_rc_ok'); + check_modulating(0); + }, + function(data) { + mark_fail('is_rc_ok', JSON.parse(data)['reason']); + }); +} + +function check_modulating(last_num_frames) { + mark_pending('is_modulating'); + apiRequestChain("/api/parameter", + {controllable: 'sdr', param: 'frames'}, + function(data) { + if (data > 0) { + if (last_num_frames == 0) { + setTimeout(function() { check_modulating(data); }, 200); + } + else { + if (data == last_num_frames) { + mark_fail('is_modulating', "Frame counter not incrementing: " + data); + } + else { + mark_ok('is_modulating', "Number of frames modulated: " + data); + check_dpdce_running(); + } + } + } + else { + mark_fail('is_modulating', 'number of frames is 0'); + } + }, + function(data) { + mark_fail('is_modulating', data); + }); +} + +function check_dpdce_running() { + mark_pending('is_dpdce_running'); + apiRequestChain("/api/dpd_results", + {controllable: 'sdr', param: 'frames'}, + function(data) { + mark_ok('is_dpdce_running', "State: " + data['state']); + mark_ok('overall_state'); + }, + function(data) { + mark_fail('is_dpdce_running', JSON.parse(data)['reason']); + }); +} + +$(function(){ + setTimeout(check_rc, 20); +}); + + +// ToolTip init +$(function(){ + $('[data-toggle="tooltip"]').tooltip(); +}); diff --git a/python/gui/templates/home.html b/python/gui/templates/home.html index cc8fbf0..bf802d6 100644 --- a/python/gui/templates/home.html +++ b/python/gui/templates/home.html @@ -4,13 +4,37 @@ {% include 'head.html' %} <body> - {% include 'body-nav.html' %} - - <div class="container-fluid"> - <div class="jumbotron"> - <h1>Opendigitalradio</h1><h2>ODR-DabMod Interface</h2> - </div> - </div> + {% include 'body-nav.html' %} + + <div class="container-fluid"> + <div class="jumbotron"> + <h1>Opendigitalradio</h1><h2>ODR-DabMod Status Check + <span id="overall_state" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> + </h2> + <div class="well well-sm"> + <p>ODR-DabMod + </p> + <ul> + <li>Answering to RC: + <span id="is_rc_ok" class="glyphicon glyphicon-question-sign"></span> + <span id="is_rc_ok_comment"><span> + </li> + <li>Frame generation: + <span id="is_modulating" class="glyphicon glyphicon-question-sign"></span> + <span id="is_modulating_comment"><span> + </li> + </ul> + + <p>Checking predistortion + <ul> + <li>DPDCE running: + <span id="is_dpdce_running" class="glyphicon glyphicon-question-sign"></span> + <span id="is_dpdce_running_comment"><span> + </li> + </ul> + </div> + </div> + </div> </body> </html> |