@mxtommy/kip 3.10.0-beta.9 → 3.10.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +11 -0
  3. package/images/KipGaugeSample3-1024x508.png +0 -0
  4. package/package.json +2 -1
  5. package/plugin/index.js +238 -31
  6. package/plugin/openApi.json +367 -0
  7. package/public/3rdpartylicenses.txt +52 -52
  8. package/public/assets/help-docs/kiosk.md +192 -0
  9. package/public/assets/help-docs/menu.json +1 -0
  10. package/public/assets/help-docs/welcome.md +27 -2
  11. package/public/assets/svg/icons.svg +5 -1
  12. package/public/chunk-2XB2ZNXV.js +1 -0
  13. package/public/{chunk-J3WNXGAQ.js → chunk-4N6AW5Y5.js} +1 -1
  14. package/public/chunk-5NKFZDV5.js +5 -0
  15. package/public/chunk-AREYGJLO.js +3 -0
  16. package/public/chunk-B6IRZFL5.js +3 -0
  17. package/public/chunk-CCEKSCJH.js +8 -0
  18. package/public/chunk-DSBAZLLN.js +5 -0
  19. package/public/chunk-DSWRNQDG.js +15 -0
  20. package/public/{chunk-LRX3XYXK.js → chunk-EOXCM3IV.js} +1 -1
  21. package/public/chunk-G5U7W6LL.js +1 -0
  22. package/public/{chunk-7OMETTVK.js → chunk-JHI7SSDT.js} +1 -1
  23. package/public/{chunk-GJ33QBJ6.js → chunk-KABAIECE.js} +1 -1
  24. package/public/chunk-LYPFRDZT.js +1 -0
  25. package/public/chunk-O2GGGUBC.js +2 -0
  26. package/public/chunk-QZO4362R.js +4 -0
  27. package/public/chunk-RJDZKEUA.js +1 -0
  28. package/public/{chunk-TDHAZ7DS.js → chunk-SVI34QP4.js} +1 -1
  29. package/public/chunk-TSNRNW3D.js +2 -0
  30. package/public/{chunk-WSW3WZXR.js → chunk-TTNX7JB6.js} +10 -10
  31. package/public/chunk-WUFURHSA.js +5 -0
  32. package/public/chunk-X45MUE6N.js +2 -0
  33. package/public/chunk-YPVFGYWU.js +1 -0
  34. package/public/chunk-ZGO25KK6.js +2 -0
  35. package/public/chunk-ZOYXBB55.js +2 -0
  36. package/public/index.html +1 -1
  37. package/public/{main-TITA4PAE.js → main-JN6ENHFX.js} +12 -14
  38. package/COPILOT.md +0 -362
  39. package/eslint.config.js +0 -45
  40. package/kip-plugin/src/index.ts +0 -53
  41. package/kip-plugin/tsconfig.plugin.json +0 -13
  42. package/public/chunk-2B3JF66M.js +0 -2
  43. package/public/chunk-3QS25L5K.js +0 -1
  44. package/public/chunk-BZF6OYAF.js +0 -7
  45. package/public/chunk-FW2LAMAA.js +0 -16
  46. package/public/chunk-FWG5JGYN.js +0 -1
  47. package/public/chunk-HKUJILH7.js +0 -6
  48. package/public/chunk-JFDPDIG2.js +0 -2
  49. package/public/chunk-MXKB5Z6M.js +0 -5
  50. package/public/chunk-NL52VRFS.js +0 -1
  51. package/public/chunk-PTADMSJZ.js +0 -1
  52. package/public/chunk-S7BCYLTC.js +0 -11
  53. package/public/chunk-T5GXSVMN.js +0 -1
