@rhizomatics/signalk-einklabel-plugin 1.3.0-beta1 → 1.3.0-beta11
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 +29 -1
- package/README.md +42 -3
- package/dist/cli/index.d.ts +4 -1
- package/dist/cli/index.js +25 -1
- package/dist/config.d.ts +46 -14
- package/dist/config.js +170 -53
- package/dist/devices/bleBackend.d.ts +30 -2
- package/dist/devices/bleBackend.js +179 -7
- package/dist/devices/bleDiscovery.d.ts +9 -2
- package/dist/devices/bleDiscovery.js +12 -3
- package/dist/devices/discoveryCoordinator.d.ts +18 -0
- package/dist/devices/discoveryCoordinator.js +89 -22
- package/dist/devices/gicisky/compression.d.ts +22 -9
- package/dist/devices/gicisky/compression.js +128 -13
- package/dist/devices/gicisky/encode.d.ts +1 -1
- package/dist/devices/gicisky/encode.js +2 -2
- package/dist/devices/gicisky/index.js +19 -8
- package/dist/devices/gicisky/layout.d.ts +13 -1
- package/dist/devices/gicisky/layout.js +21 -0
- package/dist/devices/types.d.ts +22 -0
- package/dist/devices/types.js +2 -0
- package/dist/devices/zhsunyco/compression.d.ts +1 -0
- package/dist/devices/zhsunyco/compression.js +30 -0
- package/dist/devices/zhsunyco/index.js +10 -4
- package/dist/devices/zhsunyco/protocol.d.ts +2 -0
- package/dist/devices/zhsunyco/protocol.js +2 -0
- package/dist/plugin.js +11 -2
- package/dist/render/mirror.d.ts +11 -0
- package/dist/render/mirror.js +24 -0
- package/dist/repaintScheduler.js +27 -12
- package/package.json +15 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
# 1.3.0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## BLE Manager
|
|
4
|
+
|
|
5
|
+
First implementation of using new SignalK BLE Manager rather than directly using the `bluez` services.
|
|
6
|
+
|
|
7
|
+
- Off by default until longer term stability demonstrated.
|
|
8
|
+
- It may be less reliable for some devices that can be reached with direct bluez access - try it and fall back to the direct mode if so.
|
|
9
|
+
- BLE Manager use reduces interference between plugins competing for same BLE devices
|
|
10
|
+
- Recommend using SignalK at least release v2.33.0.
|
|
11
|
+
|
|
12
|
+
## Compression
|
|
13
|
+
|
|
14
|
+
Images are now compressed before sending - no change to what's displayed, but send time is massively reduced for labels with lots of empty space, so less battery is used and sends are less likely to fail.
|
|
15
|
+
|
|
16
|
+
- On by default for Zhsunyco labels and Gicisky 7.5"/10.2" labels; can be turned off per label, or with `--no-compress` on the CLI
|
|
17
|
+
- Experimental opt-in _Wire format_ `chunked` sends a Gicisky 4.2" BWR compressed too (`--compression-format chunked` on the CLI)
|
|
18
|
+
|
|
19
|
+
## Advanced Options
|
|
20
|
+
|
|
21
|
+
Connect timeout and retries can now be defined per label.
|
|
22
|
+
|
|
23
|
+
Some labels may need images flipped, so a per-label _Mirror_ option can flip the image horizontally, vertically, or both (rotate 180°, for a label mounted upside down). Also available as `--mirror` on the CLI `paint` and `render` commands.
|
|
24
|
+
|
|
25
|
+
Different 'chunking' options to help with new label models.
|
|
26
|
+
|
|
27
|
+
All the advanced options now grouped together to make the config clearer. Note that if you roll back to a previous version you may have to re-enter these values (they are automatically moved to the new section when upgrading).
|
|
28
|
+
|
|
29
|
+
## Dependencies
|
|
30
|
+
|
|
31
|
+
- `xmldom` updated to fix security issue with markup injection
|
|
4
32
|
|
|
5
33
|
# 1.2.3
|
|
6
34
|
|
package/README.md
CHANGED
|
@@ -134,10 +134,16 @@ Enable the plugin, and use the large **+** sign to add a label, which opens up t
|
|
|
134
134
|
- If it's a SignalK path, enter it next, for example `environment.tide.state`
|
|
135
135
|
- If it's time based, enter how many hours between repaints, for example 00:00/08:00/16:00 for an 8h schedule, and if you want a specific number of minutes after the hour.
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
- _If the render doesn't match the panel size_ - see [Reframing](#reframing)
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
The rest are grouped under _Advanced settings_, and can usually be ignored.
|
|
140
|
+
|
|
141
|
+
- _Compress upload_, _Mirror_ and _Wire format_ - see [Other Image Options](#other-image-options)
|
|
140
142
|
- _Force Repaint_ - Next time the label is due to be painted, update even if the data or template hasn't changed (this flag will automatically be cleared after this.)
|
|
143
|
+
- _BLE AES key_ - Only needed if the default key doesn't work and you have a better alternative, otherwise ignore
|
|
144
|
+
- _Paint connect timeout_ and _Paint retries_ for this device - leave blank to use the plugin-wide settings, or set them for a label that's slower to respond or further away than the others
|
|
145
|
+
|
|
146
|
+
Configs saved by earlier versions are moved into this layout automatically when the plugin starts.
|
|
141
147
|
|
|
142
148
|
When the plugin starts, it will automatically re-paint the label if it's new, or the last timed slot was missed and the data has changed.
|
|
143
149
|
|
|
@@ -178,6 +184,14 @@ Templates are simply SVG files, to which expressions can be added to use SignalK
|
|
|
178
184
|
|
|
179
185
|
There's some wiggle room with the `reframe` options to use a template that's a bit too small, or too large, for the label, although best results come from a template that's precisely matching the pixel height and width of the label. Next best is template that has the same aspect ratio, so it can be cleanly scaled. `crop` is the 2nd least worst, though if its only a handful of pixels its often not worth worring about a separate template and `crop` is just fine. `scale` is likely to look worst, since it will force an image in regardless of aspect ratio.
|
|
180
186
|
|
|
187
|
+
### Other Image Options
|
|
188
|
+
|
|
189
|
+
Each label has a few more settings for how the image is sent, under _Advanced settings_. The CLI `paint` command has matching options (see [Command Line Interface](#command-line-interface)), so you can try them on a label before changing the plugin config.
|
|
190
|
+
|
|
191
|
+
- _Compress upload_ - on by default. Sends much less data over Bluetooth, so painting is quicker, uses less of the label's battery and is less likely to time out. Works for Zhsunyco labels and Gicisky 7.5"/10.2" labels, and is ignored for others. Turn it off if a label stops updating.
|
|
192
|
+
- _Wire format (Gicisky, experimental)_ - `auto` by default. `chunked` sends a Gicisky 4.2" BWR label compressed, the same way as the 7.5"/10.2". The vendor's own app has been seen doing this, but it hasn't been tested on current firmware. Set it back to `auto` if the label stops updating.
|
|
193
|
+
- _Mirror_ - `none` by default. `horizontal` or `vertical` fixes a label model whose image comes out mirrored. `both` rotates the image 180°, for a label that has to be mounted upside down.
|
|
194
|
+
|
|
181
195
|
### Template Families (multiple panel sizes/colours)
|
|
182
196
|
|
|
183
197
|
A "Template" selection can either be one specific `.svg` file, or a _directory_ holding several versions of the same template for different panel sizes/colour-sets, e.g. `templates/tides/416x240-BWRY.svg` and `templates/tides/250x128-BWRY.svg` both implement the tide clock, just at different sizes.
|
|
@@ -309,6 +323,12 @@ Left unset, both `render` and `paint` default `-w/--width`/`--height` to the tem
|
|
|
309
323
|
|
|
310
324
|
The main SignalK plugin offers the same choice per device (defaulting to `crop` there too) in each device's own config - "If the render doesn't match the panel size".
|
|
311
325
|
|
|
326
|
+
`paint` has matching options for the other per-label image settings too (see [Other Image Options](#other-image-options)):
|
|
327
|
+
|
|
328
|
+
- `--mirror <mode>` - `none` (default), `horizontal`, `vertical`, or `both` (rotate 180°). `render` also takes `--mirror`, to preview the flip as a PNG without a label
|
|
329
|
+
- `--no-compress` - send the image uncompressed, to rule compression out if a label won't update
|
|
330
|
+
- `--compression-format <format>` - `auto` (default) or `chunked`, to try the experimental compressed format on a Gicisky 4.2" BWR
|
|
331
|
+
|
|
312
332
|
`esl-cli` can also be extended with new subcommands by a `-r/--require`'d package - see [Extending](#extending) below - which is how [`@rhizomatics/signalk-einklabel-genai-plugin`](#genai-rendering) adds its own `prompt`/`generate` commands for testing prompts without a device.
|
|
313
333
|
|
|
314
334
|
( The CLI can also be run from a checked out module, or by opening a terminal shell at `~/.signalk/node_modules/@rhizomatics/signalk-einklabel-plugin`, as `npx esl-cli command --args` )
|
|
@@ -377,12 +397,24 @@ The label address previously discovered via `esl-cli scan`
|
|
|
377
397
|
npx esl-cli paint -t templates/tides/250x128-BWRY.svg -a FF:FF:92:84:53:93
|
|
378
398
|
```
|
|
379
399
|
|
|
380
|
-
If the label turns out to be a different size than the template (e.g. it's a 250x128 template on a 416x240 panel),
|
|
400
|
+
If the label turns out to be a different size than the template (e.g. it's a 250x128 template on a 416x240 panel), it's cropped to fit by default - add `--reframe scale` to stretch it instead:
|
|
381
401
|
|
|
382
402
|
```bash
|
|
383
403
|
npx esl-cli paint -t templates/tides/250x128-BWRY.svg -a FF:FF:92:84:53:93 --reframe scale
|
|
384
404
|
```
|
|
385
405
|
|
|
406
|
+
If a label doesn't update, try sending it uncompressed to see whether compression is the cause:
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
npx esl-cli paint -t templates/tides/250x128-BWRY.svg -a FF:FF:92:84:53:93 --no-compress
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
If the image comes out mirrored, try each `--mirror` mode until it looks right, then set the same _Mirror_ option in the label's config:
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
npx esl-cli paint -t templates/tides/250x128-BWRY.svg -a FF:FF:92:84:53:93 --mirror horizontal
|
|
416
|
+
```
|
|
417
|
+
|
|
386
418
|
#### Test Template Without Updating Label
|
|
387
419
|
|
|
388
420
|
This will work even if you don't have a label, or even bluetooth. (The `-u` can be left out if your SignalK server running locally on default ports).
|
|
@@ -537,6 +569,8 @@ USB_DENYLIST="0b05:190e"
|
|
|
537
569
|
|
|
538
570
|
## Other ESL and General eInk Resources
|
|
539
571
|
|
|
572
|
+
### Components
|
|
573
|
+
|
|
540
574
|
- [Open ePaper Link](https://openepaperlink.de) - Alternative open source firmware to flash onto eInk shelf labels, with Home Assistant integration.
|
|
541
575
|
- [zhsunyco-esl](https://github.com/roxburghm/zhsunyco-esl) - Python interface
|
|
542
576
|
- [WoLink](https://github.com/NickWaterton/Wolink) - Python interface and protocol analysis
|
|
@@ -545,9 +579,14 @@ USB_DENYLIST="0b05:190e"
|
|
|
545
579
|
- [esp32-esl-system](https://github.com/giobauermeister/esp32-esl-system) - Docker and ESP32 based system for updating ESLs.
|
|
546
580
|
- [hass-gicisky](https://github.com/eigger/hass-gicisky) - Home Assistant integration for Gicisky ESLs ( a similar vendor to Zhsunyco). Uses [imagespec](https://github.com/eigger/imagespec) for templating.
|
|
547
581
|
- [ha-panda](https://github.com/moryoav/ha-panda) - Home Assistant integration for Panda ESLs ( a similar vendor to Zhsunyco).
|
|
582
|
+
|
|
583
|
+
### Notes and Experiences
|
|
584
|
+
|
|
585
|
+
- [Cabalist Gicisky Image Notes](https://github.com/Cabalist/gicisky_image_notes)
|
|
548
586
|
- [Dmitry.gr](https://dmitry.gr/?r=05.Projects&proj=29.%20eInk%20Price%20Tags) - Personal site of an ESL hacker
|
|
549
587
|
- [Aaron Christobel](https://www.youtube.com/@atc1441) - YouTube channel of an ESL hacker.
|
|
550
588
|
- [rbaron.net](https://rbaron.net/blog/2022/07/29/Daisy-chaining-multiple-electronic-shelf-labels) - Blog of an early ESL hacker.
|
|
589
|
+
### Retail
|
|
551
590
|
- [Pimoroni](https://shop.pimoroni.com/collections/displays?tags=e-ink%20Displays) - All shapes and sizes of eInk displays, aimed at hackers, and with an [inky](https://github.com/pimoroni/inky) GitHub project to support them.
|
|
552
591
|
- [WaveShare](https://www.waveshare.com/product/displays/e-paper.htm) - Wide range of eInk displays for hardware projects, not limited to ESLs.
|
|
553
592
|
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import { Colour } from "../devices/types";
|
|
3
|
+
import { Colour, CompressionFormat } from "../devices/types";
|
|
4
4
|
import { ReframeMode } from "../render/reframe";
|
|
5
|
+
import { MirrorMode } from "../render/mirror";
|
|
5
6
|
import { Binding } from "../render/binding";
|
|
6
7
|
import { TemplateContext } from "../render/types";
|
|
7
8
|
/** Tried in order when -u/--url is omitted (and -e/--example-data isn't given) - first one that answers wins. */
|
|
8
9
|
export declare const DEFAULT_SIGNALK_URLS: string[];
|
|
9
10
|
export declare function parseColours(code: string): Colour[];
|
|
10
11
|
export declare function parseReframeMode(value: string): ReframeMode;
|
|
12
|
+
export declare function parseMirrorMode(value: string): MirrorMode;
|
|
13
|
+
export declare function parseCompressionFormat(value: string): CompressionFormat;
|
|
11
14
|
/** Shared by every command that takes -u/--url and -e/--example-data - -e wins when both are present; when neither is given, probes DEFAULT_SIGNALK_URLS for a default. */
|
|
12
15
|
export declare function assembleContext(opts: {
|
|
13
16
|
url?: string;
|
package/dist/cli/index.js
CHANGED
|
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.program = exports.DEFAULT_SIGNALK_URLS = void 0;
|
|
5
5
|
exports.parseColours = parseColours;
|
|
6
6
|
exports.parseReframeMode = parseReframeMode;
|
|
7
|
+
exports.parseMirrorMode = parseMirrorMode;
|
|
8
|
+
exports.parseCompressionFormat = parseCompressionFormat;
|
|
7
9
|
exports.assembleContext = assembleContext;
|
|
8
10
|
const promises_1 = require("fs/promises");
|
|
9
11
|
const path_1 = require("path");
|
|
@@ -13,6 +15,8 @@ const registry_1 = require("../devices/registry");
|
|
|
13
15
|
const zhsunyco_1 = require("../devices/zhsunyco");
|
|
14
16
|
const gicisky_1 = require("../devices/gicisky");
|
|
15
17
|
const bleDiscovery_1 = require("../devices/bleDiscovery");
|
|
18
|
+
const types_1 = require("../devices/types");
|
|
19
|
+
const mirror_1 = require("../render/mirror");
|
|
16
20
|
const svgRenderer_1 = require("../render/svgRenderer");
|
|
17
21
|
const png_1 = require("../render/png");
|
|
18
22
|
const binding_1 = require("../render/binding");
|
|
@@ -45,6 +49,18 @@ function parseReframeMode(value) {
|
|
|
45
49
|
}
|
|
46
50
|
return value;
|
|
47
51
|
}
|
|
52
|
+
function parseMirrorMode(value) {
|
|
53
|
+
if (!mirror_1.MIRROR_MODES.includes(value)) {
|
|
54
|
+
throw new Error(`unknown --mirror value "${value}" - expected one of ${mirror_1.MIRROR_MODES.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
function parseCompressionFormat(value) {
|
|
59
|
+
if (!types_1.COMPRESSION_FORMATS.includes(value)) {
|
|
60
|
+
throw new Error(`unknown --compression-format value "${value}" - expected one of ${types_1.COMPRESSION_FORMATS.join(", ")}`);
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
48
64
|
/** Probes DEFAULT_SIGNALK_URLS in order and returns the first that answers a plain GET - used when -u/--url is omitted. */
|
|
49
65
|
async function resolveDefaultUrl() {
|
|
50
66
|
for (const candidate of exports.DEFAULT_SIGNALK_URLS) {
|
|
@@ -226,6 +242,9 @@ exports.program
|
|
|
226
242
|
.option("--voffset <px>", "vertical pixel offset of the panel - overrides the looked-up model for unsupported hardware (requires --colours)", "0")
|
|
227
243
|
.option("--colours <code>", "device colour palette for unsupported hardware: BW, BWR, or BWRY - overrides the looked-up model (uses --width/--height/--voffset)")
|
|
228
244
|
.option("--reframe <mode>", "how to fit the rendered image onto the device's actual panel size when it doesn't match: crop (default - place at top-left, truncating or leaving the rest blank), scale (stretch the template to the panel), fixed (reject the mismatch instead)", "crop")
|
|
245
|
+
.option("--mirror <mode>", "flip the image before sending: none (default), horizontal, vertical, or both (rotate 180°)", "none")
|
|
246
|
+
.option("--no-compress", 'send the image uncompressed (zhsunyco; gicisky 7.5"/10.2" or --compression-format chunked - compression is on by default)')
|
|
247
|
+
.option("--compression-format <format>", 'gicisky wire format: auto (default - the model\'s usual format) or chunked (experimental - send a 4.2" BWR compressed like the 7.5"/10.2")', "auto")
|
|
229
248
|
.option("--connect-timeout <seconds>", "BLE connect timeout before giving up on an attempt", "30")
|
|
230
249
|
.option("--retries <n>", "number of paint attempts (including the first) before giving up", "3")
|
|
231
250
|
.action(async (opts) => {
|
|
@@ -269,6 +288,9 @@ exports.program
|
|
|
269
288
|
modelOverride,
|
|
270
289
|
connectTimeoutMs,
|
|
271
290
|
reframe: parseReframeMode(opts.reframe),
|
|
291
|
+
mirror: parseMirrorMode(opts.mirror),
|
|
292
|
+
compress: opts.compress,
|
|
293
|
+
compressionFormat: parseCompressionFormat(opts.compressionFormat),
|
|
272
294
|
});
|
|
273
295
|
});
|
|
274
296
|
console.log(`painted ${opts.address} (${bitmap.width}x${bitmap.height}) ${opts.colours}`);
|
|
@@ -287,7 +309,9 @@ exports.program
|
|
|
287
309
|
.option("-f, --font <path>", "override a bundled font with this file (repeatable) - defaults to the bundled monospace/sans-serif/serif trio",
|
|
288
310
|
// See the -r/--require option above for why `| undefined` is needed here despite commander's typings.
|
|
289
311
|
(value, previous = []) => [...previous, value])
|
|
312
|
+
.option("--mirror <mode>", "flip the PNG the same way paint --mirror would: none (default), horizontal, vertical, or both", "none")
|
|
290
313
|
.action(async (opts) => {
|
|
314
|
+
const mirror = parseMirrorMode(opts.mirror);
|
|
291
315
|
const svgSource = await (0, promises_1.readFile)(opts.template, "utf-8");
|
|
292
316
|
const declared = (0, binding_1.readTemplateDimensions)(svgSource);
|
|
293
317
|
const width = resolveDimension(opts.width, [declared.width], DEFAULT_RENDER_WIDTH);
|
|
@@ -295,7 +319,7 @@ exports.program
|
|
|
295
319
|
const bindings = (0, binding_1.findBindings)(svgSource);
|
|
296
320
|
const context = await assembleContext(opts, bindings);
|
|
297
321
|
const renderer = opts.font ? new svgRenderer_1.SvgRenderer(opts.font) : new svgRenderer_1.SvgRenderer();
|
|
298
|
-
const bitmap = await renderer.render(opts.template, context, width, height, (0, path_1.dirname)(opts.template), config_1.BUNDLED_TEMPLATES_DIR);
|
|
322
|
+
const bitmap = (0, mirror_1.mirrorBitmap)(await renderer.render(opts.template, context, width, height, (0, path_1.dirname)(opts.template), config_1.BUNDLED_TEMPLATES_DIR), mirror);
|
|
299
323
|
await (0, promises_1.writeFile)(opts.output, (0, png_1.bitmapToPng)(bitmap));
|
|
300
324
|
console.log(`wrote ${opts.output} (${bitmap.width}x${bitmap.height})`);
|
|
301
325
|
});
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ServerAPI } from "@signalk/server-api";
|
|
2
|
-
import { Colour, DiscoveredDevice } from "./devices/types";
|
|
2
|
+
import { Colour, CompressionFormat, DiscoveredDevice } from "./devices/types";
|
|
3
3
|
import { ReframeMode } from "./render/reframe";
|
|
4
|
+
import { MirrorMode } from "./render/mirror";
|
|
4
5
|
/**
|
|
5
6
|
* Special `device` value meaning "every currently-known discovered device" instead of one specific
|
|
6
7
|
* BLE address - lets a single `DeviceConfig` entry (one template, one trigger) broadcast to every
|
|
@@ -26,8 +27,6 @@ export interface DeviceConfig {
|
|
|
26
27
|
* `./render/templateProviders.ts`) tailoring content to where the label actually sits.
|
|
27
28
|
*/
|
|
28
29
|
description?: string;
|
|
29
|
-
/** Per-device override; if omitted, the vendor driver may fall back to a stock/manufacturer-default key. */
|
|
30
|
-
aesKey?: string;
|
|
31
30
|
/**
|
|
32
31
|
* Either one specific `.svg` file, or the name of a *template-family* directory holding several
|
|
33
32
|
* same-purpose templates for different panel sizes/colour-sets, named `<width>x<height>-<colours>.svg`
|
|
@@ -48,8 +47,6 @@ export interface DeviceConfig {
|
|
|
48
47
|
intervalHours?: number;
|
|
49
48
|
/** ...at this minute past the hour. */
|
|
50
49
|
intervalMinute?: number;
|
|
51
|
-
/** One-shot override to repaint even if the data is unchanged; cleared automatically once that repaint completes. */
|
|
52
|
-
forceRepaint?: boolean;
|
|
53
50
|
/**
|
|
54
51
|
* How to fit the rendered image onto the device's actual panel size when it doesn't match (see
|
|
55
52
|
* `ReframeMode`) - e.g. a template family with no variant sized for this particular label. Left
|
|
@@ -58,7 +55,34 @@ export interface DeviceConfig {
|
|
|
58
55
|
* showing *something*, even off-size, beats a repaint that just fails outright.
|
|
59
56
|
*/
|
|
60
57
|
reframe?: ReframeMode;
|
|
58
|
+
/** Settings most labels never need, grouped so the admin UI shows them in their own "Advanced settings" box. */
|
|
59
|
+
advanced?: AdvancedDeviceSettings;
|
|
61
60
|
}
|
|
61
|
+
export interface AdvancedDeviceSettings {
|
|
62
|
+
/** Compress the upload (zhsunyco, and gicisky's chunked 7.5"/10.2" panels - ignored otherwise). Unset means on; turn off if a device fails to show compressed images. */
|
|
63
|
+
compress?: boolean;
|
|
64
|
+
/** Flip the image before sending - for a panel whose layout is mirrored, or one mounted upside down (`"both"`). Unset means `"none"`. */
|
|
65
|
+
mirror?: MirrorMode;
|
|
66
|
+
/**
|
|
67
|
+
* Experimental opt-in wire format (gicisky only) - `"chunked"` sends a 4.2" BWR (or another plain
|
|
68
|
+
* two-plane panel) QuickLZ-compressed like the 7.5"/10.2". Unset means `"auto"`, the model's own
|
|
69
|
+
* format. See `CompressionFormat`.
|
|
70
|
+
*/
|
|
71
|
+
compressionFormat?: CompressionFormat;
|
|
72
|
+
/** One-shot override to repaint even if the data is unchanged; cleared automatically once that repaint completes. */
|
|
73
|
+
forceRepaint?: boolean;
|
|
74
|
+
/** Per-device override; if omitted, the vendor driver may fall back to a stock/manufacturer-default key. */
|
|
75
|
+
aesKey?: string;
|
|
76
|
+
/** Per-device override of `PluginConfig.paintConnectTimeoutSeconds` - unset uses the plugin-wide value. */
|
|
77
|
+
paintConnectTimeoutSeconds?: number;
|
|
78
|
+
/** Per-device override of `PluginConfig.paintRetries` - unset uses the plugin-wide value. */
|
|
79
|
+
paintRetries?: number;
|
|
80
|
+
}
|
|
81
|
+
/** Applies `migrateDeviceConfig` to every device entry - see `healStoredConfig` for persisting the result. */
|
|
82
|
+
export declare function migrateConfig<T extends Partial<PluginConfig>>(config: T): {
|
|
83
|
+
config: T;
|
|
84
|
+
migrated: boolean;
|
|
85
|
+
};
|
|
62
86
|
export interface PluginConfig {
|
|
63
87
|
/**
|
|
64
88
|
* Directory the plugin scans for template files, instead of an upload UI - follows
|
|
@@ -71,6 +95,9 @@ export interface PluginConfig {
|
|
|
71
95
|
* signalk-bluetti-plugin does. Off by default - a `device: ALL_DEVICES` entry scans on demand the
|
|
72
96
|
* first time it has nothing discovered yet (see `resolveTargets` in `repaintScheduler.ts`), and an
|
|
73
97
|
* explicit device selection only ever needed this to populate the dropdown once at initial setup.
|
|
98
|
+
* Also unnecessary with `useBleApi` on, which discovers continuously in the background instead (see
|
|
99
|
+
* `startBleApiDiscoveryListener` in `discoveryCoordinator.ts`) - kept meaningful mainly for direct
|
|
100
|
+
* BlueZ access, which has no continuous-scan equivalent to piggyback on.
|
|
74
101
|
*/
|
|
75
102
|
scanOnStart: boolean;
|
|
76
103
|
/** How long the startup scan runs, in seconds. */
|
|
@@ -137,16 +164,21 @@ export declare const RENDER_FALLBACK_TEMPLATE_NAME = ".error";
|
|
|
137
164
|
export declare function defaultConfig(): PluginConfig;
|
|
138
165
|
export declare function readCurrentConfig(app: ServerAPI): Partial<PluginConfig>;
|
|
139
166
|
/**
|
|
140
|
-
* Actively rewrites the on-disk file
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* `
|
|
146
|
-
*
|
|
147
|
-
*
|
|
167
|
+
* Actively rewrites the on-disk file when it's in an outdated shape - `readCurrentConfig` alone only
|
|
168
|
+
* fixes things up in memory for callers that go through it, but the admin UI's config form
|
|
169
|
+
* round-trips whatever raw JSON it was handed verbatim. Two shapes are healed:
|
|
170
|
+
*
|
|
171
|
+
* - A nested file (see `readCurrentConfig`'s doc comment): left alone, the UI keeps re-persisting a
|
|
172
|
+
* stray nested `configuration` key it never touches (no schema field maps to it) forever (see
|
|
173
|
+
* `support/signalk-einklabel-plugin.json`).
|
|
174
|
+
* - Advanced device settings saved before they were grouped under `advanced` (see
|
|
175
|
+
* `migrateDeviceConfig`): left alone, the UI would show that group empty, even though the plugin
|
|
176
|
+
* itself still honours the old values.
|
|
177
|
+
*
|
|
178
|
+
* Called once at plugin start, which - unlike `clearForceRepaint` - isn't gated on any device having
|
|
179
|
+
* `forceRepaint` set, so an outdated file gets fixed even if nothing ever triggers that path.
|
|
148
180
|
*/
|
|
149
|
-
export declare function
|
|
181
|
+
export declare function healStoredConfig(app: ServerAPI): void;
|
|
150
182
|
/** See `resolveDir` - `templatesDir`'s own resolution. */
|
|
151
183
|
export declare function resolveTemplatesDir(templatesDir: string | undefined): string;
|
|
152
184
|
export declare function parseDevice(device: string): {
|