layout | title | nav-menu | show_tile | permalink |
---|---|---|---|---|
pageContent |
Plugins |
false |
false |
PLUGINS.html |
Plugins can be developed within the application. The plugins are written in typescript/javascript. The editor knows the definitions of the application api and the used libraries. This way it can give you full code completion support while editing. Saving the data will directly result into a update source. It is best to write and debug code in chrome.
A view examples plugins with one or more widgets can be installed from the "add from web" option.
The plugins are stored on github. You can fork te repository an push your own plugin
https://github.com/tijmenvangulik/Ergometerspace/tree/master/data/plugins
You can also send it to me using mail: [email protected]
To see what is possible open a popup menu. For more info on the editor:
[https://microsoft.github.io/monaco-editor]
To save ctrl S or mac command S. The widgets loaded by the plugin will be refreshed. When you get an typescript error during the save the code will not be saved.
All code is stored in your local storage. Clearing te browser history can remove all your code. It is best to export your code once in a while.
name | version | note | url |
---|---|---|---|
jquery | 1.8.3 | ||
jquery ui | 1.9.2 | ||
highcharts | gauge and charts | ||
socket.io | for server communcation | ||
bootstrap | 3.3.7 | ||
FileSaver | |||
require | dynamic loading extra scripts | ||
Font awesome | Icons | ||
jquery.ui.theme.font-awesome | Better icons for jquery ui based on font awesome | ||
typescript | 1.4.2 | [http://www.typescriptlang.org] (The editor is based on this version, for my own code I use 1.6.2 but I keep it backwards compatible with 1.4.2) | |
Validator | |||
jasny-bootstrap | |||
openlayer | |||
bootstrap-slider | |||
bootstrap-select | |||
bootstrap-dialog | |||
Monaco editor | |||
gridstack |
Type script reference [http://www.typescriptlang.org]
Included typescript (javascript) definitions:
All API definitions are stored here:
[http://www.vangulik.org/Ergometer/typescripts/]
Name | link |
---|---|
The application API | [http://www.vangulik.org/Ergometer/typescripts/ErgometerApp.d.ts] |
Highcharts | [http://www.vangulik.org/Ergometer/typescripts/highcharts.d.ts] |
jquery | [http://www.vangulik.org/Ergometer/typescripts/jquery.d.ts] |
jquery-ui | [http://www.vangulik.org/Ergometer/typescripts/jqueryui.d.ts] |
Require | [http://www.vangulik.org/Ergometer/typescripts/require.d.ts] |
Save as | [http://www.vangulik.org/Ergometer/typescripts/SaveAs.d.ts] |
All definitions can be viewed in the First Application API link. There are some important object which are documented in the following table:
object | Description |
---|---|
app | The global application object |
app.dashboard The main dashboard controller object | |
pm3.monitor | the connection to the ergometer |
ergometerServerClient.connection | connection to the server |
app.plugins | plugin manager |
newsTickers.infoTicker | shows news |
newsTickers.statusTicker | shows none blocking errors and info messages |
It is best to use chrome for debugging. The internal scripts are shown in the source group named (no domain) The name of your plugin will be used as name of the source. You should open an fresh debugger window after you update the script. If you do not do this you will not see your recent changes.
Settings break points in the debugger of the browser does not always work. The workaround is to add the debugger command to a line to stop it. You can add these break points by hand or your can click in the gutter margin. The break points only work if update the script and start a fresh new browser debugger.
You do not need to connect your computer to the ergometer for every test run. On the toolbar there is a button to play test data. Be default it plays back a recording of 100m. You can press the record button to record your own data.
There are a number of examples on writing widgets. All these widgets inherit from the ErgometerWidget or an higher class. It is possible you want to write a widget which is based on an existing div in the html page or you want to dynamically create the div. The ErgometerWidget always creates its own div. The ErgometerWidget is defined the following way:
class ErgometerWidget extends dashboard.Widget {
public initControl() {
//make a new div within the main control (by default the widgets uses an existing)
this.controller.$mainControl.append(
"<div id='"+this.name+"'' ></div>")
super.initControl();
}
}
class | description |
---|---|
dashboard.Widget | base widget class |
-> ergometerWidgets.ErgometerWidget | base widget class for all ergometer widgets |
-> -> ergometerWidgets.CanvasWidget | For all widgets which show a animation on a canvas |
-> -> ergometerWidgets.HighChartWidget | For chart widgets |
-> -> -> ergometerWidgets.GaugeWidget | for gauge widgets |
-> -> ergometerWidgets.ValueWidget | for displaying one value |
-> -> -> ergometerWidgets.StrokeValueWidget | for displaying a stroke value |
-> -> -> ergometerWidgets.TrainingValueWidget | for displaying training value |
The main application object contains some useful routines
class ErgometerApp {
//show an error on top of the page which the user has to click away
showTopError(messageText : string)
//show an error in the news ticker
showError(text : string)
//ask for an confirmation with yes, no as ansers
confirmYesNo(text : string,yesAnswer? : () =>void,noAnswer? : () =>void )
//ask for a confirm message
interface ConfirmButtons {
[name: string] : ()=>void;
}
confirm(text : string,buttons : ConfirmButtons )
}
var app : ErgometerApp;
Some handy utility functions
module utilities {
//format to a time value
function formatTimeValue(value: number, digits: number): string;
//format a relative date to a time
function formatRelativeTime(date: Date): string;
//check if an value is a number
function isNumber(n): bool;
//html 5 time out routine needed for animations
function requestTimeout(fn: any, delay: number);
//draw an ellipse on a canvas
function ellipse(context: CanvasRenderingContext2D, cx, cy, rx, ry: number): void;
}
Widgets subscribe them selves to ergometer data events to receive information. This is done on the visible changed method. This way a widget only receives data when it is visible. Ergometer Events are located in the pm3.monitor.pubsubs object.
public visibleChanged() {
if (this.visible) {
pm3.monitor.pubsubs.subStrokeDataUpdate(this, this.strokeDataUpdate);
pm3.monitor.pubsubs.subTrainingDataUpdate(this, this.trainingDataUpdate);
this.paint();
}
else {
pm3.monitor.pubsubs.unsubStrokeDataUpdate(this,this.strokeDataUpdate);
pm3.monitor.pubsubs.unsubTrainingDataUpdate(this,this.trainingDataUpdate);
}
super.visibleChanged();
}
Event | Description |
---|---|
subStrokeDataUpdate | Send at the end of the stroke with stroke data |
subPowerCurveUpdate | Send the power curve at the end of a stroke |
subTrainingDataUpdate | when the training changes this event will be called |
subNewStrokePhase | Change of stroke phase, Idle,Catch/drive/Dwell/Recovery |
subLiveForceUpdate | When force curve data is available it is directly send. This costs extra performance |
subError | monitor error happened |
subStarted | monitor start |
subStopped | monitor stopped |
subHistoryUpdate | history information added |