You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.8 KiB
132 lines
3.8 KiB
import m from 'mithril'; |
|
|
|
export interface Status { |
|
batteryVoltage: number; // in Volts |
|
motorCurrent: number; // in Amperes |
|
speed: number; // in meters per second |
|
tripDistance: number; // in meters |
|
tripTotalTime: number; // in seconds |
|
tripMovingTime: number; // in seconds |
|
tripAscendingElevation: number; // in meters |
|
tripMotorEnergy: number; // in Watt-hour |
|
temperature: number; // in Celcius degrees |
|
altitude: number; // in meters above sea level |
|
}; |
|
|
|
interface ApiStatus { |
|
v: number; // voltage (mV) |
|
c: number; // current (mA) |
|
s: number; // speed (mm/s) |
|
td: number; // trip distance (m) |
|
ttt: number; // trip total time (s) |
|
tmt: number; // trip moving time (s) |
|
tae: number; // trip ascending elevation (m) |
|
tme: number; // trip motor energy (Wh) |
|
temp: number; // temperature (tenth of °C) |
|
alt: number; // altitude (mm) |
|
} |
|
|
|
export class MonitorApi { |
|
private mockServer: boolean; |
|
private lastStatus: Status = null; |
|
private static api: MonitorApi = null; |
|
|
|
private lastFetchTime = 0; |
|
private lastFetchAltitude = -100000; |
|
|
|
private mockedTripDistance = 0; |
|
private mockedTripTotalTime = 0; |
|
private mockedTripMovingTime = 0; |
|
private mockedTripAscendingElevation = 0; |
|
private mockedTripMotorEnergy = 0; |
|
|
|
constructor() { |
|
this.mockServer = window.location.protocol == "file:"; |
|
} |
|
|
|
static get() { |
|
if(MonitorApi.api == null) |
|
MonitorApi.api = new MonitorApi(); |
|
return MonitorApi.api; |
|
} |
|
|
|
getStatus() { return this.lastStatus; } |
|
|
|
async fetchStatus(): Promise<Status> { |
|
let apiStatus: ApiStatus; |
|
|
|
if(this.mockServer) { |
|
await new Promise(resolve => setTimeout(resolve, 200)); |
|
|
|
let t = Date.now() / 1000.0; |
|
if(this.lastFetchTime == 0) this.lastFetchTime = t; |
|
let dt = t - this.lastFetchTime; |
|
this.lastFetchTime = t; |
|
|
|
let speed = (Math.cos(t*0.3)+1.0)*0.5 * 14; // in meters per second |
|
if(speed < 0.25) speed = 0; |
|
|
|
this.mockedTripDistance += speed * dt; |
|
this.mockedTripTotalTime += dt; |
|
if(speed > 0) |
|
this.mockedTripMovingTime += dt; |
|
|
|
let altitude = (Math.cos(t*0.0001)+1.0)*0.5 * 4500 - 200 + (Math.cos(t*0.03))*0.5 * 60; // in meters |
|
if(this.lastFetchAltitude == -100000) this.lastFetchAltitude = altitude; |
|
let altitudeChange = altitude - this.lastFetchAltitude; |
|
this.lastFetchAltitude = altitude; |
|
|
|
if(altitudeChange > 0) |
|
this.mockedTripAscendingElevation += altitudeChange; |
|
|
|
let voltage = (Math.cos(t*0.4)+1.0)*0.5 * 6 + 36; |
|
let current = (Math.cos(t*0.7)+1.0)*0.5 * 30; |
|
let newEnergy = voltage * current * dt / 3600; |
|
this.mockedTripMotorEnergy += newEnergy; |
|
|
|
apiStatus = { |
|
v: Math.round(voltage * 1000), |
|
c: Math.round(current * 1000), |
|
s: Math.round(speed * 1000), |
|
td: Math.round(this.mockedTripDistance), |
|
ttt: Math.round(this.mockedTripTotalTime), |
|
tmt: Math.round(this.mockedTripMovingTime), |
|
tae: Math.round(this.mockedTripAscendingElevation*10.0), |
|
tme: Math.round(this.mockedTripMotorEnergy*10.0), |
|
temp: Math.round((Math.cos(t*0.2)+1.0)*0.5 * 400 - 100), |
|
alt: Math.round(altitude * 1000) |
|
}; |
|
} else { |
|
apiStatus = await new Promise<ApiStatus>((resolve, error) => { |
|
let request = new XMLHttpRequest(); |
|
request.onreadystatechange = () => { |
|
if(request.readyState == 4) { |
|
if(request.status == 200) { |
|
resolve(JSON.parse(request.response)); |
|
} |
|
else { |
|
error(); |
|
} |
|
} |
|
}; |
|
request.open('GET', '/api/status', true); |
|
request.send(); |
|
}); |
|
} |
|
|
|
this.lastStatus = { |
|
batteryVoltage: apiStatus.v / 1000, |
|
motorCurrent: apiStatus.c / 1000, |
|
speed: apiStatus.s / 1000, |
|
tripDistance: apiStatus.td, |
|
tripTotalTime: apiStatus.ttt, |
|
tripMovingTime: apiStatus.tmt, |
|
tripAscendingElevation: apiStatus.tae / 10, |
|
tripMotorEnergy: apiStatus.tme / 10, |
|
temperature: apiStatus.temp / 10, |
|
altitude: apiStatus.alt / 1000 |
|
}; |
|
|
|
return this.lastStatus; |
|
} |
|
}
|
|
|