diff --git a/ansible/README.md b/ansible/README.md index 386e7bf7fdf256daafa8683f1f0419774fbab5c2..288aee344794b32017a25a6c0a6d48d854bc828d 100644 --- a/ansible/README.md +++ b/ansible/README.md @@ -6,7 +6,8 @@ - Boot as default and set your preferred options for country, password, etc. > From command line on your local PC (not the pi): -- copy your ssh keys if you don't want a password every time +- generate and copy your ssh keys if you don't want a password every time + - ssh-keygen - ssh-copy-id pi@MY-RPI-IPADDRESS - then setup ansible: - install ansible on your local PC with your package manager @@ -18,7 +19,7 @@ cd hev-sw/ansible source hev-ansible.sh cd playbooks ``` -- add the address of your Raspberry Pi to the `hosts` file under the section `[hevpi]` +- add the address of your Raspberry Pi to the `hosts` file under the section `[hevpi]`. The default host file is found at /etc/ansible/hosts - example : ``` [hevpi] diff --git a/raspberry-backend/static/css/notifications.css b/raspberry-backend/static/css/notifications.css index 90d9e61dd24376c19e085e69846b931c45db7d7c..2346dd7159bfae2052ce8976f423945cd8e5a741 100644 --- a/raspberry-backend/static/css/notifications.css +++ b/raspberry-backend/static/css/notifications.css @@ -1 +1 @@ -.ncf-container{font-size:14px;box-sizing:border-box;position:fixed;z-index:999999}.ncf-container.nfc-top-left{top:12px;left:12px}.ncf-container.nfc-top-right{top:12px;right:12px}.ncf-container.nfc-bottom-right{bottom:12px;right:12px}.ncf-container.nfc-bottom-left{bottom:12px;left:12px}@media (max-width:767px){.ncf-container{left:0;right:0}}.ncf-container .ncf{background:#fff;transition:.3s ease;position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:30px;width:300px;border-radius:3px 3px 3px 3px;box-shadow:0 0 12px #999;color:#000;opacity:.9;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=90);filter:alpha(opacity=90);background-position:15px!important;background-repeat:no-repeat!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ncf-container .ncf:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.ncf-container .ncf .ncf-title{font-weight:700;font-size:16px;text-align:left;margin-top:0;margin-bottom:6px;word-wrap:break-word}.ncf-container .ncf .nfc-message{margin:0;text-align:left;word-wrap:break-word}.ncf-container .success{background:#51a351;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")}.ncf-container .info{background:#2f96b4;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=")}.ncf-container .warning{background:#f87400;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=")}.ncf-container .error{background:#bd362f;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")!important}.ncf-container button{position:relative;right:-.3em;top:-.3em;float:right;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff;opacity:.8;line-height:1;font-size:16px;padding:0;cursor:pointer;background:transparent;border:0}.ncf-container button:hover{opacity:1} \ No newline at end of file +.ncf-container{font-size:14px;box-sizing:border-box;position:fixed;z-index:999999}.ncf-container.nfc-top-left{top:12px;left:12px}.ncf-container.nfc-top-right{top:12px;right:12px}.ncf-container.nfc-bottom-right{bottom:12px;right:12px}.ncf-container.nfc-bottom-left{bottom:12px;left:12px}@media (max-width:767px){.ncf-container{left:0;right:0}}.ncf-container .ncf{background:#fff;transition:.3s ease;position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:30px;width:300px;border-radius:3px 3px 3px 3px;box-shadow:0 0 12px #999;color:#000;opacity:.9;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=90);filter:alpha(opacity=90);background-position:15px!important;background-repeat:no-repeat!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ncf-container .ncf:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.ncf-container .ncf .ncf-title{font-weight:700;font-size:16px;text-align:left;margin-top:0;margin-bottom:6px;word-wrap:break-word}.ncf-container .ncf .nfc-message{margin:0;text-align:left;word-wrap:break-word}.ncf-container .success{background:#51a351;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")}.ncf-container .info{background:rgb(31,71,147);color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=")}.ncf-container .warning{background:#f87400;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=")}.ncf-container .error{background:#bd362f;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")!important}.ncf-container button{position:relative;right:-.3em;top:-.3em;float:right;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff;opacity:.8;line-height:1;font-size:16px;padding:0;cursor:pointer;background:transparent;border:0}.ncf-container button:hover{opacity:1} \ No newline at end of file diff --git a/raspberry-backend/static/css/style_v3.css b/raspberry-backend/static/css/style_v3.css index a6a42176503f4f951abac90e566466cec204a2b4..986cce5a612b3373978429dd0d6698f981987355 100644 --- a/raspberry-backend/static/css/style_v3.css +++ b/raspberry-backend/static/css/style_v3.css @@ -91,6 +91,12 @@ html { } } +@media (min-width: 1400px) { + html{ + font-size: 30px; + + } +} @@ -1843,8 +1849,8 @@ small, .card-body { flex: 1 1 auto; - min-height: 1px; padding: 1.25rem; + align-items:center; } .card-title { @@ -5934,10 +5940,10 @@ html, body { } .br-red{border: 1px solid #ff0000;} -.reading{font-size:1.7rem;min-width:6rem;display:inline-block;text-align:right;} +.reading{font-size:1.7rem;min-width:5rem;display:inline-block;text-align:right;} .reading-main{font-size:1.2rem;min-width:4rem;display:inline-block;text-align:right;} -.input-reading{font-size:1.2rem;width:4em;text-align:center;background:transparent;border:0;text-align:right;} +.input-reading{font-size:1.2rem;width:3.4em;text-align:center;background:transparent;border:0;text-align:right;} .input-reading:disabled{color:black;} .input-editable:enabled{border:1;background:white;} @@ -5985,7 +5991,7 @@ div.active{ } -.sb-nav-button{ border: 1px solid var(--cern); width:95px; fill:none; +.sb-nav-button{ border: 2px solid var(--cern); width:95px; background-color:none; display: inline-block; //text-shadow: 0 0 2px rgba(0,0,0,.3); @@ -6044,4 +6050,83 @@ div.active{ //text-overflow: ''; } -.app-none{appearance:none;} \ No newline at end of file +.app-none{appearance:none;} + +.lock { +position: fixed; +bottom: 0; +width:5%; +right: 0.5rem; +text-align: center; +border-top-left-radius: 1.0rem !important; +border-top-right-radius: 1.0rem !important; +padding-top:0.35rem; +padding-bottom:0.3rem; +background-color: rgb(211,211,211); +border: 1px solid rgba(0, 0, 0, 0.125); +} +.fa-lock{ + width:2rem;height:2rem; +} +.col-charts-main, .col-cards-main, .card-reading{ + position: relative; + width: 100%; + padding-right: 0.75rem; + padding-left: 0.75rem; +} +.col-charts-main{ + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + +} +.col-cards-main { + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; +} +.card-reading{ + position: relative; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; + display:flex; + flex-direction:column; + flex: 0 0 31.8%; + max-width: 31.8%; + padding-right: 0.15rem !important; + padding-left: 0.15rem !important; + margin-right: 0.05rem !important; + margin-left: 0.05rem !important; + background-color: rgb(211,211,211); + color: #343a40 !important; + margin-bottom: 0.5rem !important; + height:calc((100vh - var(--top-height) - 0.5rem)/4.0 - 0.5rem); +} + +.range-button-container{ + height:2.0rem; + margin-left:auto; + margin-right:auto; +} + +.main-chart-container { + position:relative; + width:100%; + height:calc((100vh - var(--top-height) - 0.5rem - 2.0rem)/3.0); // 2.0rem if for the range-button container +} +.reading-wrapper{ + margin-top:auto; + margin-bottom:auto; +} +@media (min-height: 1200px) { + .card-reading { + flex: 0 49.1%; + max-width: 49.1%; + } + +} +.nav-link-disabled { + pointer-events: none; +} diff --git a/raspberry-backend/static/js/Chart-display.js b/raspberry-backend/static/js/Chart-display.js index 647043879d5dcb33d48a591edb9d622a12d46ca1..7b0bee1ae7f61031a9226391542170c081b96680 100644 --- a/raspberry-backend/static/js/Chart-display.js +++ b/raspberry-backend/static/js/Chart-display.js @@ -8,11 +8,56 @@ var initial_yaxis_pressure = []; var initial_yaxis_volume = []; var initial_yaxis_flow = []; +var fio_reading; + /** * Request data from the server, add it to the graph and set a timeout * to request again */ +var current_timestamp = -1; + +function setChartXaxisRange(min,max){ + chart_volume.options.scales.xAxes[0].ticks.min = min; + chart_volume.options.scales.xAxes[0].ticks.max = max; + chart_flow.options.scales.xAxes[0].ticks.min = min; + chart_flow.options.scales.xAxes[0].ticks.max = max; + chart_pressure.options.scales.xAxes[0].ticks.min = min; + chart_pressure.options.scales.xAxes[0].ticks.max = max; + + +} + +function init_results(){ + $.getJSON({ + url: '/last_N_data', + success: function(data) { + for (i=0; i<data.length; i++) { + var seconds = data[i]["timestamp"]/1000; + if ( seconds == "" ) continue; + initial_yaxis_pressure.push({x : seconds, y : data[i]["pressure_buffer"]}); + initial_yaxis_volume.push({x : seconds, y : data[i]["pressure_inhale"]}); + initial_yaxis_flow.push({x : seconds, y : data[i]["temperature_buffer"]}); + } + //reverse because data is read from the other way + initial_xaxis.reverse(); + initial_yaxis_pressure.reverse(); + initial_yaxis_volume.reverse(); + initial_yaxis_flow.reverse(); + + if (initial_yaxis_pressure.length > 0) current_timestamp = initial_yaxis_pressure[0][0]; + for ( let i = 0 ; i < initial_yaxis_pressure.length; i++){ + initial_yaxis_pressure[i][0] = initial_yaxis_pressure[i][0] - current_timestamp; + initial_yaxis_volume[i][0] = initial_yaxis_volume[i][0] - current_timestamp; + initial_yaxis_flow[i][0] = initial_yaxis_flow[i][0] - current_timestamp; + } + + }, + cache: false + }); +} + +/* function last_results() { $.getJSON({ url: '/last_N_data', @@ -38,10 +83,11 @@ function last_results() { cache: false }); } - +*/ // Calling the function here to retrive // the initial values to be plotted on the charts -last_results(); +//last_results(); +init_results(); @@ -49,46 +95,47 @@ function requestChartVar() { $.ajax({ url: '/live-data', success: function(point) { - + fio_reading = (point["pressure_buffer"]).toFixed(0) ; + //console.log(fio_reading); + fio_gauge.data.datasets[0].gaugeData['value'] = fio_reading; + + var seconds = point["timestamp"]/1000; + // get difference between last time stamp and this and apply to existing points + var diff = 0; + if ( current_timestamp == -1 ){ + diff = seconds; + } + else { + diff = seconds - current_timestamp; + } + current_timestamp = seconds; + if(chart_pressure.data.datasets[0].data.length > 300){ - chart_pressure.data.labels.shift(); chart_pressure.data.datasets[0].data.shift(); } if(chart_flow.data.datasets[0].data.length > 300){ - //chart_flow.data.labels.shift(); chart_flow.data.datasets[0].data.shift(); } - if(chart_volume.data.datasets[0].data.length > 300){ - //chart_volume.data.labels.shift(); chart_volume.data.datasets[0].data.shift(); } - - for (var i=0; i<300; i++) { - var x = chart_pressure.data.labels[i] - 0.20 ; - chart_pressure.data.labels[i] = x.toFixed(1); - } - - - // add the point - chart_pressure.data.labels.push(0); - //chart_pressure.data.labels.push(point["timestamp"]); - chart_pressure.data.datasets[0].data.push(point["pressure_buffer"]); - - // add the point - //chart_pressure.data.labels.push(0); - chart_flow.data.datasets[0].data.push(point["temperature_buffer"]); - - // add the point - //chart_pressure.data.labels.push(0); - chart_volume.data.datasets[0].data.push(point["pressure_inhale"]); + for ( let i = 0 ; i < initial_yaxis_pressure.length; i++){ + initial_yaxis_pressure[i]['x'] = initial_yaxis_pressure[i]['x'] - diff; + initial_yaxis_volume[i]['x'] = initial_yaxis_volume[i]['x'] - diff; + initial_yaxis_flow[i]['x'] = initial_yaxis_flow[i]['x'] - diff; + } + + chart_pressure.data.datasets[0].data.push({x : 0, y : point["pressure_buffer"]}); + chart_flow.data.datasets[0].data.push({ x : 0, y : point["temperature_buffer"]}); + chart_volume.data.datasets[0].data.push({ x : 0, y : point["pressure_inhale"]}); chart_pressure.update(); chart_flow.update(); chart_volume.update(); - + fio_gauge.update(); + }, cache: false }); @@ -103,15 +150,15 @@ requestChartVar(); $(document).ready(function() { var ctx_pressure = document.getElementById('pressure_chart'); chart_pressure = new Chart(ctx_pressure, { - type: 'line', + type: 'scatter', data: { - labels: initial_xaxis, datasets: [{ data: initial_yaxis_pressure, label: "Var1", borderColor: "#0049b8", borderWidth: 4, - fill: false + fill: false, + showLine: true, } ] }, @@ -122,6 +169,7 @@ $(document).ready(function() { } }, responsive: true, + maintainAspectRatio: false, stroke: { curve: 'smooth' }, @@ -131,25 +179,23 @@ $(document).ready(function() { title: { display: true, text: 'Pressure [mbar]', - fontSize: 25 + fontSize: 0.7*parseFloat(getComputedStyle(document.documentElement).fontSize), }, scales: { + xAxes: [{ ticks: { - fontSize: 25, - beginAtZero: true - }, - //type: 'time', - time: { - unit: 'second', - displayFormat: 'second' - } - }], - yAxes: [{ + maxTicksLimit: 13, + maxRotation: 0, + min: -60, + max: 0, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize),}}], + yAxes: [{ ticks: { - fontSize: 25, beginAtZero: true, - suggestedMax: 25 + suggestedMax: 25, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize), + maxTicksLimit: 8, }, scaleLabel: { display: false, @@ -180,16 +226,17 @@ $(document).ready(function() { $(document).ready(function() { var ctx_flow = document.getElementById('flow_chart'); chart_flow = new Chart(ctx_flow, { - type: 'line', + type: 'scatter', data: { - labels: initial_xaxis, + //labels: initial_xaxis, datasets: [{ data: initial_yaxis_flow, label: "Var1", //borderColor: "#3e95cd", borderColor: "#000000", borderWidth: 4, - fill: false + fill: false, + showLine: true, }] }, options: { @@ -199,6 +246,7 @@ $(document).ready(function() { } }, responsive: true, + maintainAspectRatio: false, stroke: { curve: 'smooth' }, @@ -207,26 +255,24 @@ $(document).ready(function() { }, title: { display: true, - text: 'Flow [mL/min]', - fontSize: 25 + text: 'Flow [mL/min]', + fontSize: 0.7*parseFloat(getComputedStyle(document.documentElement).fontSize), }, scales: { + xAxes: [{ ticks: { - fontSize: 25, - beginAtZero: true - }, - //type: 'time', - time: { - unit: 'second', - displayFormat: 'second' - } - }], + maxTicksLimit: 13, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize), + maxRotation: 0, + min: -60, + max: 0, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize),}}], yAxes: [{ ticks: { - fontSize: 25, beginAtZero: true, - suggestedMax: 25 + maxTicksLimit: 8, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize), }, scaleLabel: { display: false, @@ -256,17 +302,19 @@ $(document).ready(function() { $(document).ready(function() { var ctx_volume = document.getElementById('volume_chart'); chart_volume = new Chart(ctx_volume, { - type: 'line', + type: 'scatter', data: { - labels: initial_xaxis, + //labels: initial_xaxis, datasets: [{ data: initial_yaxis_volume, label: "Var1", borderColor: "#ba0202", borderWidth: 4, - fill: false + fill: false, + showLine: true, }] }, + options: { elements: { point: { @@ -274,6 +322,7 @@ $(document).ready(function() { } }, responsive: true, + maintainAspectRatio: false, stroke: { curve: 'smooth' }, @@ -283,25 +332,26 @@ $(document).ready(function() { title: { display: true, text: 'Volume [mL]', - fontSize: 25 + fontSize: 0.7*parseFloat(getComputedStyle(document.documentElement).fontSize), }, scales: { + xAxes: [{ ticks: { - fontSize: 25, - beginAtZero: true - }, - //type: 'time', - time: { - unit: 'second', - displayFormat: 'second' - } - }], - yAxes: [{ - ticks: { - fontSize: 25, + maxTicksLimit: 13, + maxRotation: 0, + min: -60, + max: 0, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize),}}], + + yAxes: [{ + ticks: { beginAtZero: true, - suggestedMax: 25 + suggestedMax: 25, + maxTicksLimit: 8, + fontSize: 0.6*parseFloat(getComputedStyle(document.documentElement).fontSize), + + }, scaleLabel: { display: false, @@ -318,11 +368,28 @@ $(document).ready(function() { duration: 20000, refresh: 1000, delay: 2000 - //onRefresh: requestChartVar3() } } }); }); +var ctx = document.getElementById("example_gauge").getContext("2d"); +fio_gauge = new Chart(ctx, { + type: "tsgauge", + data: { + datasets: [{ + backgroundColor: ["#0fdc63", "#fd9704", "#ff7143"], + borderWidth: 0, + gaugeData: { + value: 0, + valueColor: "#ff7143" + }, + gaugeLimits: [0, 50, 100] + }] + }, + options: { + events: [] + } +}); diff --git a/raspberry-backend/static/js/Chart-displayLoop.js b/raspberry-backend/static/js/Chart-displayLoop.js index a5d7df0a4a7bf53a7b75bcb81444afdd4ef48a30..b9251278c9363485b412f60b551d902979a99156 100644 --- a/raspberry-backend/static/js/Chart-displayLoop.js +++ b/raspberry-backend/static/js/Chart-displayLoop.js @@ -13,34 +13,48 @@ function requestChartVar() { success: function(point) { if( chart_PV.data.datasets[1].data.length > 100 ){ chart_PV.data.datasets[1].data.shift(); - chart_FV.data.datasets[1].data.shift(); + chart_VF.data.datasets[1].data.shift(); chart_PF.data.datasets[1].data.shift(); } // point labelled as: (stealing definitions from Chart-display.js) // Pressure = pressure_buffer // Flow = pressure_inhale ?? // Volume = temperature_buffer !!? - chart_PV.data.datasets[1].data.push({x: point["temperature_buffer"], - y: point["pressure_buffer"]}); - chart_FV.data.datasets[1].data.push({x: point["temperature_buffer"], - y: point["pressure_inhale"]}); - chart_PF.data.datasets[1].data.push({x: point["pressure_inhale"], - y: point["pressure_buffer"]}); - chart_PV.data.datasets[0].data = - [{x: point["temperature_buffer"],y: point["pressure_buffer"]}]; + var pressure = point["pressure_buffer"]; + var volume = point["temperature_buffer"]; + var flow = point["pressure_inhale"]; - chart_FV.data.datasets[0].data = - [{x: point["temperature_buffer"], y: point["pressure_inhale"]}]; + // to quote the AAMI: + //For Pressure-Volume loops, the graph + //is required to use delivered volume on the vertical axis + //and airway pressure on the horizontal axis. Positive + //values should increase in up/right directions. Every + //breath resets the graph, setting the volume back at the + //origin. - chart_PF.data.datasets[0].data = - [{x: point["pressure_inhale"], y: point["pressure_buffer"]}]; + //For Flow-Volume loops the graph is required to use flow + //rate on the vertical axis and delivered volume on the + //horizontal axis. Positive values should increase in the + //up/right directions. Every breath resets the graph, + //setting the volume back at the origin. The document also + //suggests that there could be another version using + //exhalation flow, if possible. + // loops: + chart_PV.data.datasets[1].data.push({x: pressure, y: volume}); + chart_VF.data.datasets[1].data.push({x: volume, y: flow}); + chart_PF.data.datasets[1].data.push({x: pressure, y: flow}); + + // current data: + chart_PV.data.datasets[0].data = [{x: pressure, y: volume}]; + chart_VF.data.datasets[0].data = [{x: volume, y: flow}]; + chart_PF.data.datasets[0].data = [{x: pressure, y: flow}]; + + // now run chart updates chart_PV.update(); - chart_FV.update(); + chart_VF.update(); chart_PF.update(); - - console.info("chart_PV.data", chart_PV.data); - }, + }, cache: false }); setTimeout(requestChartVar, 200); @@ -53,77 +67,67 @@ $(document).ready(function() { chart_PV = new Chart(ctx_PV, { type: 'scatter', data: {datasets: [{data: [], - label: "Pressure:Volme (current)", + label: "Pressure (x) [mbar]: Volume (y) [ml] (current)", borderColor: "rgb(128,0,0)", - fillColor: "rgb(200,0,0)", + pointBackgroundColor : "rgb(128,0,0)", fill: true}, {data: [], - label: "Loop Pressure:Volme (last 20s)", + label: "Loop (20s)", borderColor: "rgb(51,99,255)", + pointBackgroundColor : "rgb(51,99,255)", fill: false }, ]}, - options: {scales: {xAxes: [{type: 'linear', - position: 'bottom', - lablelString: 'temperature_buffer??', - display: true, - ticks: {min: -1000, max: 1500, - stepSize: 500 }}], - yAxes: [{type: 'linear', - position: 'left', - lablelString: 'pressure_buffer??', - display: true, + options: {elements: { point: { radius: 5}}, + scales: {xAxes: [{display: true, ticks: {min: 0, max: 25, - stepSize: 5 }}]}} + stepSize: 5, fontSize: 25 }}], + yAxes: [{display: true, + ticks: {min: -1000, max: 1500, + stepSize: 500, fontSize:25 }}]}} }); - var ctx_FV = document.getElementById('flow_volume_chart'); - chart_FV = new Chart(ctx_FV, { + var ctx_VF = document.getElementById('flow_volume_chart'); + chart_VF = new Chart(ctx_VF, { type: 'scatter', data: {datasets: [{data: [], - label: "Flow:Volme (current)", + label: "Volume (x) [ml]: Flow (y) [ml/min] (current)", borderColor: "rgb(128,0,0)", + pointBackgroundColor : "rgb(128,0,0)", fill: true }, {data: [], - label: "Loop Flow:Volme (last 20s)", + label: "Loop (20s)", borderColor: "rgb(51,99,255)", + pointBackgroundColor : "rgb(51,99,255)", fill: false }]} - ,options: {scales: {xAxes: [{type: 'linear', - position: 'bottom', - lablelString: 'temperature_buffer??', - display: true, - ticks: {min: -1000, max: 1500, - stepSize: 500 }}], - yAxes: [{type: 'linear', - position: 'left', - lablelString: 'pressure_inhale??', - display: true, + ,options: {elements: { point: { radius: 5}}, + scales: {xAxes: [{display: true, + ticks: {min: -1000, max: 1500, + stepSize: 500, fontSize: 25 }}], + yAxes: [{display: true, ticks: {min: 0, max: 300, - stepSize: 100 }}]}} + stepSize: 100, fontSize: 25 }}]}} }); var ctx_PF = document.getElementById('pressure_flow_chart'); chart_PF = new Chart(ctx_PF, { type: 'scatter', data: {datasets: [{data: [], - label: "Pressure:Flow (current)", + label: "Pressure (x) [mbar]: Flow (y) [ml/min] (current)", borderColor: "rgb(128,0,0)", + pointBackgroundColor : "rgb(128,0,0)", fill: true }, {data: [], - label: "Loop Pressure:Flow (last 20s)", + label: "Loop (20s)", borderColor: "rgb(51,99,255)", + pointBackgroundColor : "rgb(51,99,255)", fill: false }]} - ,options: {scales: {xAxes: [{type: 'linear', - position: 'bottom', - lablelString: 'pressure_inhale??', - display: true, + ,options: {elements: { point: { radius: 5, fill: true}}, + scales: {xAxes: [{display: true, + ticks: {min: 0, max: 25 , + stepSize: 5 , fontSize: 25 }}], + yAxes: [{display: true, ticks: {min: 0, max: 300, - stepSize: 100 }}], - yAxes: [{type: 'linear', - position: 'left', - lablelString: 'pressure_buffer??', - display: true, - ticks: {min: 0, max: 25, - stepSize: 5 }}]}} + stepSize: 100, fontSize: 25 }}]}} }); }); diff --git a/raspberry-backend/static/js/Gauge.js b/raspberry-backend/static/js/Gauge.js new file mode 100644 index 0000000000000000000000000000000000000000..0994eeaae1c397bda77687a8efd678fd81a74900 --- /dev/null +++ b/raspberry-backend/static/js/Gauge.js @@ -0,0 +1,217 @@ +(function () { + if (!window.Chart) { + return; + } + function GaugeChartHelper() { + } + GaugeChartHelper.prototype.setup = function(chart, config) { + this.chart = chart; + this.ctx = chart.ctx; + this.limits = config.data.datasets[0].gaugeLimits; + this.data = config.data.datasets[0].gaugeData; + var options = chart.options; + this.fontSize = options.defaultFontSize; + this.fontStyle = options.defaultFontFamily; + this.fontColor = options.defaultFontColor; + this.ctx.textBaseline = "alphabetic"; + this.arrowAngle = 25 * Math.PI / 180; + this.arrowColor = config.options.indicatorColor || options.arrowColor; + this.showMarkers = typeof(config.options.showMarkers) === 'undefined' ? true : config.options.showMarkers; + if (config.options.markerFormatFn) { + this.markerFormatFn = config.options.markerFormatFn; + } else { + this.markerFormatFn = function(value) { + return value; + } + } + }; + GaugeChartHelper.prototype.applyGaugeConfig = function(chartConfig) { + this.calcLimits(); + chartConfig.data.datasets[0].data = this.doughnutData; + var ctx = this.ctx; + var labelsWidth = this.limits.map(function(label){ + var text = this.markerFormatFn(label); + return ctx.measureText(text).width; + }.bind(this)); + var padding = Math.max.apply(this, labelsWidth) + this.chart.width / 35; + var heightRatio = this.chart.height / 50; + chartConfig.options.layout.padding = { + top: this.fontSize + heightRatio, + left: padding, + right: padding, + bottom: heightRatio * 2 + }; + }; + GaugeChartHelper.prototype.calcLimits = function() { + var limits = this.limits; + var data = []; + var total = 0; + for (var i = 1, ln = limits.length; i < ln; i++) { + var dataValue = Math.abs(limits[i] - limits[i - 1]); + total += dataValue; + data.push(dataValue); + } + this.doughnutData = data; + var minValue = limits[0]; + var maxValue = limits[limits.length - 1]; + this.isRevers = minValue > maxValue; + this.minValue = this.isRevers ? maxValue : minValue; + this.totalValue = total; + }; + GaugeChartHelper.prototype.updateGaugeDimensions = function() { + var chartArea = this.chart.chartArea; + this.gaugeRadius = this.chart.innerRadius; + this.gaugeCenterX = (chartArea.left + chartArea.right) / 2; + this.gaugeCenterY = (chartArea.top + chartArea.bottom + this.chart.outerRadius) / 2; + this.arrowLength = this.chart.radiusLength * 2; + }; + GaugeChartHelper.prototype.getCoordOnCircle = function(r, alpha) { + return { + x: r * Math.cos(alpha), + y: r * Math.sin(alpha) + }; + }; + GaugeChartHelper.prototype.getAngleOfValue = function(value) { + var result = 0; + var gaugeValue = value - this.minValue; + if (gaugeValue <= 0) { + result = 0; + } else if (gaugeValue >= this.totalValue) { + result = Math.PI; + } else { + result = Math.PI * gaugeValue / this.totalValue; + } + if (this.isRevers) { + return Math.PI - result; + } else { + return result; + } + }; + GaugeChartHelper.prototype.renderLimitLabel = function(value) { + var ctx = this.ctx; + var angle = this.getAngleOfValue(value); + var coord = this.getCoordOnCircle(this.chart.outerRadius + (this.chart.radiusLength / 2), angle); + var align; + var diff = angle - (Math.PI / 2); + if (diff > 0) { + align = "left"; + } else if (diff < 0) { + align = "right"; + } else { + align = "center"; + } + ctx.textAlign = align; + ctx.font = this.fontSize + "px " + this.fontStyle; + ctx.fillStyle = this.fontColor; + var text = this.markerFormatFn(value); + ctx.fillText(text, this.gaugeCenterX - coord.x, this.gaugeCenterY - coord.y); + }; + GaugeChartHelper.prototype.renderLimits = function() { + for (var i = 0, ln = this.limits.length; i < ln; i++) { + this.renderLimitLabel(this.limits[i]); + } + }; + GaugeChartHelper.prototype.renderValueLabel = function() { + var label = this.data.value.toString(); + var ctx = this.ctx; + ctx.font = "30px " + this.fontStyle; + var stringWidth = ctx.measureText(label).width; + var elementWidth = 0.75 * this.gaugeRadius * 2; + var widthRatio = elementWidth / stringWidth; + var newFontSize = Math.floor(30 * widthRatio); + var fontSizeToUse = Math.min(newFontSize, this.gaugeRadius); + ctx.textAlign = "center"; + ctx.font = fontSizeToUse + "px " + this.fontStyle; + ctx.fillStyle = this.data.valueColor || this.fontColor; + ctx.fillText(label, this.gaugeCenterX, this.gaugeCenterY); + }; + GaugeChartHelper.prototype.renderValueArrow = function(value) { + var angle = this.getAngleOfValue(typeof value === "number" ? value : this.data.value); + this.ctx.globalCompositeOperation = "source-over"; + this.renderArrow(this.gaugeRadius, angle, this.arrowLength, this.arrowAngle, this.arrowColor); + }; + GaugeChartHelper.prototype.renderSmallValueArrow = function(value) { + var angle = this.getAngleOfValue(value); + this.ctx.globalCompositeOperation = "source-over"; + this.renderArrow(this.gaugeRadius - 1, angle, this.arrowLength - 1, this.arrowAngle, this.arrowColor); + }; + GaugeChartHelper.prototype.clearValueArrow = function(value) { + var angle = this.getAngleOfValue(value); + this.ctx.lineWidth = 2; + this.ctx.globalCompositeOperation = "destination-out"; + this.renderArrow(this.gaugeRadius - 1, angle, this.arrowLength + 1, this.arrowAngle, "#FFFFFF"); + this.ctx.stroke(); + }; + GaugeChartHelper.prototype.renderArrow = function(radius, angle, arrowLength, arrowAngle, arrowColor) { + var coord = this.getCoordOnCircle(radius, angle); + var arrowPoint = { + x: this.gaugeCenterX - coord.x, + y: this.gaugeCenterY - coord.y + }; + var ctx = this.ctx; + ctx.fillStyle = arrowColor; + ctx.beginPath(); + ctx.moveTo(arrowPoint.x, arrowPoint.y); + coord = this.getCoordOnCircle(arrowLength, angle + arrowAngle); + ctx.lineTo(arrowPoint.x + coord.x, arrowPoint.y + coord.y); + coord = this.getCoordOnCircle(arrowLength, angle - arrowAngle); + ctx.lineTo(arrowPoint.x + coord.x, arrowPoint.y + coord.y); + ctx.closePath(); + ctx.fill(); + }; + GaugeChartHelper.prototype.animateArrow = function() { + var stepCount = 30; + var animateTimeout = 300; + var gaugeValue = this.data.value - this.minValue; + var step = gaugeValue / stepCount; + var i = 0; + var currentValue = this.minValue; + var interval = setInterval(function() { + i++; + this.clearValueArrow(currentValue); + if (i > stepCount) { + clearInterval(interval); + this.renderValueArrow(); + } else { + currentValue += step; + this.renderSmallValueArrow(currentValue); + } + }.bind(this), animateTimeout / stepCount); + }; + Chart.defaults.tsgauge = { + animation: { + animateRotate: true, + animateScale: false + }, + cutoutPercentage: 95, + rotation: Math.PI, + circumference: Math.PI, + legend: { + display: false + }, + scales: {}, + arrowColor: "#444" + }; + Chart.controllers.tsgauge = Chart.controllers.doughnut.extend({ + initialize: function(chart) { + var gaugeHelper = this.gaugeHelper = new GaugeChartHelper(); + gaugeHelper.setup(chart, chart.config); + gaugeHelper.applyGaugeConfig(chart.config); + chart.config.options.animation.onComplete = function(chartElement) { + gaugeHelper.updateGaugeDimensions(); + gaugeHelper.animateArrow(); + }; + Chart.controllers.doughnut.prototype.initialize.apply(this, arguments); + }, + draw: function() { + Chart.controllers.doughnut.prototype.draw.apply(this, arguments); + var gaugeHelper = this.gaugeHelper; + gaugeHelper.updateGaugeDimensions(); + gaugeHelper.renderValueLabel(); + if (gaugeHelper.showMarkers) { + gaugeHelper.renderLimits(); + } + gaugeHelper.renderSmallValueArrow(gaugeHelper.minValue); + } + }); +})(); diff --git a/raspberry-backend/templates/base.html b/raspberry-backend/templates/base.html index 5e483a80fa21e660fe16b9e945177f14b0e96883..58dded62453c87d9de2dfd07be9ac2cec5dcbae9 100644 --- a/raspberry-backend/templates/base.html +++ b/raspberry-backend/templates/base.html @@ -22,6 +22,7 @@ {% endblock %} </head> <body class="sb-nav-fixed {{'no-scroll-lock' if logs_active}}"> + <nav class="sb-topnav navbar navbar-expand navbar-dark bg-white px-0 py-0"> <!-- Logo --> <a class="navbar-brand" href=""><img src="{{ url_for('static', filename='img/cern-hev-logo.png') }}" id="logo"></a> @@ -40,8 +41,10 @@ <!-- Battery --> <ul class="navbar-nav ml-auto mr-0 mr-md-3 my-2 my-md-0"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="battery-full" class="svg-inline--fa fa-battery-full fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"> + <!--Powered --> + <path class="path-icon transparent" id = "powered" d="M320,32a32,32,0,0,0-64,0v96h64Zm48,128H16A16,16,0,0,0,0,176v32a16,16,0,0,0,16,16H32v32A160.07,160.07,0,0,0,160,412.8V512h64V412.8A160.07,160.07,0,0,0,352,256V224h16a16,16,0,0,0,16-16V176A16,16,0,0,0,368,160ZM128,32a32,32,0,0,0-64,0v96h64Z"></path> <!-- Full --> - <path class="path-icon" id = "battery-full" d="M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z"></path> + <path class="path-icon transparent" id = "battery-full" d="M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z"></path> <!-- Empty --> <path class="path-icon-alarm transparent" id = "battery-empty" d="M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z"></path> <!--Three Quarter --> @@ -52,15 +55,6 @@ <path class="path-icon-alarm transparent" id ="battery-one-quarter" d="M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z"> </svg> </ul> - <ul class = "navbar-nav ml-auto mr-0 mr-md-3 my-2 my-md-0"> - <a class="unlock" id="toggle_lock" onclick="toggle_lock()"> - <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" class="svg-inline--fa fa-lock fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> - <path class="path-icon" id = "path-locked-main" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> - <path class="path-icon transparent" id="path-unlocked-main" d="M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"></path> - </svg> - </a> - </ul> - </nav> <div id="layoutSidenav"> @@ -68,23 +62,23 @@ <nav class="sb-sidenav accordion sb-sidenav-dark px-1" id="sidenavAccordion"> <div class="sb-sidenav-menu"> <div class="nav"> - <a href="/"> <div id="fan-icon" class = "sb-nav-link-icon border-invisible {{'active' if fan_active }}"> + <a href="/" class = "nav-link-href nav-link-disabled"> <div id="fan-icon" class = "sb-nav-link-icon border-invisible {{'active' if fan_active }}"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="user-md" class="fa-user-md fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path class="path-icon" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zM104 424c0 13.3 10.7 24 24 24s24-10.7 24-24-10.7-24-24-24-24 10.7-24 24zm216-135.4v49c36.5 7.4 64 39.8 64 78.4v41.7c0 7.6-5.4 14.2-12.9 15.7l-32.2 6.4c-4.3.9-8.5-1.9-9.4-6.3l-3.1-15.7c-.9-4.3 1.9-8.6 6.3-9.4l19.3-3.9V416c0-62.8-96-65.1-96 1.9v26.7l19.3 3.9c4.3.9 7.1 5.1 6.3 9.4l-3.1 15.7c-.9 4.3-5.1 7.1-9.4 6.3l-31.2-4.2c-7.9-1.1-13.8-7.8-13.8-15.9V416c0-38.6 27.5-70.9 64-78.4v-45.2c-2.2.7-4.4 1.1-6.6 1.9-18 6.3-37.3 9.8-57.4 9.8s-39.4-3.5-57.4-9.8c-7.4-2.6-14.9-4.2-22.6-5.2v81.6c23.1 6.9 40 28.1 40 53.4 0 30.9-25.1 56-56 56s-56-25.1-56-56c0-25.3 16.9-46.5 40-53.4v-80.4C48.5 301 0 355.8 0 422.4v44.8C0 491.9 20.1 512 44.8 512h358.4c24.7 0 44.8-20.1 44.8-44.8v-44.8c0-72-56.8-130.3-128-133.8z"></path></svg> </div></a> - <a href="prototype"> <div class = "sb-nav-link-icon border-invisible {{'active' if prototype_active}}"> + <a href="prototype" class = "nav-link-href nav-link-disabled"> <div class = "sb-nav-link-icon border-invisible {{'active' if prototype_active}}"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="fan" class="fa-fan fa-w-15" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="path-icon" d="M352.57 128c-28.09 0-54.09 4.52-77.06 12.86l12.41-123.11C289 7.31 279.81-1.18 269.33.13 189.63 10.13 128 77.64 128 159.43c0 28.09 4.52 54.09 12.86 77.06L17.75 224.08C7.31 223-1.18 232.19.13 242.67c10 79.7 77.51 141.33 159.3 141.33 28.09 0 54.09-4.52 77.06-12.86l-12.41 123.11c-1.05 10.43 8.11 18.93 18.59 17.62 79.7-10 141.33-77.51 141.33-159.3 0-28.09-4.52-54.09-12.86-77.06l123.11 12.41c10.44 1.05 18.93-8.11 17.62-18.59-10-79.7-77.51-141.33-159.3-141.33zM256 288a32 32 0 1 1 32-32 32 32 0 0 1-32 32z"></path></svg> </div></a> - <a href="charts"> <div class = "sb-nav-link-icon border-invisible {{'active' if charts_active}}"> + <a href="charts" class = "nav-link-href nav-link-disabled"> <div class = "sb-nav-link-icon border-invisible {{'active' if charts_active}}"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chart-area" class="fa-chart-area fa-w-15" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="path-icon" d="M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z"></path></svg> </div></a> - <a href="chartsLoop"> <div class = "sb-nav-link-icon border-invisible {{'active' if chartsLoop_active}}"> + <a href="chartsLoop" class = "nav-link-href nav-link-disabled"> <div class = "sb-nav-link-icon border-invisible {{'active' if chartsLoop_active}}"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chart-line" class="fa-chart-line fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="path-icon" d="M 496,384 H 64 V 80 C 64,71.2 57,64 48,64 H 16 C 7,64 0,71 0,80 v 336 c 0,18 14,32 32,32 h 464 c 9,0 16,-7 16,-16 v -32 c 0,-9 -7,-16 -16,-16 z M 296,79 c -9,-15 -48,-18 -60,-6 L 86,220 c -6,6 -6,16 0,23 L 116,275 c 6,6 16,6 22,0 L 267,143 386,266 H 233 v -22 c -1,-8 -1,-8 -9,-2 l -59,59 56,61 c 8,8 9,9 10,0 v -30 H 440 c 23,0 37,-45 24,-66 z"> </div></a> - <a href="logs"> <div class = "sb-nav-link-icon border-invisible {{'active' if logs_active}}"> + <a href="logs" class = "nav-link-href nav-link-disabled"> <div class = "sb-nav-link-icon border-invisible {{'active' if logs_active}}"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="exclamation-circle" class="fa-chart-area fa-w-15" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="path-icon" fill="currentColor" d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"></path></svg> </div></a> - <a href="settings"> <div class = "sb-nav-link-icon border-invisible {{'active' if settings_active}}"> + <a href="settings" class = "nav-link-href nav-link-disabled"> <div class = "sb-nav-link-icon border-invisible {{'active' if settings_active}}"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sliders-h" class="fa-sliders-h fa-w-15" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="path-icon" d="M496 384H160v-16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h80v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h336c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-160h-80v-16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h336v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h80c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-160H288V48c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16C7.2 64 0 71.2 0 80v32c0 8.8 7.2 16 16 16h208v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h208c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16z"></path></svg> </div></a> @@ -108,11 +102,25 @@ {% endblock %} </div> </div> + + + + <div class = "lock"> + <a class="unlock" id="toggle_lock" onclick="toggle_lock()"> + <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" class="fa-lock" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> + <path class="path-icon" id = "path-locked-main" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> + <path class="path-icon transparent" id="path-unlocked-main" d="M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"></path> + </svg> + </a> + </div> + + <script src="{{ url_for('static', filename='js/jquery-3.4.1.min.js') }}"></script> <script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script> <script src="{{ url_for('static', filename='js/Chart.min.js') }}"></script> <script src="{{ url_for('static', filename='js/moment.js') }}"></script> - <script src="{{ url_for('static', filename='js/Chart.js') }}"></script> + <script src="{{ url_for('static', filename='js/Chart.js') }}"></script> + <script src="{{ url_for('static', filename='js/Gauge.js') }}"></script> <script src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script> <script src="{{ url_for('static', filename='js/dataTables.bootstrap4.min.js') }}"></script> @@ -134,8 +142,16 @@ var lockTimer; + var idleTimer; var unlocked = Boolean(false); - + + {% if not fan_active %} + idleTimer = setTimeout( idleRedirect, 5000 ); + {% endif %} + function idleRedirect(){ + window.location.href = "/"; + } + function timeOutLock(){ window.createNotification({ closeOnClick: 1, @@ -198,6 +214,9 @@ function unlock(){ var x = document.getElementsByClassName("input-editable"); for (i = 0; i < x.length; i++) {x[i].readOnly=false;x[i].disabled = false;} + var l = document.getElementsByClassName("nav-link-href"); + for (i = 0; i < l.length; i++) {l[i].classList.remove("nav-link-disabled");} + var el = document.getElementById("path-locked-main"); el.classList.add("transparent"); var el2 = document.getElementById("path-unlocked-main"); @@ -209,15 +228,18 @@ function lock() { - var x = document.getElementsByClassName("input-editable"); + clearTimeout(lockTimer); + var x = document.getElementsByClassName("input-editable"); for (i = 0; i < x.length; i++) {x[i].readOnly=true;x[i].disabled = true;} + var l = document.getElementsByClassName("nav-link-href"); + for (i = 0; i < l.length; i++) {l[i].classList.add("nav-link-disabled");} var el = document.getElementById("path-locked-main"); el.classList.remove("transparent"); var el2 = document.getElementById("path-unlocked-main"); el2.classList.add("transparent"); unlocked = 0; } - function toggle_lock() { + function toggle_lock() { setTimeout(function(){ var x = document.getElementsByClassName("input-editable"); if ( x.length > 0 && x[0].readOnly == false ){lock();} @@ -232,18 +254,33 @@ if (unlocked) { clearTimeout(lockTimer); lockTimer = setTimeout('timeOutLock()', 10000); + } - }) - $(this).keypress(function (e) { + + {% if not fan_active %} + clearTimeout(idleTimer); + idleTimer = setTimeout( idleRedirect, 5000 ); + {% endif %} + }); + + $(this).keypress(function (e) { + console.log('keypress'); if (unlocked) { clearTimeout(lockTimer); - lockTimer = setTimeout('timeOutLock()', 10000);} - }) + lockTimer = setTimeout('timeOutLock()', 10000); + } + {% if not fan_active %} + clearTimeout(idleTimer); + idleTimer = setTimeout( idleRedirect, 5000 ); + {% endif %} + }); - var battery = 100; + var battery = 200; function update_battery() { // set all transparent + var powered = document.getElementById("powered"); + powered.classList.add("transparent"); var full = document.getElementById("battery-full"); full.classList.add("transparent"); three_qtr = document.getElementById("battery-three-quarter"); @@ -256,18 +293,46 @@ empty.classList.add("transparent"); - // find the one to show - if ( battery >=87.5 ) {full.classList.remove("transparent");} + // find the one to show + if (battery > 100.0) { powered.classList.remove("transparent"); } + else if ( battery >=87.5 && battery <= 100.0 ) {full.classList.remove("transparent");} else if (battery >= 67.5 && battery < 87.5) { three_qtr.classList.remove("transparent"); } else if (battery >= 37.5 && battery < 67.5) { half.classList.remove("transparent"); } else if (battery >= 7.5 && battery < 37.5) { one_qtr.classList.remove("transparent"); } else { empty.classList.remove("transparent"); } battery = battery - 1; - if (battery <= 0 ) battery = 100; - } - var batteryInterval = setInterval('update_battery()', 1000); - </script> + if (battery <= 0 ) battery = 200; + } var batteryInterval = setInterval('update_battery()', 1000); + var prev_val; +$('.input-editable').focus(function() { + prev_val = $(this).val(); +}).change(function() { +$(this).blur() // Firefox fix as suggested by AgDude + +/*window.createNotification({ + closeOnClick: 0, + displayCloseButton: 1, + positionClass: "nfc-bottom-right", + showDuration: false, + theme: "info" + })({ + title: "Screen Lock", + message: "Screen has locked due to timeout" + });*/ + var success = confirm('Are you sure you want to change the ' + $(this).name + " from" + prev_val + " to " + $(this).val()); + if(success) +{ +//send to hevserver +$(this).val($(this).val()); + } + else + { + $(this).val(prev_val); +} +lock(); +}); + </script> </body> diff --git a/raspberry-backend/templates/charts.html b/raspberry-backend/templates/charts.html index d06d11e2cbb72ac046a63a1038cfd145a6df015a..71ad272c97c453a79380576231355145c637d7d4 100644 --- a/raspberry-backend/templates/charts.html +++ b/raspberry-backend/templates/charts.html @@ -15,28 +15,16 @@ <div class = "col-md-10 py-0"> <div class="row"> - <div class="col-md-12"> - <div class="card mb-6"> <!-- <div class="card-chart-header small ">Pressure [mbar]</div> --> - <div class="card-body px-0 py-0"><canvas id="pressure_chart" width="200%" height="30"></canvas></div> - </div> - </div> + <div class="main-chart-container"><canvas id="pressure_chart"></canvas></div> </div> <div class = "row"> - <div class="col-md-12"> - <div class="card mb-6 px-0 py-0"> <!-- <div class="card-chart-header small">Flow [mL/min]</div> --> - <div class="card-body px-0 py-0"><canvas id="flow_chart" width="200%" height="30"></canvas></div> - </div> - </div> + <div class="main-chart-container"><canvas id="flow_chart"></canvas></div> </div> <div class = "row"> - <div class="col-md-12"> - <div class="card mb-6 px-0 py-0"> <!-- <div class="card-chart-header small ">Volume [mL]</div> --> - <div class="card-body px-0 py-0"><canvas id="volume_chart" width="200%" height="30"></canvas></div> - </div> - </div> + <div class="main-chart-container"><canvas id="volume_chart"></canvas></div> </div> </div> diff --git a/raspberry-backend/templates/index.html b/raspberry-backend/templates/index.html index 4afcaf9aeffa01c19b787058ba9dcd4d042df488..9c03789c022d079aa43dba2de7cc4501031da75e 100644 --- a/raspberry-backend/templates/index.html +++ b/raspberry-backend/templates/index.html @@ -8,53 +8,43 @@ <main> <div class="container-fluid"> - <!--<h1 class="mt-4">Info</h1> !--> <div class = "row"> - <div class = "col-md-7 py-0"> - <div class="row col-center pb-1"> - <div class = "col-md-8 px-0 py-0"> - <select id='chart_variables' multiple placeholder = "Select Plots"> - <option value='pressure_air_supply' selected>Air (supply)</option> - <option value='pressure_air_regulated' selected>Air (regulated)</option> - <option value='pressure_o2_supply' selected>O2 (supply)</option> - <option value='pressure_o2_regulated' selected>O2 (regulated)</option> - <option value='pressure_buffer' selected>Buffer</option> - <option value='pressure_inhale' selected>Inhale</option> - <option value='temperature_buffer' selected>temperature_buffer</option> - <option value='pressure_patient' selected>Patient</option> - <option value='pressure_diff_patient' selected>Patient (diff)</option> - <!-- VICTOR test --> - <option value='pressure_buffer' selected>Pressure</option> - <option value='pressure_inhale' selected>Flow</option> - <option value='temperature_buffer' selected>Volume</option> - </select> - </div> - <div class = "col-md-3"> - <input class="form-button" type="button" value="Submit" onclick="updateChartType()"> - </div> - </div> + <div class = "col-charts-main"> <!-- chart on left --> - - <div class="row"> - <div class="col-md-12"> - <div class="card mb-6"> - <div class="card-body px-0 py-0 tiny"><canvas id="pressure_air_supply" width="100%" height="80px"></canvas></div> - </div> - </div> - </div> + <div class="row"> + <div class="col-md-12"> + <div class = "main-chart-container"><canvas id="pressure_chart"></canvas></div> + </div> + </div> + <div class = "row"> + <div class="col-md-12"> + <div class="main-chart-container"><canvas id="flow_chart"></canvas></div> + </div> + </div> + <div class = "row"> + <div class="col-md-12"> + <div class = "main-chart-container"><canvas id="volume_chart"></canvas></div> + </div> + </div> + + <div class = "row"> + <div class = "range-button-container ml-auto mr-auto"> + <input type="button" class="sb-nav-button" name="fivesecs" value="5s" onclick="setChartXaxisRange(-5,0)"> + <input type="button" class="sb-nav-button" name="thirtysecs" value="30s" onclick="setChartXaxisRange(-30,0)"> + <input type="button" class="sb-nav-button" name="sixtysecs" value="60s" onclick="setChartXaxisRange(-60,0)"> + <input type="button" class="sb-nav-button" name="ninetysecs" value="90s" onclick="setChartXaxisRange(-90,0)"> + </div> + </div> </div> - - - <div class = "col-md-5 py-0 px-0 mr-0 pl-1"> + <div class = "col-cards-main"> + <div class = "row"> <!---- row 1 --> - <div class="row"> - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + <div class="card-reading br-red"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <span class="small text-dark col-center" href="#">Mode</span> </div> - <div class="card-body px-1 py-1 ml-auto mr-auto"> - <select class = "input-reading input-editable br-red" name="VentilatorMode" id="vent_mode" placeholder = "PC-A/C" disabled readOnly> + <div class="card-body px-1 py-1"> + <select class = "input-reading input-editable" name="VentilatorMode" id="vent_mode" placeholder = "PC-A/C" disabled readOnly> <optgroup label = "Pressure Control Modes"> <option value="opt1" selected>PC-A/C</option> <option value="opt2">PC-A/C-PRVC</option> @@ -65,118 +55,96 @@ </optgroup> </select> </div> - </div> </div> - - <div class="col-xl-4 px-1 py-0 mr-0"> - <div class="card bg-primary text-dark mb-2"> + + <div class="card-reading br-red"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <a class="small text-dark col-center" href="#">FIO<sub>2</sub></a> </div> - <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading py-0" id = "fio2" value="62" type="number" readOnly disabled>%</div> - </div> + <!-- <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading py-0" id = "fio2" value="62" type="number" readOnly disabled>%</div> --> + <div class = "main-chart-container"><canvas id="example_gauge"></canvas></div> </div> - <div class="col-xl-4 px-1 py-0 mr-0"> - <div class="card bg-primary text-dark mb-2"> + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <a class="small text-dark col-center" href="#">P<sub>Peak</sub></a> </div> - <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id="p_peak" readOnly disabled value=20.0>cmH2O</div> + <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id="p_peak" readOnly disabled value=20.0>cmH2O</div> </div> - </div> - </div> - <!--- end row 1 --> + <!--- end row 1 --> + <!-- row 2 --> - <div class = "row"> - <div class="col-xl-4 px-1 py-0 mr-0"> - <div class="card bg-primary text-dark mb-2"> + + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <a class="small text-dark col-center" href="#">P<sub>Plateau</sub></a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id = "p_plateau" value=4.0 readOnly disabled>cmH2O</div> - </div> - </div> - <div class="col-xl-4 px-1 py-0 mr-0"> - <div class="card bg-primary text-dark mb-2"> + </div> + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <a class="small text-dark col-center" href="#">P<sub>Mean</sub></a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id = "p_mean" value=13.0 readOnly disabled>cmH2O</div> - </div> - </div> - - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + </div> + + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <a class="small text-dark col-center" href="#">PEEP</a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading input-editable" onclick="show_easy_numpad_wrapper(this);lock();" id = "pressure_buffer" value=5 readOnly disabled>cmH2O</div> </div> - </div> - - </div> + <!-- end row 2 --> - + <!-- row 3 --> - - <div class="row"> - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + + + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between small py-1 min-height-1b"> <a class="small text-dark col-center" href="#">VTI</a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id = "vti" value=285 readOnly disabled></span> mL</div> - </div> </div> - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between small py-1 min-height-1b"> <a class="small text-dark col-center" href="#">VTE</a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id = "vte" value=273 readOnly disabled>mL</div> </div> - </div> - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 small min-height-1b"> <a class="small text-dark col-center" href="#">MVI</a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id = "mvi" value=6.5 readOnly disabled>L/min</div> </div> - </div> - </div> + + <!-- row 4 --> - <div class="row"> - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 small min-height-1b"> <a class="small text-dark col-center" href="#">MVE</a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading" id = "mve" value=6.0 readOnly disabled> L/min</div> </div> - </div> - - <div class="col-xl-4 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> + + <div class="card-reading"> <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> <a class="small text-dark col-center" href="#">I:E Ratio</a> </div> <div class="card-body px-1 py-1 tiny ml-auto mr-auto"><input class = "input-reading input-editable" id = "ie_ratio" value=1.3 readOnly disabled onclick="show_easy_numpad_wrapper(this);lock();"> </div> </div> - </div> - - <div class="col-xl-4 px-1 py-0"> - </div> </div> <!-- end row 4 --> - </div> </div> - </div> +</div> +</div> </div> </main> {% endblock %} @@ -192,11 +160,11 @@ document.getElementById("pressure_inhale").innerHTML = data.pressure_inhale.toPrecision(5); //document.getElementById("temperature_buffer").innerHTML = data.temperature_buffer.toPrecision(5); document.getElementById("pressure_air_supply").innerHTML = data.pressure_air_supply.toPrecision(5); - document.getElementById("pressure_air_regulated").innerHTML = data.pressure_air_regulated.toPrecision(5); + document.getElementById("pressure_air_regulated").innerHTML = data.pressure_air_regulated.toPrecision(5); document.getElementById("pressure_o2_supply").innerHTML = data.pressure_o2_supply.toPrecision(5); document.getElementById("pressure_o2_regulated").innerHTML = data.pressure_o2_regulated.toPrecision(5); document.getElementById("pressure_patient").innerHTML = data.pressure_patient.toPrecision(5); - document.getElementById("pressure_diff_patient").innerHTML = data.pressure_diff_patient.toPrecision(5); + document.getElementById("pressure_diff_patient").innerHTML = data.pressure_diff_patient.toPrecision(5); document.getElementById("fsm_state").innerHTML = data.fsm_state.toPrecision(1); //document.getElementById("version").innerHTML = data.version.toPrecision(1); //Commented because not included in the html part */ @@ -204,11 +172,11 @@ //document.getElementById("pressure_inhale").innerHTML = (data.pressure_inhale).toFixed(2); //document.getElementById("temperature_buffer").innerHTML = (data.temperature_buffer).toFixed(2); //document.getElementById("pressure_air_supply").innerHTML = (data.pressure_air_supply).toFixed(2); - //document.getElementById("pressure_air_regulated").innerHTML = (data.pressure_air_regulated).toFixed(2); + //document.getElementById("pressure_air_regulated").innerHTML = (data.pressure_air_regulated).toFixed(2); //document.getElementById("pressure_o2_supply").innerHTML = (data.pressure_o2_supply).toFixed(2); //document.getElementById("pressure_o2_regulated").innerHTML = (data.pressure_o2_regulated).toFixed(2); //document.getElementById("pressure_patient").innerHTML = (data.pressure_patient).toFixed(2); - //document.getElementById("pressure_diff_patient").innerHTML = (data.pressure_diff_patient).toFixed(2); + //document.getElementById("pressure_diff_patient").innerHTML = (data.pressure_diff_patient).toFixed(2); //document.getElementById("fsm_state").innerHTML = (data.fsm_state).toFixed(2); //document.getElementById("version").innerHTML = (data.version).toFixed(2); //Commented because not included in the html part } @@ -217,34 +185,14 @@ setInterval('update_variables()', 1000); </script> - + {% endblock %} {% block body_scripts %} -<script src="{{ url_for('static', filename='js/Chart-plot.js') }}"></script> +<script src="{{ url_for('static', filename='js/Chart-display.js') }}"></script> - <script> -var prev_val; - -$('.input-editable').focus(function() { - prev_val = $(this).val(); -}).change(function() { - $(this).blur() // Firefox fix as suggested by AgDude - var success = confirm('Are you sure you want to change the ' + $(this).name + " from" + prev_val + " to " + $(this).val()); - if(success) -{ -//send to hevserver -$(this).val($(this).val()); - } - else - { - $(this).val(prev_val); -} -lock(); -}); - </script> <script> pickout.to({ el:'.pickout',