@rhizomatics/signalk-einklabel-plugin 0.4.1 → 0.4.2

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 CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.4.2
2
+ - Fix High/Low display for tide clock template
3
+ - Fix last repaint time for display being hour out
4
+ - Change default name of template directory to 'einklabel/templates'
1
5
  # 0.4.1
2
6
  - Packaging fixes
3
7
  # 0.4.0
package/README.md CHANGED
@@ -30,7 +30,7 @@ In the `description` of the SVG text box, use a comma separated set of key value
30
30
 
31
31
  For example, `path=environment.forecast.description` uses the default data source (the `self` vessel context) and the named SignalK path. A bare path with no key/value pairs at all, e.g. just `environment.forecast.description`, is shorthand for the same thing. Overriding the default context can be done with `path=environment.forecast.description,context=vessels.urn:mrn:imo:mmsi:232345678` - the `context` value must match a real SignalK context exactly as it appears in the Data Browser.
32
32
 
33
- #### SignalK REST APIs
33
+ #### SignalK REST APIs
34
34
 
35
35
  The source can be overridden to use the SignalK server's Resources API instead. For example, `source=resources,resource=tides,path=station.name` picks the `tides` resource and pulls the `station.name` path out of the JSON response - this works for any resource type (`tides`, `waypoints`, `routes`, ...), and needs nothing configured: the plugin reaches the Resources API directly. Where a resource is specified, it will be fetched once for that render, and subsequent fields sourced from the same resource use that cached response.
36
36
 
@@ -51,6 +51,8 @@ A `format` can be specified to make the value easier to understand. The supporte
51
51
 
52
52
  SignalK's unit preferences are used to automatically convert a `signalk`-sourced numeric value to its preferred display unit, and append a unit symbol like `kt` or `m`, unless `format=raw` is specified to switch that off. However, when using plugin or API data there may be no path metadata to convert from (for example `signalk-tides` publishes tide data to the Resources API, and `level` is a raw metre value with no SignalK path of its own) - in these cases an explicit `category` can be given instead, and the unit preferences will be applied the same way, for example `category=depth` for the tides level figure.
53
53
 
54
+ Note that for dates and times, the server timezone must be set correctly, for example `Europe/London` rather than the default `Etc/UTC`. This can be done on Linux using `timedatectl` or `raspi-config` if using a Raspberry Pi with Raspian.
55
+
54
56
  Common categories:
55
57
 
56
58
  * `depth` - Use the SignalK preferred depth unit, make the conversion if needed, and tack on the unit name as a suffix
package/dist/config.js CHANGED
@@ -13,7 +13,7 @@ const resolveApiUrl_1 = require("./resolveApiUrl");
13
13
  /** The package's own bundled `templates/` directory (ships alongside `dist/`, see package.json's `files`) - templates here are always available, but a same-named template in the user's `templatesDir` takes priority. */
14
14
  const BUNDLED_TEMPLATES_DIR = (0, path_1.join)(__dirname, '..', 'templates');
15
15
  const SIGNALK_HOME_DIR = (0, path_1.join)((0, os_1.homedir)(), '.signalk');
