signalk-czone 0.3.0-beta.11 → 0.3.0-beta.13
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 +12 -0
- package/README.md +36 -5
- package/package.json +2 -2
- package/public/fullscreen.js +36 -0
- package/public/icon-180.png +0 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/index.html +34 -7
- package/public/manifest.webmanifest +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0-beta.13
|
|
4
|
+
|
|
5
|
+
- Adds a fullscreen icon beside the CZone / Boat Systems branding, with expand/collapse states and accessible labels.
|
|
6
|
+
- Adds standalone tablet home-screen launch assets and safe-area spacing.
|
|
7
|
+
- Documents signalk-ssl setup, trusted CA certificate installation and device reboot steps for HTTPS app launch.
|
|
8
|
+
|
|
9
|
+
## 0.3.0-beta.12
|
|
10
|
+
|
|
11
|
+
- Keeps the connection indicator disconnected when circuit-list REST refreshes succeed but the live WebSocket is down; shows connecting/reconnecting status and the snapshot time.
|
|
12
|
+
|
|
3
13
|
## 0.3.0-beta.11
|
|
4
14
|
|
|
15
|
+
- Uses the npm `latest` tag for default installation and App Store updates while retaining the BETA version and listing labels.
|
|
16
|
+
|
|
5
17
|
- Routes circuit current to known physical output owners instead of groups referencing those outputs, restoring Starlink current and correcting Port Fresh Water Pump and Meitaki Nav. AIS attribution.
|
|
6
18
|
- Preserves existing current mappings when output ownership is ambiguous and adds regression coverage across all six ZCF fixtures.
|
|
7
19
|
|
package/README.md
CHANGED
|
@@ -208,15 +208,15 @@ Once this beta is published and available in your App Store:
|
|
|
208
208
|
3. Open **Server → Plugin Config → CZone** and use **Upload and install ZCF** to upload your vessel's `.zcf` configuration.
|
|
209
209
|
4. Enable the plugin after configuration, then check the **Diagnostics** tab and published currents before testing controls.
|
|
210
210
|
|
|
211
|
-
The plugin is disabled by default until explicitly enabled.
|
|
211
|
+
The plugin is disabled by default until explicitly enabled. Tested releases use the npm `latest` tag for default installation and Signal K App Store discovery; the version and listing retain their BETA labels.
|
|
212
212
|
|
|
213
|
-
### Explicit npm
|
|
213
|
+
### Explicit npm installation
|
|
214
214
|
|
|
215
215
|
After npm publication, run this as the Signal K service user from the server's configuration directory (normally `~/.signalk`, or the directory configured by `SIGNALK_NODE_CONFIG_DIR`):
|
|
216
216
|
|
|
217
217
|
```bash
|
|
218
218
|
cd ~/.signalk
|
|
219
|
-
npm install signalk-czone@
|
|
219
|
+
npm install signalk-czone@latest --omit=dev --ignore-scripts
|
|
220
220
|
```
|
|
221
221
|
|
|
222
222
|
Restart Signal K and follow the configuration steps above. For Docker or appliance installations, use the corresponding container/configuration directory and restart method.
|
|
@@ -225,9 +225,9 @@ For installation from a maintainer-provided npm tarball, run `npm install /path/
|
|
|
225
225
|
|
|
226
226
|
### Publishing (maintainers)
|
|
227
227
|
|
|
228
|
-
Publish `signalk-czone-zcf@0.1.0-beta.1` first. Then run `npm install`, `npm test`, and `npm pack --dry-run` in this repository, verify the runtime files and App Store assets, and run `npm publish --tag
|
|
228
|
+
Publish `signalk-czone-zcf@0.1.0-beta.1` first. Then run `npm install`, `npm test`, and `npm pack --dry-run` in this repository, verify the runtime files and App Store assets, and run `npm publish --tag latest` after npm authentication.
|
|
229
229
|
|
|
230
|
-
The package defaults to
|
|
230
|
+
The package defaults to `latest`, including versions named `-beta.N`. The GitHub publishing workflow runs when `package.json` or the workflow changes on `main`: it tests and packs the release, publishes it if the version is new, and sets and verifies the `latest` tag. If the version already exists, the workflow promotes that existing version without republishing its contents.
|
|
231
231
|
|
|
232
232
|
### Beta feedback
|
|
233
233
|
|
|
@@ -423,3 +423,34 @@ Only the installed path is stored in plugin configuration; the binary ZCF is not
|
|
|
423
423
|
- **0.3.0-beta.5** — added explicit AC/DC source classification for downstream telemetry storage while retaining stable circuit-name paths and the diagnostics/status tooling.
|
|
424
424
|
|
|
425
425
|
The beta is intended for extended real-world testing before a stable `0.3.0` release.
|
|
426
|
+
|
|
427
|
+
## Fullscreen and tablet home-screen launch
|
|
428
|
+
|
|
429
|
+
Open `/signalk-czone/` directly in your browser. The **fullscreen icon** beside
|
|
430
|
+
the CZone / Boat Systems branding enters fullscreen; tap the icon again or use the browser's exit gesture
|
|
431
|
+
(or Escape on desktop) to leave. It appears only when the browser exposes the
|
|
432
|
+
fullscreen API. Embedded views may need permission from their parent page.
|
|
433
|
+
|
|
434
|
+
For a home-screen launch, open the app over **trusted HTTPS**, then use your
|
|
435
|
+
browser's **Install app** / **Add to Home Screen** option (Safari: Share → Add to
|
|
436
|
+
Home Screen). Compatible browsers launch CZone in standalone mode without the
|
|
437
|
+
usual address bar. Installation and fullscreen support vary by device/browser.
|
|
438
|
+
The manifest uses relative URLs, so it follows your server's hostname and port;
|
|
439
|
+
no boat IP address is hard-coded. Plain HTTP on a LAN IP may only offer a shortcut.
|
|
440
|
+
|
|
441
|
+
### Set up HTTPS for a full-screen app
|
|
442
|
+
|
|
443
|
+
To launch CZone from the tablet or device's home screen without the URL bar and
|
|
444
|
+
browser controls, first set up trusted HTTPS on your Signal K server:
|
|
445
|
+
|
|
446
|
+
1. Install and configure the **signalk-ssl** plugin.
|
|
447
|
+
2. In Signal K **Server Settings**, turn on the **Use SSL** toggle and apply the settings. Restart Signal K if prompted.
|
|
448
|
+
3. On each tablet or device, download the server's CA certificate (`ca.crt`). For example: [https://einstein.local:3443/signalk-ssl/ca.crt](https://einstein.local:3443/signalk-ssl/ca.crt). Replace `einstein.local` and port `3443` with your server's hostname and HTTPS port.
|
|
449
|
+
4. Import/install `ca.crt` as a trusted CA certificate in the device's certificate settings. Enable trust for the certificate if the device requires a separate step.
|
|
450
|
+
5. After the certificate installs successfully, you will most likely need to **reboot the tablet or device** before the browser recognises it.
|
|
451
|
+
6. Open CZone over HTTPS, for example [https://einstein.local:3443/signalk-czone/](https://einstein.local:3443/signalk-czone/), and check that the browser trusts the connection. Use **Install app** / **Add to Home Screen**, then launch CZone from its new home-screen icon.
|
|
452
|
+
|
|
453
|
+
Certificate installation and app installation menus vary by device and browser.
|
|
454
|
+
|
|
455
|
+
The app still needs a live Signal K connection. No offline caching or service
|
|
456
|
+
worker is installed, and installing it does not grant circuit-write permission.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signalk-czone",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.13",
|
|
4
4
|
"description": "BETA: Signal K CZone monitoring and control using dynamically parsed ZCF configuration and NMEA 2000",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -57,6 +57,6 @@
|
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public",
|
|
60
|
-
"tag": "
|
|
60
|
+
"tag": "latest"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* Fullscreen is optional: the ordinary page and home-screen launch work without it. */
|
|
2
|
+
(() => {
|
|
3
|
+
const button = document.getElementById('fullscreenToggle');
|
|
4
|
+
const root = document.documentElement;
|
|
5
|
+
const request = root.requestFullscreen || root.webkitRequestFullscreen;
|
|
6
|
+
const exit = document.exitFullscreen || document.webkitExitFullscreen;
|
|
7
|
+
const enabled = document.fullscreenEnabled ?? document.webkitFullscreenEnabled;
|
|
8
|
+
if (!button || !request || !exit || enabled === false) return;
|
|
9
|
+
|
|
10
|
+
const current = () => document.fullscreenElement || document.webkitFullscreenElement;
|
|
11
|
+
const update = () => {
|
|
12
|
+
const active = !!current();
|
|
13
|
+
const label = active ? 'Exit fullscreen' : 'Show CZone fullscreen';
|
|
14
|
+
button.setAttribute('aria-label', label);
|
|
15
|
+
button.setAttribute('aria-pressed', String(active));
|
|
16
|
+
button.title = label;
|
|
17
|
+
};
|
|
18
|
+
button.hidden = false;
|
|
19
|
+
update();
|
|
20
|
+
document.addEventListener('fullscreenchange', update);
|
|
21
|
+
document.addEventListener('webkitfullscreenchange', update);
|
|
22
|
+
button.addEventListener('click', async () => {
|
|
23
|
+
button.disabled = true;
|
|
24
|
+
try {
|
|
25
|
+
// Invoke directly in the tap handler; browsers require user activation.
|
|
26
|
+
if (current()) await exit.call(document);
|
|
27
|
+
else await request.call(root);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.warn('[CZone UI] Fullscreen unavailable', error);
|
|
30
|
+
alert('Fullscreen is unavailable in this browser or embedded view. Try opening CZone directly in a browser, or adding it to your home screen.');
|
|
31
|
+
} finally {
|
|
32
|
+
button.disabled = false;
|
|
33
|
+
update();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
})();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/public/index.html
CHANGED
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
6
6
|
<meta name="theme-color" content="#071321">
|
|
7
7
|
<link rel="icon" type="image/png" href="icon.png">
|
|
8
|
-
<link rel="apple-touch-icon" href="icon.png">
|
|
8
|
+
<link rel="apple-touch-icon" sizes="180x180" href="icon-180.png">
|
|
9
|
+
<link rel="manifest" href="manifest.webmanifest">
|
|
10
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
11
|
+
<meta name="apple-mobile-web-app-title" content="CZone">
|
|
9
12
|
<title>CZone Circuits</title>
|
|
10
13
|
<style>
|
|
11
14
|
:root {
|
|
@@ -39,7 +42,16 @@
|
|
|
39
42
|
.sidebar, .rightbar { background: rgba(5, 16, 29, .78); backdrop-filter: blur(18px); border-color: var(--line); }
|
|
40
43
|
.sidebar { border-right: 1px solid var(--line); padding: 22px 16px; position: sticky; top: 0; height: 100vh; overflow-y: auto; }
|
|
41
44
|
.rightbar { border-left: 1px solid var(--line); padding: 22px 16px; position: sticky; top: 0; height: 100vh; overflow-y: auto; }
|
|
42
|
-
.brand { display:flex; align-items:center; gap:11px; padding: 2px 10px 25px; }
|
|
45
|
+
.brand { display:flex; flex-wrap:nowrap; align-items:center; gap:11px; padding: 2px 10px 25px; }
|
|
46
|
+
.fullscreen-toggle { margin-left:auto; flex:0 0 44px; width:44px; height:44px; display:grid; place-items:center; padding:10px; border:1px solid rgba(56,169,255,.25); border-radius:12px; background:linear-gradient(145deg,rgba(24,213,232,.12),rgba(56,169,255,.05)); color:var(--cyan); cursor:pointer; transition:background .15s, border-color .15s; }
|
|
47
|
+
.fullscreen-toggle:hover { background:rgba(24,213,232,.18); border-color:var(--cyan); }
|
|
48
|
+
.fullscreen-toggle:disabled { opacity:.55; cursor:wait; }
|
|
49
|
+
.fullscreen-toggle svg { width:22px; height:22px; }
|
|
50
|
+
.fullscreen-toggle .fullscreen-collapse, .fullscreen-toggle[aria-pressed="true"] .fullscreen-expand { display:none; }
|
|
51
|
+
.fullscreen-toggle[aria-pressed="true"] .fullscreen-collapse { display:inline; }
|
|
52
|
+
.fullscreen-toggle[hidden] { display:none; }
|
|
53
|
+
.fullscreen-toggle:focus-visible { outline:2px solid var(--cyan); outline-offset:2px; }
|
|
54
|
+
body { padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
|
|
43
55
|
.brand-mark { width:38px; height:38px; display:block; object-fit:contain; border-radius:10px; box-shadow: 0 8px 25px rgba(31,154,255,.24); }
|
|
44
56
|
.brand strong { display:block; font-size:17px; letter-spacing:.2px; }
|
|
45
57
|
.brand span { color:var(--muted); font-size:12px; }
|
|
@@ -225,7 +237,12 @@
|
|
|
225
237
|
<div class="app">
|
|
226
238
|
<div class="leftwell">
|
|
227
239
|
<aside class="sidebar">
|
|
228
|
-
<div class="brand"><img class="brand-mark" src="icon.png" alt="CZone" width="38" height="38"><div><strong>CZone</strong><span>Boat Systems</span></div
|
|
240
|
+
<div class="brand"><img class="brand-mark" src="icon.png" alt="CZone" width="38" height="38"><div><strong>CZone</strong><span>Boat Systems</span></div><button id="fullscreenToggle" class="fullscreen-toggle" type="button" aria-label="Show CZone fullscreen" title="Show CZone fullscreen" aria-pressed="false" hidden>
|
|
241
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
|
|
242
|
+
<path class="fullscreen-expand" d="M8 3H3v5m13-5h5v5M3 16v5h5m13-5v5h-5"/>
|
|
243
|
+
<path class="fullscreen-collapse" d="M3 8h5V3m8 0v5h5M8 21v-5H3m18 0h-5v5"/>
|
|
244
|
+
</svg>
|
|
245
|
+
</button></div>
|
|
229
246
|
<div class="nav" id="mainNav"></div>
|
|
230
247
|
<div class="separator"></div>
|
|
231
248
|
<div class="section-label">Categories</div>
|
|
@@ -260,6 +277,7 @@
|
|
|
260
277
|
</main>
|
|
261
278
|
|
|
262
279
|
</div>
|
|
280
|
+
<script src="fullscreen.js"></script>
|
|
263
281
|
<script>
|
|
264
282
|
(() => {
|
|
265
283
|
const API = '/plugins/signalk-czone';
|
|
@@ -293,7 +311,7 @@
|
|
|
293
311
|
];
|
|
294
312
|
const topLevelCategories = new Set(['AC', 'DC', 'Favorites']);
|
|
295
313
|
let circuits = [], status = {}, modes = [], activeMode = null, vesselName = '', view = 'all', category = null, query = '', sort = 'name', socket = null;
|
|
296
|
-
let socketReconnectTimer = null, watchdogTimer = null, lastSocketUpdateAt = 0, socketConnected = false;
|
|
314
|
+
let socketReconnectTimer = null, watchdogTimer = null, lastSocketUpdateAt = 0, socketConnected = false, socketEverOpen = false;
|
|
297
315
|
const WS_WATCHDOG_MS = 120000;
|
|
298
316
|
const COMMAND_CONFIRM_MS = 15000;
|
|
299
317
|
const COMMAND_RECONCILE_DELAY_MS = 200;
|
|
@@ -565,8 +583,16 @@
|
|
|
565
583
|
console.debug('[CZone UI] REST refresh', reason, { circuits: incoming.length, modes: Array.isArray(data.modes) ? data.modes.length : 0, sendingEnabled: data.sendingEnabled === true, nmeaReady: data.nmeaReady === true });
|
|
566
584
|
mergeRest(data);
|
|
567
585
|
if (incoming.length === 0) throw new Error('CZone plugin returned an empty circuit list');
|
|
568
|
-
|
|
569
|
-
|
|
586
|
+
// "Connected" only while the live feed is up. This read is a one-off
|
|
587
|
+
// (first load, or the watchdog's reconciliation): with the feed down
|
|
588
|
+
// the page would otherwise say Connected while nothing on it moves.
|
|
589
|
+
const conn = document.querySelector('#connection');
|
|
590
|
+
conn.classList.toggle('ok', socketConnected);
|
|
591
|
+
conn.innerHTML = socketConnected
|
|
592
|
+
? '<i></i><span>Connected · live circuit data</span>'
|
|
593
|
+
: socketEverOpen
|
|
594
|
+
? `<i></i><span>Live updates lost · reconnecting… (circuits as of ${new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })})</span>`
|
|
595
|
+
: '<i></i><span>Circuits loaded · connecting live updates…</span>';
|
|
570
596
|
render();
|
|
571
597
|
return true;
|
|
572
598
|
} catch (e) {
|
|
@@ -1018,6 +1044,7 @@
|
|
|
1018
1044
|
socket = new WebSocket(SK);
|
|
1019
1045
|
socket.onopen = () => {
|
|
1020
1046
|
socketConnected = true;
|
|
1047
|
+
socketEverOpen = true;
|
|
1021
1048
|
lastSocketUpdateAt = Date.now();
|
|
1022
1049
|
updateSocketIndicator('Connected · WebSocket live', true);
|
|
1023
1050
|
sendSubscriptions();
|
|
@@ -1046,7 +1073,7 @@
|
|
|
1046
1073
|
};
|
|
1047
1074
|
socket.onclose = () => {
|
|
1048
1075
|
socketConnected = false;
|
|
1049
|
-
updateSocketIndicator('
|
|
1076
|
+
updateSocketIndicator(socketEverOpen ? 'Live updates lost · reconnecting…' : 'Connecting live updates…', false);
|
|
1050
1077
|
console.warn('[CZone WS] closed; reconnecting');
|
|
1051
1078
|
clearTimeout(socketReconnectTimer);
|
|
1052
1079
|
socketReconnectTimer = setTimeout(connectSocket, 3000);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "./",
|
|
3
|
+
"name": "CZone Boat Systems",
|
|
4
|
+
"short_name": "CZone",
|
|
5
|
+
"description": "Monitor and control your boat\u2019s CZone electrical systems through Signal K.",
|
|
6
|
+
"start_url": "./",
|
|
7
|
+
"scope": "./",
|
|
8
|
+
"display": "standalone",
|
|
9
|
+
"background_color": "#06101d",
|
|
10
|
+
"theme_color": "#071321",
|
|
11
|
+
"icons": [
|
|
12
|
+
{
|
|
13
|
+
"src": "icon-192.png",
|
|
14
|
+
"sizes": "192x192",
|
|
15
|
+
"type": "image/png",
|
|
16
|
+
"purpose": "any"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"src": "icon-512.png",
|
|
20
|
+
"sizes": "512x512",
|
|
21
|
+
"type": "image/png",
|
|
22
|
+
"purpose": "any"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|