Added menu with two pages (RawDataPage and DashboardPage)
Added temperature and altitude display in RawDataPage
This commit is contained in:
parent
127fd6176c
commit
f5ea6054da
@ -10,7 +10,6 @@
|
|||||||
"author": "Youen Toupin",
|
"author": "Youen Toupin",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mithril": "^2.0.4"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mithril": "^2.0.9",
|
"@types/mithril": "^2.0.9",
|
||||||
@ -20,6 +19,8 @@
|
|||||||
"ts-loader": "^9.2.8",
|
"ts-loader": "^9.2.8",
|
||||||
"typescript": "^4.6.2",
|
"typescript": "^4.6.2",
|
||||||
"webpack": "^5.70.0",
|
"webpack": "^5.70.0",
|
||||||
"webpack-cli": "^4.9.2"
|
"webpack-cli": "^4.9.2",
|
||||||
|
"bulma": "^0.9.3",
|
||||||
|
"mithril": "^2.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
import m from 'mithril';
|
import m from 'mithril';
|
||||||
import MainPage from './main-page';
|
|
||||||
|
|
||||||
m.mount(document.body, MainPage);
|
import Layout from './layout';
|
||||||
|
import RawDataPage from './raw-data-page';
|
||||||
|
import DashboardPage from './dashboard-page';
|
||||||
|
|
||||||
|
require('../node_modules/bulma/css/bulma.css');
|
||||||
|
|
||||||
|
m.route(document.body, "/raw", {
|
||||||
|
"/dashboard": { render: () => m(Layout, m(DashboardPage)) },
|
||||||
|
"/raw": { render: () => m(Layout, m(RawDataPage)) },
|
||||||
|
});
|
||||||
|
29
WebApp/src/dashboard-page.tsx
Normal file
29
WebApp/src/dashboard-page.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import m from 'mithril';
|
||||||
|
import { MonitorApi, Status } from './monitor-api';
|
||||||
|
|
||||||
|
export default class DashboardPage {
|
||||||
|
api = new MonitorApi();
|
||||||
|
status?: Status;
|
||||||
|
autoRefresh = true;
|
||||||
|
|
||||||
|
oninit() {
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
onbeforeremove() {
|
||||||
|
this.autoRefresh = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async refresh() {
|
||||||
|
this.status = await this.api.getStatus();
|
||||||
|
if(this.autoRefresh)
|
||||||
|
setTimeout(() => { if(this.autoRefresh) this.refresh(); }, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
view() {
|
||||||
|
return this.status
|
||||||
|
? <div class="dashboard-page">
|
||||||
|
</div>
|
||||||
|
: <p>Chargement...</p>;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<title>Ordinateur de bord</title>
|
<title>Ordinateur de bord</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
3
WebApp/src/layout.css
Normal file
3
WebApp/src/layout.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/*html body {
|
||||||
|
font-size: 3rem;
|
||||||
|
}*/
|
33
WebApp/src/layout.tsx
Normal file
33
WebApp/src/layout.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import m from 'mithril';
|
||||||
|
|
||||||
|
require("./layout.css");
|
||||||
|
|
||||||
|
export default class Layout {
|
||||||
|
private menuActive = false;
|
||||||
|
|
||||||
|
view(vnode: m.Vnode) {
|
||||||
|
return [
|
||||||
|
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item" href='#!/dashboard'>Tableau de bord</a>
|
||||||
|
|
||||||
|
<a role="button" class={'navbar-burger ' + (this.menuActive ? 'is-active' : '')} onclick={() => this.menuActive = !this.menuActive} aria-label="menu" aria-expanded="false" data-target="mainMenu">
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="mainMenu" class={'navbar-menu ' + (this.menuActive ? 'is-active' : '')}>
|
||||||
|
<div class="navbar-start" onclick={() => { this.menuActive = false; return true; }}>
|
||||||
|
<a class="navbar-item" href='#!/raw'>Données brutes</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>,
|
||||||
|
|
||||||
|
<section>
|
||||||
|
{vnode.children}
|
||||||
|
</section>
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +0,0 @@
|
|||||||
.main-page p {
|
|
||||||
font-size: 4rem;
|
|
||||||
}
|
|
@ -1,19 +1,26 @@
|
|||||||
import m from 'mithril';
|
import m from 'mithril';
|
||||||
|
|
||||||
export interface Status {
|
export interface Status {
|
||||||
batteryVoltage: number;
|
batteryVoltage: number; // in Volts
|
||||||
motorCurrent: number;
|
motorCurrent: number; // in Amperes
|
||||||
speed: number; // in meters per second
|
speed: number; // in meters per second
|
||||||
|
temperature: number; // in Celcius degrees
|
||||||
|
altitude: number; // in meters above sea level
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ApiStatus {
|
interface ApiStatus {
|
||||||
v: number;
|
v: number;
|
||||||
c: number;
|
c: number;
|
||||||
s: number;
|
s: number;
|
||||||
|
t: number;
|
||||||
|
alt: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MonitorApi {
|
export class MonitorApi {
|
||||||
constructor(private mockServer: boolean) {
|
private mockServer: boolean;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.mockServer = window.location.protocol == "file:";
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStatus(): Promise<Status> {
|
async getStatus(): Promise<Status> {
|
||||||
@ -24,7 +31,9 @@ export class MonitorApi {
|
|||||||
apiStatus = {
|
apiStatus = {
|
||||||
v: Math.random() * 20000 + 20000,
|
v: Math.random() * 20000 + 20000,
|
||||||
c: Math.random() * 30000,
|
c: Math.random() * 30000,
|
||||||
s: Math.random() * 14000
|
s: Math.random() * 14000,
|
||||||
|
t: Math.random() * 400 - 100,
|
||||||
|
alt: Math.random() * 4500000 - 200000
|
||||||
}
|
}
|
||||||
setTimeout(() => m.redraw(), 0);
|
setTimeout(() => m.redraw(), 0);
|
||||||
} else {
|
} else {
|
||||||
@ -37,7 +46,9 @@ export class MonitorApi {
|
|||||||
return {
|
return {
|
||||||
batteryVoltage: apiStatus.v / 1000,
|
batteryVoltage: apiStatus.v / 1000,
|
||||||
motorCurrent: apiStatus.c / 1000,
|
motorCurrent: apiStatus.c / 1000,
|
||||||
speed: apiStatus.s / 1000
|
speed: apiStatus.s / 1000,
|
||||||
|
temperature: apiStatus.t / 10,
|
||||||
|
altitude: apiStatus.alt / 1000
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
WebApp/src/raw-data-page.css
Normal file
3
WebApp/src/raw-data-page.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.raw-data-page p {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import m from 'mithril';
|
import m from 'mithril';
|
||||||
import { MonitorApi, Status } from './monitor-api';
|
import { MonitorApi, Status } from './monitor-api';
|
||||||
|
|
||||||
require("./main-page.css");
|
require("./raw-data-page.css");
|
||||||
|
|
||||||
export default class MainPage {
|
export default class RawDataPage {
|
||||||
api = new MonitorApi(false);
|
api = new MonitorApi();
|
||||||
status?: Status;
|
status?: Status;
|
||||||
autoRefresh = true;
|
autoRefresh = true;
|
||||||
|
|
||||||
@ -24,11 +24,13 @@ export default class MainPage {
|
|||||||
|
|
||||||
view() {
|
view() {
|
||||||
return this.status
|
return this.status
|
||||||
? <div class="main-page">
|
? <div class="raw-data-page">
|
||||||
<p>Tension batterie : {this.status.batteryVoltage.toFixed(3)}V</p>
|
<p>Tension batterie : {this.status.batteryVoltage.toFixed(3)}V</p>
|
||||||
<p>Courant : {this.status.motorCurrent.toFixed(3)}A</p>
|
<p>Courant : {this.status.motorCurrent.toFixed(3)}A</p>
|
||||||
<p>Puissance : {(this.status.batteryVoltage * this.status.motorCurrent).toFixed(1)}W</p>
|
<p>Puissance : {(this.status.batteryVoltage * this.status.motorCurrent).toFixed(1)}W</p>
|
||||||
<p>Vitesse : {(this.status.speed * 3.6).toFixed(1)}km/h</p>
|
<p>Vitesse : {(this.status.speed * 3.6).toFixed(1)}km/h</p>
|
||||||
|
<p>Temperature : {this.status.temperature.toFixed(1)}°C</p>
|
||||||
|
<p>Altitude : {this.status.altitude.toFixed(1)}m</p>
|
||||||
</div>
|
</div>
|
||||||
: <p>Chargement...</p>;
|
: <p>Chargement...</p>;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user