16
- const DEFAULT_TEMPLATES_DIR = (0, path_1.join)(SIGNALK_HOME_DIR, 'esl', 'templates');
16
+ const DEFAULT_TEMPLATES_DIR = (0, path_1.join)(SIGNALK_HOME_DIR, 'einklabel', 'templates');
17
17
  function defaultConfig() {
18
18
  return {
19
19
  templatesDir: '',
@@ -14,13 +14,17 @@ function formatDisplayUnits(value, displayUnits, round) {
14
14
  /**
15
15
  * The local vessel's timezone (`signalk.self.environment.time.timezoneRegion`), regardless of which
16
16
  * vessel's value is being formatted - the display's own clock/locale is what matters, not the data
17
- * source's. Falls back to UTC when unset.
17
+ * source's. Most installs never publish that path (it needs a GPS/position-derived timezone plugin),
18
+ * so this falls back to the host machine's own configured zone - the same thing the SignalK Data
19
+ * Browser ends up showing, since it's just the browser's local `Intl` zone rather than anything the
20
+ * server itself publishes. For the live plugin that's the device's own OS timezone (set once via
21
+ * `raspi-config`/`timedatectl` et al, not GPS-derived); for the CLI it's the developer machine's.
18
22
  */
19
23
  function selfTimezone(context) {
20
24
  const signalk = context.signalk;
21
25
  const self = signalk?.self;
22
26
  const environment = self?.environment;
23
- return environment?.time?.timezoneRegion || 'utc';
27
+ return environment?.time?.timezoneRegion || Intl.DateTimeFormat().resolvedOptions().timeZone;
24
28
  }
25
29
  /**
26
30
  * Shows the explicit IANA zone name rather than an abbreviation (e.g. "BST") - UK tide tables are
@@ -62,8 +62,16 @@ class SvgRenderer {
62
62
  const descElement = element.getElementsByTagName('desc').item(0);
63
63
  if (!descElement)
64
64
  continue;
65
- const binding = (0, binding_1.parseBinding)(descElement.textContent ?? '');
66
- element.textContent = (0, binding_1.renderBinding)(binding, context);
65
+ // Scoped to this one element - a single bad/unavailable binding (e.g. a resource that hasn't
66
+ // loaded yet) must not blank out every other field on the label, nor abort the whole repaint.
67
+ try {
68
+ const binding = (0, binding_1.parseBinding)(descElement.textContent ?? '');
69
+ element.textContent = (0, binding_1.renderBinding)(binding, context);
70
+ }
71
+ catch (err) {
72
+ console.error(`field "${descElement.textContent}" failed to render: ${err.message}`);
73
+ element.textContent = 'ERROR';
74
+ }
67
75
  }
68
76
  const svgOutput = new xmldom_1.XMLSerializer().serializeToString(doc);
69
77
  const resvg = new resvg_wasm_1.Resvg(svgOutput, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhizomatics/signalk-einklabel-plugin",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "SignalK plugin that renders selected SignalK data to eInk Electronic Shelf Labels",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -63,15 +63,15 @@
63
63
  font-size="18"
64
64
  font-family="serif"
65
65
  fill="black"
66
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:2.39571"
66
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ffffff;stroke-width:2.39571"
67
67
  transform="scale(0.83037506,1.2042751)"><tspan
68
68
  sodipodi:role="line"
69
69
  id="tspan1"
70
70
  x="325.49939"
71
71
  y="195.87753"
72
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:2.39571;fill:#999999">signalk-einklabel-plugin</tspan></text>
72
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.99999995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:2.39571;fill:#ffffff">signalk-einklabel-plugin</tspan></text>
73
73
  <text
74
- id="station.name-8-2"
74
+ id="last_repaint"
75
75
  x="4.3477793"
76
76
  y="201.9895"
77
77
  font-size="18"
@@ -81,10 +81,7 @@
81
81
  transform="scale(0.85412558,1.170788)"><desc
82
82
  id="desc12">source=einklabel,path=repainted,format=local_datetime_short</desc><tspan
83
83
  sodipodi:role="line"
84
- id="tspan3"
85
- x="4.3477793"
86
- y="201.9895"
87
- style="stroke-width:1.19309;-inkscape-font-specification:'Sans, Normal';font-family:Sans;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:13.33333347px;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">Last updated 27 Jun 26 18:05</tspan></text>
84
+ id="tspan3">27 Jun 26 18:05</tspan></text>
88
85
  <text
89
86
  id="extremes.0"
90
87
  x="7.9661016"
@@ -92,7 +89,8 @@
92
89
  font-size="14"
93
90
  font-family="monospace"
94
91
  fill="black"
95
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;font-family:monospace;-inkscape-font-specification:'monospace, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff0000">High Water</text>
92
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;font-family:monospace;-inkscape-font-specification:'monospace, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff0000"><desc
93
+ id="desc13">source=resources,resource=tides,path=extremes.[0].label</desc>High Water</text>
96
94
  <text
97
95
  id="extremes.1"
98
96
  x="13.35283"
@@ -100,7 +98,8 @@
100
98
  font-size="14"
101
99
  font-family="monospace"
102
100
  fill="black"
103
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;font-family:monospace;-inkscape-font-specification:'monospace, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff0000">Low Water</text>
101
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;font-family:monospace;-inkscape-font-specification:'monospace, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff0000"><desc
102
+ id="desc14">source=resources,resource=tides,path=extremes.[1].label</desc>Low Water</text>
104
103
  <text
105
104
  id="extremes.2"
106
105
  x="7.9661016"
@@ -108,7 +107,8 @@
108
107
  font-size="14"
109
108
  font-family="monospace"
110
109
  fill="red"
111
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;font-family:monospace;-inkscape-font-specification:'monospace, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff0000">High Water</text>
110
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;font-family:monospace;-inkscape-font-specification:'monospace, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ff0000"><desc
111
+ id="desc15">source=resources,resource=tides,path=extremes.[2].label</desc>High Water</text>
112
112
  <text
113
113
  id="environment.time.timezoneRegion"
114
114
  x="338.47461"