@@ -0,0 +1,367 @@
1
+ {
2
+ "openapi": "3.0.0",
3
+ "info": {
4
+ "version": "1.0.0",
5
+ "title": "KIP Remote Displays API",
6
+ "description": "API endpoints to list KIP displays and control the active screen for a given KIP instance via Signal K self.displays tree.\n\nUsage:\n- List displays:\n curl -s http://localhost:3000/plugins/kip/displays\n- Read a display's screens:\n curl -s http://localhost:3000/plugins/kip/displays/{displayId}\n- Set a display entry:\n curl -s -X PUT -H 'Content-Type: application/json' -d '{\"displayName\":\"Mast\"}' http://localhost:3000/plugins/kip/displays/{displayId}\n- Get active screen:\n curl -s http://localhost:3000/plugins/kip/displays/{displayId}/activeScreen\n- Set active screen:\n curl -s -X PUT -H 'Content-Type: application/json' -d '{\"screenIdx\":1}' http://localhost:3000/plugins/kip/displays/{displayId}/activeScreen",
7
+ "termsOfService": "http://signalk.org/terms/",
8
+ "license": {
9
+ "name": "Apache 2.0",
10
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
11
+ }
12
+ },
13
+ "externalDocs": {
14
+ "url": "http://signalk.org/specification/",
15
+ "description": "Signal K specification."
16
+ },
17
+ "servers": [
18
+ {
19
+ "url": "/"
20
+ }
21
+ ],
22
+ "tags": [
23
+ {
24
+ "name": "Displays",
25
+ "description": "KIP display discovery and control."
26
+ }
27
+ ],
28
+ "components": {
29
+ "schemas": {
30
+ "DisplayInfo": {
31
+ "type": "object",
32
+ "properties": {
33
+ "displayId": {
34
+ "type": "string",
35
+ "description": "KIP instance UUID"
36
+ },
37
+ "displayName": {
38
+ "type": "string",
39
+ "nullable": true
40
+ }
41
+ },
42
+ "required": [
43
+ "displayId"
44
+ ]
45
+ },
46
+ "ScreenItem": {
47
+ "type": "object",
48
+ "properties": {
49
+ "id": {
50
+ "type": "string"
51
+ },
52
+ "name": {
53
+ "type": "string"
54
+ },
55
+ "icon": {
56
+ "type": "string"
57
+ }
58
+ },
59
+ "required": [
60
+ "id",
61
+ "name",
62
+ "icon"
63
+ ]
64
+ },
65
+ "SuccessResponse": {
66
+ "type": "object",
67
+ "properties": {
68
+ "state": {
69
+ "type": "string",
70
+ "enum": [
71
+ "SUCCESS"
72
+ ]
73
+ },
74
+ "statusCode": {
75
+ "type": "integer",
76
+ "enum": [
77
+ 200
78
+ ]
79
+ }
80
+ },
81
+ "required": [
82
+ "state",
83
+ "statusCode"
84
+ ]
85
+ },
86
+ "ErrorResponse": {
87
+ "type": "object",
88
+ "properties": {
89
+ "state": {
90
+ "type": "string",
91
+ "enum": [
92
+ "FAILED"
93
+ ]
94
+ },
95
+ "statusCode": {
96
+ "type": "integer"
97
+ },
98
+ "message": {
99
+ "type": "string"
100
+ }
101
+ },
102
+ "required": [
103
+ "state",
104
+ "statusCode",
105
+ "message"
106
+ ]
107
+ },
108
+ "ActiveScreenSetRequest": {
109
+ "type": "object",
110
+ "properties": {
111
+ "screenIdx": {
112
+ "type": "integer",
113
+ "nullable": true,
114
+ "description": "Index of active screen or null to clear"
115
+ }
116
+ }
117
+ },
118
+ "AnyObjectOrNull": {
119
+ "oneOf": [
120
+ {
121
+ "type": "object",
122
+ "additionalProperties": true
123
+ },
124
+ {
125
+ "type": "null"
126
+ }
127
+ ]
128
+ }
129
+ },
130
+ "parameters": {
131
+ "DisplayIdParam": {
132
+ "in": "path",
133
+ "required": true,
134
+ "name": "displayId",
135
+ "description": "KIP instance UUID",
136
+ "schema": {
137
+ "type": "string"
138
+ }
139
+ }
140
+ },
141
+ "securitySchemes": {
142
+ "bearerAuth": {
143
+ "type": "http",
144
+ "scheme": "bearer",
145
+ "bearerFormat": "JWT"
146
+ },
147
+ "cookieAuth": {
148
+ "type": "apiKey",
149
+ "in": "cookie",
150
+ "name": "JAUTHENTICATION"
151
+ }
152
+ }
153
+ },
154
+ "security": [
155
+ {
156
+ "cookieAuth": []
157
+ },
158
+ {
159
+ "bearerAuth": []
160
+ }
161
+ ],
162
+ "paths": {
163
+ "/plugins/kip/displays": {
164
+ "get": {
165
+ "tags": [
166
+ "Displays"
167
+ ],
168
+ "summary": "List available KIP displays",
169
+ "responses": {
170
+ "200": {
171
+ "description": "List of KIP instances discovered under self.displays",
172
+ "content": {
173
+ "application/json": {
174
+ "schema": {
175
+ "type": "array",
176
+ "items": {
177
+ "$ref": "#/components/schemas/DisplayInfo"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ },
183
+ "400": {
184
+ "description": "Bad request",
185
+ "content": {
186
+ "application/json": {
187
+ "schema": {
188
+ "$ref": "#/components/schemas/ErrorResponse"
189
+ }
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ },
196
+ "/plugins/kip/displays/{displayId}": {
197
+ "parameters": [
198
+ {
199
+ "$ref": "#/components/parameters/DisplayIdParam"
200
+ }
201
+ ],
202
+ "get": {
203
+ "tags": [
204
+ "Displays"
205
+ ],
206
+ "summary": "List screens for a display (self.displays.{displayId}.value.screens)",
207
+ "responses": {
208
+ "200": {
209
+ "description": "Array of screen entries",
210
+ "content": {
211
+ "application/json": {
212
+ "schema": {
213
+ "type": "array",
214
+ "items": {
215
+ "$ref": "#/components/schemas/ScreenItem"
216
+ }
217
+ }
218
+ }
219
+ }
220
+ },
221
+ "404": {
222
+ "description": "Not found",
223
+ "content": {
224
+ "application/json": {
225
+ "schema": {
226
+ "$ref": "#/components/schemas/ErrorResponse"
227
+ }
228
+ }
229
+ }
230
+ },
231
+ "400": {
232
+ "description": "Bad request",
233
+ "content": {
234
+ "application/json": {
235
+ "schema": {
236
+ "$ref": "#/components/schemas/ErrorResponse"
237
+ }
238
+ }
239
+ }
240
+ }
241
+ }
242
+ },
243
+ "put": {
244
+ "tags": [
245
+ "Displays"
246
+ ],
247
+ "summary": "Set display entry under self.displays.{displayId}",
248
+ "requestBody": {
249
+ "required": false,
250
+ "content": {
251
+ "application/json": {
252
+ "schema": {
253
+ "$ref": "#/components/schemas/AnyObjectOrNull"
254
+ }
255
+ }
256
+ }
257
+ },
258
+ "responses": {
259
+ "200": {
260
+ "description": "Updated",
261
+ "content": {
262
+ "application/json": {
263
+ "schema": {
264
+ "$ref": "#/components/schemas/SuccessResponse"
265
+ }
266
+ }
267
+ }
268
+ },
269
+ "400": {
270
+ "description": "Bad request",
271
+ "content": {
272
+ "application/json": {
273
+ "schema": {
274
+ "$ref": "#/components/schemas/ErrorResponse"
275
+ }
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+ },
282
+ "/plugins/kip/displays/{displayId}/activeScreen": {
283
+ "parameters": [
284
+ {
285
+ "$ref": "#/components/parameters/DisplayIdParam"
286
+ }
287
+ ],
288
+ "get": {
289
+ "tags": [
290
+ "Displays"
291
+ ],
292
+ "summary": "Get active screen index for display",
293
+ "responses": {
294
+ "200": {
295
+ "description": "Active screen index or null",
296
+ "content": {
297
+ "application/json": {
298
+ "schema": {
299
+ "type": "integer",
300
+ "nullable": true
301
+ }
302
+ }
303
+ }
304
+ },
305
+ "404": {
306
+ "description": "Not found",
307
+ "content": {
308
+ "application/json": {
309
+ "schema": {
310
+ "$ref": "#/components/schemas/ErrorResponse"
311
+ }
312
+ }
313
+ }
314
+ },
315
+ "400": {
316
+ "description": "Bad request",
317
+ "content": {
318
+ "application/json": {
319
+ "schema": {
320
+ "$ref": "#/components/schemas/ErrorResponse"
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+ },
327
+ "put": {
328
+ "tags": [
329
+ "Displays"
330
+ ],
331
+ "summary": "Set active screen index for display",
332
+ "requestBody": {
333
+ "required": false,
334
+ "content": {
335
+ "application/json": {
336
+ "schema": {
337
+ "$ref": "#/components/schemas/ActiveScreenSetRequest"
338
+ }
339
+ }
340
+ }
341
+ },
342
+ "responses": {
343
+ "200": {
344
+ "description": "Updated",
345
+ "content": {
346
+ "application/json": {
347
+ "schema": {
348
+ "$ref": "#/components/schemas/SuccessResponse"
349
+ }
350
+ }
351
+ }
352
+ },
353
+ "400": {
354
+ "description": "Bad request",
355
+ "content": {
356
+ "application/json": {
357
+ "schema": {
358
+ "$ref": "#/components/schemas/ErrorResponse"
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ }
365
+ }
366
+ }
367
+ }
@@ -478,58 +478,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
478
478
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
479
479
  SOFTWARE.
480
480
 
481
- --------------------------------------------------------------------------------
482
- Package: @angular/router
483
- License: "MIT"
484
-
485
- The MIT License
486
-
487
- Copyright (c) 2010-2025 Google LLC. https://angular.dev/license
488
-
489
- Permission is hereby granted, free of charge, to any person obtaining a copy
490
- of this software and associated documentation files (the "Software"), to deal
491
- in the Software without restriction, including without limitation the rights
492
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
493
- copies of the Software, and to permit persons to whom the Software is
494
- furnished to do so, subject to the following conditions:
495
-
496
- The above copyright notice and this permission notice shall be included in
497
- all copies or substantial portions of the Software.
498
-
499
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
500
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
501
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
502
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
503
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
504
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
505
- THE SOFTWARE.
506
-
507
- --------------------------------------------------------------------------------
508
- Package: compare-versions
509
- License: "MIT"
510
-
511
- The MIT License (MIT)
512
-
513
- Copyright (c) 2015-2021 Ole Michelsen
514
-
515
- Permission is hereby granted, free of charge, to any person obtaining a copy
516
- of this software and associated documentation files (the "Software"), to deal
517
- in the Software without restriction, including without limitation the rights
518
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
519
- copies of the Software, and to permit persons to whom the Software is
520
- furnished to do so, subject to the following conditions:
521
-
522
- The above copyright notice and this permission notice shall be included in all
523
- copies or substantial portions of the Software.
524
-
525
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
526
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
527
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
528
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
529
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
530
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
531
- SOFTWARE.
532
-
533
481
  --------------------------------------------------------------------------------
534
482
  Package: rxjs
535
483
  License: "Apache-2.0"
@@ -789,6 +737,32 @@ maintained libraries used by this software which have their own
789
737
  licenses; we recommend you read them, as their terms may differ from the
790
738
  terms above.
791
739
 
740
+ --------------------------------------------------------------------------------
741
+ Package: compare-versions
742
+ License: "MIT"
743
+
744
+ The MIT License (MIT)
745
+
746
+ Copyright (c) 2015-2021 Ole Michelsen
747
+
748
+ Permission is hereby granted, free of charge, to any person obtaining a copy
749
+ of this software and associated documentation files (the "Software"), to deal
750
+ in the Software without restriction, including without limitation the rights
751
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
752
+ copies of the Software, and to permit persons to whom the Software is
753
+ furnished to do so, subject to the following conditions:
754
+
755
+ The above copyright notice and this permission notice shall be included in all
756
+ copies or substantial portions of the Software.
757
+
758
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
759
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
760
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
761
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
762
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
763
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
764
+ SOFTWARE.
765
+
792
766
  --------------------------------------------------------------------------------
793
767
  Package: @angular/forms
794
768
  License: "MIT"
@@ -883,6 +857,32 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
883
857
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
884
858
  THE SOFTWARE.
885
859
 
860
+ --------------------------------------------------------------------------------
861
+ Package: @angular/router
862
+ License: "MIT"
863
+
864
+ The MIT License
865
+
866
+ Copyright (c) 2010-2025 Google LLC. https://angular.dev/license
867
+
868
+ Permission is hereby granted, free of charge, to any person obtaining a copy
869
+ of this software and associated documentation files (the "Software"), to deal
870
+ in the Software without restriction, including without limitation the rights
871
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
872
+ copies of the Software, and to permit persons to whom the Software is
873
+ furnished to do so, subject to the following conditions:
874
+
875
+ The above copyright notice and this permission notice shall be included in
876
+ all copies or substantial portions of the Software.
877
+
878
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
879
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
880
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
881
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
882
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
883
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
884
+ THE SOFTWARE.
885
+
886
886
  --------------------------------------------------------------------------------
887
887
  Package: core-js
888
888
  License: "MIT"
@@ -0,0 +1,192 @@
1
+ # Raspberry Pi Kiosk Mode (Chromium)
2
+
3
+ This guide launches Chromium in kiosk mode to display KIP at:
4
+ http://<sk_server_IP>:3000/@mxtommy/kip/#/page/0
5
+
6
+ It supports Raspberry Pi OS Bullseye (X11/LXDE) and Bookworm (Wayland).
7
+
8
+ ## What is “kiosk mode”?
9
+ Kiosk mode runs a single application full-screen and suppresses most desktop UI. In this guide, Chromium loads KIP and stays on screen like a dedicated instrument display.
10
+
11
+ - What it does:
12
+ - Launches Chromium full-screen without toolbars (“chrome”).
13
+ - Autostarts after login; optional auto-restart via systemd.
14
+ - Disables screen blanking; can hide the mouse cursor.
15
+ - What it does not do:
16
+ - It is not a full OS lockdown or content filter.
17
+ - Exit/maintenance:
18
+ - Desktop autostart: press Alt+F4 to close, or switch to a TTY (Ctrl+Alt+F2) and run: pkill chromium-browser || pkill chromium.
19
+ - systemd user service: systemctl --user stop kiosk.service (disable with systemctl --user disable kiosk.service).
20
+
21
+
22
+ ## 1) Prerequisites
23
+
24
+ - Raspberry Pi OS with Desktop, user: `pi` (or adjust paths).
25
+ - Chromium installed:
26
+ ```
27
+ sudo apt update
28
+ sudo apt install -y chromium-browser || sudo apt install -y chromium
29
+ ```
30
+ - Optional (hide mouse cursor):
31
+ ```
32
+ sudo apt install -y unclutter
33
+ ```
34
+ - Enable Desktop autologin:
35
+ ```
36
+ sudo raspi-config
37
+ ```
38
+ System Options → Boot / Auto Login → Desktop Autologin
39
+
40
+ - Disable screen blanking
41
+ - Wayland (Bookworm): raspi-config → Display Options → Screen Blanking → No
42
+ - X11 (Bullseye): we also disable via `xset` in the script below.
43
+
44
+ ## 2) Create the kiosk launcher script
45
+
46
+ ```
47
+ sudo nano /home/pi/kiosk.sh
48
+ ```
49
+
50
+ Paste:
51
+
52
+ ```
53
+ #!/usr/bin/env bash
54
+ set -euo pipefail
55
+
56
+ # URL for KIP (adjust as needed)
57
+ URL="${URL:-http://<sk_server_IP>:3000/@mxtommy/kip/#/page/0}"
58
+
59
+ # Pick Chromium binary
60
+ BROWSER="$(command -v chromium-browser || true)"
61
+ if [[ -z "${BROWSER}" ]]; then
62
+ BROWSER="$(command -v chromium || true)"
63
+ fi
64
+ if [[ -z "${BROWSER}" ]]; then
65
+ echo "Chromium not installed. Try: sudo apt update && sudo apt install -y chromium-browser || sudo apt install -y chromium"
66
+ exit 1
67
+ fi
68
+
69
+ # Hide mouse cursor if unclutter is available
70
+ if command -v unclutter >/dev/null 2>&1; then
71
+ unclutter -idle 0 -root &
72
+ fi
73
+
74
+ # Disable screen blanking on X11 (LXDE). On Wayland, use raspi-config instead.
75
+ if [[ "${XDG_SESSION_TYPE:-}" == "x11" ]]; then
76
+ xset s off -dpms
77
+ xset s noblank
78
+ fi
79
+
80
+ # Optional: wait for network/host (best-effort, up to ~2 minutes)
81
+ host="$(echo "$URL" | sed -E 's#^[a-z]+://([^:/]+).*$#\1#')"
82
+ if command -v ping >/dev/null 2>&1; then
83
+ for i in {1..60}; do
84
+ ping -c1 -W1 "$host" >/dev/null 2>&1 && break || sleep 2
85
+ done
86
+ fi
87
+
88
+ exec "$BROWSER" \
89
+ --kiosk \
90
+ --start-fullscreen \
91
+ --no-first-run \
92
+ --noerrdialogs \
93
+ --disable-session-crashed-bubble \
94
+ --disable-translate \
95
+ --disable-features=TranslateUI \
96
+ --enable-features=OverlayScrollbar \
97
+ --autoplay-policy=no-user-gesture-required \
98
+ --check-for-update-interval=31536000 \
99
+ --app="$URL"
100
+ ```
101
+
102
+ Save, then:
103
+
104
+ ```
105
+ sudo chmod +x /home/pi/kiosk.sh
106
+ ```
107
+
108
+ Tip: You can override the URL without editing the script using:
109
+ ```
110
+ URL="http://signalk.local:3000/@mxtommy/kip/#/page/0" /home/pi/kiosk.sh
111
+ ```
112
+
113
+ ## 3A) Autostart via Desktop (.desktop) – simplest
114
+
115
+ Create an autostart entry:
116
+
117
+ ```
118
+ mkdir -p ~/.config/autostart
119
+ nano ~/.config/autostart/kiosk.desktop
120
+ ```
121
+
122
+ Paste:
123
+
124
+ ```
125
+ [Desktop Entry]
126
+ Type=Application
127
+ Name=KIP Kiosk
128
+ Exec=/home/pi/kiosk.sh
129
+ Terminal=false
130
+ X-GNOME-Autostart-enabled=true
131
+ ```
132
+
133
+ This launches after the desktop session starts.
134
+
135
+ ## 3B) Autostart via systemd (user) – robust, auto‑restart
136
+
137
+ Recommended if you want Chromium to restart on crash.
138
+
139
+ ```
140
+ mkdir -p ~/.config/systemd/user
141
+ nano ~/.config/systemd/user/kiosk.service
142
+ ```
143
+
144
+ Paste:
145
+
146
+ ```
147
+ [Unit]
148
+ Description=KIP Chromium Kiosk
149
+ After=graphical-session.target network-online.target
150
+ Wants=network-online.target
151
+
152
+ [Service]
153
+ Type=simple
154
+ Environment=URL=http://<sk_server_IP>:3000/@mxtommy/kip/#/page/0
155
+ ExecStart=/home/pi/kiosk.sh
156
+ Restart=on-failure
157
+ RestartSec=5
158
+
159
+ [Install]
160
+ WantedBy=graphical-session.target
161
+ ```
162
+
163
+ Enable:
164
+
165
+ ```
166
+ systemctl --user daemon-reload
167
+ systemctl --user enable --now kiosk.service
168
+ ```
169
+
170
+ Logs (for debugging):
171
+ ```
172
+ journalctl --user -u kiosk.service -f
173
+ ```
174
+
175
+ Note: This runs after user login to the desktop. Ensure Desktop Autologin is enabled (Step 1).
176
+
177
+ ## 4) Reboot and verify
178
+
179
+ ```
180
+ sudo reboot
181
+ ```
182
+
183
+ Chromium should open full-screen at:
184
+ http://<sk_server_IP>:3000/@mxtommy/kip/#/page/0
185
+
186
+ ## Troubleshooting
187
+
188
+ - Blank screen on Bookworm: confirm Screen Blanking is disabled in raspi-config (Wayland ignores xset).
189
+ - Chromium not found: install package `chromium-browser` or `chromium` (varies by OS version).
190
+ - Wrong URL: KIP is served under /@mxtommy/kip/. Ensure the full path is used.
191
+ - Certificates: prefer HTTP or trusted TLS. Avoid `--ignore-certificate-errors` in kiosk.
192
+ - systemd service not starting: check `journalctl --user -u kiosk.service -f
@@ -9,5 +9,6 @@
9
9
  { "title": "Datasets and Data Chart Widget", "file": "datasets.md" },
10
10
  { "title": "Gafana Integration", "file": "grafana.md" },
11
11
  { "title": "InfluxDB and Signal K", "file": "influxdb.md" },
12
+ { "title": "Kiosk Mode", "file": "kiosk.md" },
12
13
  { "title": "Contact Us", "file": "contact-us.md" }
13
14
  ]