signalk-compass-calibrator 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +78 -0
- package/index.js +1111 -0
- package/lib/angles.js +70 -0
- package/lib/calibration.js +360 -0
- package/lib/plugin-schema.js +14 -0
- package/lib/profile-store.js +150 -0
- package/lib/prometheus-history-provider.js +310 -0
- package/package.json +50 -0
- package/public/app.js +1062 -0
- package/public/icon.svg +12 -0
- package/public/index.html +179 -0
- package/public/remoteEntry.js +54 -0
- package/public/screenshot.png +0 -0
- package/public/styles.css +527 -0
package/public/icon.svg
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-labelledby="title">
|
|
2
|
+
<title id="title">Compass Calibrator</title>
|
|
3
|
+
<circle cx="64" cy="64" r="58" fill="#102421"/>
|
|
4
|
+
<circle cx="64" cy="64" r="49" fill="#f7fbf8"/>
|
|
5
|
+
<circle cx="64" cy="64" r="40" fill="none" stroke="#d8ded8" stroke-width="4"/>
|
|
6
|
+
<path d="M64 17v16M64 95v16M17 64h16M95 64h16" fill="none" stroke="#f7fbf8" stroke-width="7" stroke-linecap="round"/>
|
|
7
|
+
<path d="M64 28l12 44-12 28-12-28z" fill="#11685d"/>
|
|
8
|
+
<path d="M64 28l12 44H64z" fill="#22a392"/>
|
|
9
|
+
<circle cx="64" cy="64" r="7" fill="#102421"/>
|
|
10
|
+
<path d="M35 91c15 14 43 14 58 0" fill="none" stroke="#2dd4bf" stroke-width="6" stroke-linecap="round"/>
|
|
11
|
+
<path d="M34 91l-8 1 3 8M94 91l8 1-3 8" fill="none" stroke="#2dd4bf" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Compass Calibrator</title>
|
|
7
|
+
<link rel="icon" href="./icon.svg" type="image/svg+xml">
|
|
8
|
+
<link rel="stylesheet" href="./styles.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<main class="shell">
|
|
12
|
+
<header class="topbar">
|
|
13
|
+
<div>
|
|
14
|
+
<h1>Compass Calibrator</h1>
|
|
15
|
+
<p>Batch-calibrate a selected magnetic heading source from source-aware historical data.</p>
|
|
16
|
+
</div>
|
|
17
|
+
</header>
|
|
18
|
+
<div id="message" class="message" hidden></div>
|
|
19
|
+
|
|
20
|
+
<nav class="tabs" aria-label="Main sections">
|
|
21
|
+
<button class="tabButton active" type="button" data-tab="calibrationTab">Calibrate</button>
|
|
22
|
+
<button class="tabButton" type="button" data-tab="calibrationsTab">Calibrations Store</button>
|
|
23
|
+
<button class="tabButton" type="button" data-tab="runtimeTab">Runtime</button>
|
|
24
|
+
</nav>
|
|
25
|
+
|
|
26
|
+
<section id="calibrationTab" class="tabPanel active">
|
|
27
|
+
<section class="panel">
|
|
28
|
+
<h2>Sources</h2>
|
|
29
|
+
<div class="grid">
|
|
30
|
+
<label>
|
|
31
|
+
History backend URL
|
|
32
|
+
<input id="baseUrl" value="http://victoriametrics:8428">
|
|
33
|
+
</label>
|
|
34
|
+
<label>
|
|
35
|
+
History username
|
|
36
|
+
<input id="historyUsername" autocomplete="username">
|
|
37
|
+
</label>
|
|
38
|
+
<label>
|
|
39
|
+
History password
|
|
40
|
+
<input id="historyPassword" type="password" autocomplete="current-password">
|
|
41
|
+
</label>
|
|
42
|
+
<label>
|
|
43
|
+
Discovery from
|
|
44
|
+
<input id="discoverFrom" type="datetime-local">
|
|
45
|
+
</label>
|
|
46
|
+
<label>
|
|
47
|
+
Discovery to
|
|
48
|
+
<input id="discoverTo" type="datetime-local">
|
|
49
|
+
</label>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="actions">
|
|
52
|
+
<button id="discover" type="button">Discover historical sources</button>
|
|
53
|
+
<span id="discoverStatus" class="inlineStatus" hidden>Discovering historical sources...</span>
|
|
54
|
+
</div>
|
|
55
|
+
<details class="advanced">
|
|
56
|
+
<summary>Metric names</summary>
|
|
57
|
+
<div class="grid">
|
|
58
|
+
<label>
|
|
59
|
+
Heading magnetic metric
|
|
60
|
+
<input id="metricHeadingMagnetic" value="navigation_headingMagnetic">
|
|
61
|
+
</label>
|
|
62
|
+
<label>
|
|
63
|
+
COG true metric
|
|
64
|
+
<input id="metricCourseOverGroundTrue" value="navigation_courseOverGroundTrue">
|
|
65
|
+
</label>
|
|
66
|
+
<label>
|
|
67
|
+
SOG metric
|
|
68
|
+
<input id="metricSpeedOverGround" value="navigation_speedOverGround">
|
|
69
|
+
</label>
|
|
70
|
+
<label>
|
|
71
|
+
Magnetic variation metric
|
|
72
|
+
<input id="metricMagneticVariation" value="navigation_magneticVariation">
|
|
73
|
+
</label>
|
|
74
|
+
</div>
|
|
75
|
+
</details>
|
|
76
|
+
<div id="sources" class="tableWrap"></div>
|
|
77
|
+
</section>
|
|
78
|
+
|
|
79
|
+
<section class="panel">
|
|
80
|
+
<h2>Calibration</h2>
|
|
81
|
+
<div class="grid">
|
|
82
|
+
<label>
|
|
83
|
+
Context
|
|
84
|
+
<select id="context">
|
|
85
|
+
<option value="">Discover sources first</option>
|
|
86
|
+
</select>
|
|
87
|
+
</label>
|
|
88
|
+
<label>
|
|
89
|
+
Heading source
|
|
90
|
+
<select id="headingSource"></select>
|
|
91
|
+
</label>
|
|
92
|
+
<label>
|
|
93
|
+
COG source
|
|
94
|
+
<select id="cogSource"></select>
|
|
95
|
+
</label>
|
|
96
|
+
<label>
|
|
97
|
+
SOG source
|
|
98
|
+
<select id="sogSource"></select>
|
|
99
|
+
</label>
|
|
100
|
+
<label>
|
|
101
|
+
Variation source
|
|
102
|
+
<select id="variationSource"></select>
|
|
103
|
+
</label>
|
|
104
|
+
<label>
|
|
105
|
+
From
|
|
106
|
+
<input id="from" type="datetime-local">
|
|
107
|
+
</label>
|
|
108
|
+
<label>
|
|
109
|
+
To
|
|
110
|
+
<input id="to" type="datetime-local">
|
|
111
|
+
</label>
|
|
112
|
+
</div>
|
|
113
|
+
<input id="minSog" type="hidden" value="3">
|
|
114
|
+
<input id="maxCogRate" type="hidden" value="1">
|
|
115
|
+
<input id="binSize" type="hidden" value="10">
|
|
116
|
+
<input id="minSamplesPerBin" type="hidden" value="10">
|
|
117
|
+
<div class="actions">
|
|
118
|
+
<button id="calibrate" type="button">Run calibration</button>
|
|
119
|
+
<span id="calibrateStatus" class="inlineStatus" hidden>Calibration running...</span>
|
|
120
|
+
</div>
|
|
121
|
+
</section>
|
|
122
|
+
|
|
123
|
+
<section class="panel">
|
|
124
|
+
<h2>Candidate Review</h2>
|
|
125
|
+
<div id="candidate" class="summary muted">No candidate profile yet.</div>
|
|
126
|
+
<canvas id="plot" width="760" height="340"></canvas>
|
|
127
|
+
<div id="table" class="tableWrap"></div>
|
|
128
|
+
<div class="actions">
|
|
129
|
+
<button id="saveCandidate" type="button" disabled>Save table</button>
|
|
130
|
+
<button id="cancelCandidate" type="button" disabled>Cancel</button>
|
|
131
|
+
</div>
|
|
132
|
+
</section>
|
|
133
|
+
</section>
|
|
134
|
+
|
|
135
|
+
<section id="calibrationsTab" class="tabPanel">
|
|
136
|
+
<section class="panel">
|
|
137
|
+
<h2>Saved Calibrations</h2>
|
|
138
|
+
<div id="profilesList" class="tableWrap muted">No saved calibration loaded.</div>
|
|
139
|
+
</section>
|
|
140
|
+
<section class="panel">
|
|
141
|
+
<h2>Calibration Details</h2>
|
|
142
|
+
<div id="savedProfile" class="summary muted">Select a calibration table.</div>
|
|
143
|
+
<canvas id="savedPlot" width="760" height="340"></canvas>
|
|
144
|
+
<div id="savedTable" class="tableWrap"></div>
|
|
145
|
+
<div class="actions">
|
|
146
|
+
<button id="deleteProfile" type="button" disabled>Delete table</button>
|
|
147
|
+
</div>
|
|
148
|
+
</section>
|
|
149
|
+
</section>
|
|
150
|
+
|
|
151
|
+
<section id="runtimeTab" class="tabPanel">
|
|
152
|
+
<section class="panel">
|
|
153
|
+
<h2>Runtime Selection</h2>
|
|
154
|
+
<div class="grid">
|
|
155
|
+
<label>
|
|
156
|
+
Calibration table
|
|
157
|
+
<select id="runtimeProfile"></select>
|
|
158
|
+
</label>
|
|
159
|
+
<label>
|
|
160
|
+
Signal K input source
|
|
161
|
+
<select id="runtimeSource"></select>
|
|
162
|
+
</label>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="actions">
|
|
165
|
+
<button id="activateRuntime" type="button">Activate runtime calibration</button>
|
|
166
|
+
<button id="deactivateRuntime" class="secondary" type="button">Deactivate runtime calibration</button>
|
|
167
|
+
<span id="runtimeActionStatus" class="inlineStatus" hidden>Updating runtime...</span>
|
|
168
|
+
</div>
|
|
169
|
+
</section>
|
|
170
|
+
<section class="panel">
|
|
171
|
+
<h2>Runtime Status</h2>
|
|
172
|
+
<div id="runtime" class="summary muted">Runtime not loaded.</div>
|
|
173
|
+
</section>
|
|
174
|
+
</section>
|
|
175
|
+
</main>
|
|
176
|
+
|
|
177
|
+
<script src="./app.js"></script>
|
|
178
|
+
</body>
|
|
179
|
+
</html>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
var sharedReact = null
|
|
5
|
+
|
|
6
|
+
function resolveReact () {
|
|
7
|
+
return (sharedReact && (sharedReact.default || sharedReact)) || window.React
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function CompassCalibratorPanel () {
|
|
11
|
+
var React = resolveReact()
|
|
12
|
+
if (!React) throw new Error('React is required to render Compass Calibrator')
|
|
13
|
+
return React.createElement('iframe', {
|
|
14
|
+
title: 'Compass Calibrator',
|
|
15
|
+
src: '/signalk-compass-calibrator/',
|
|
16
|
+
style: {
|
|
17
|
+
border: 0,
|
|
18
|
+
display: 'block',
|
|
19
|
+
height: 'calc(100vh - 92px)',
|
|
20
|
+
minHeight: '720px',
|
|
21
|
+
width: '100%'
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var modules = {
|
|
27
|
+
'./AppPanel': function () {
|
|
28
|
+
return {
|
|
29
|
+
__esModule: true,
|
|
30
|
+
default: CompassCalibratorPanel
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
window.signalk_compass_calibrator = {
|
|
36
|
+
get: function (module) {
|
|
37
|
+
if (!modules[module]) return Promise.reject(new Error('Unknown module ' + module))
|
|
38
|
+
return Promise.resolve(modules[module])
|
|
39
|
+
},
|
|
40
|
+
init: function (shareScope) {
|
|
41
|
+
var reactShare = shareScope && shareScope.react
|
|
42
|
+
if (reactShare && typeof reactShare.get !== 'function') {
|
|
43
|
+
var versions = Object.keys(reactShare)
|
|
44
|
+
reactShare = versions.length ? reactShare[versions[0]] : null
|
|
45
|
+
}
|
|
46
|
+
if (reactShare && typeof reactShare.get === 'function') {
|
|
47
|
+
return Promise.resolve(reactShare.get()).then(function (factory) {
|
|
48
|
+
sharedReact = typeof factory === 'function' ? factory() : factory
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
return Promise.resolve()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}())
|
|
Binary file
|