WilhelmSK User Guide¶
Everything you need to set up and use WilhelmSK across all supported platforms. The table of contents above (or on the home page) is the fastest way to jump to a section.
Before You Start¶
WilhelmSK is a display client — you'll connect it to a data source on your boat (or wherever the data lives). The full setup flow is in Connecting to a Data Source below. First, a few basics that apply regardless of which source you choose.
Device Requirements¶
| Platform | Minimum Version |
|---|---|
| iPhone / iPad | iOS 13 |
| Apple Watch | watchOS 10.6 |
Installing WilhelmSK¶
Search "WilhelmSK" on the App Store. The app is a universal binary — one purchase covers iPhone and iPad. The Apple Watch app installs automatically from the iPhone app.
Network Requirements¶
Whichever data source you use, your iOS device and the data source need to reach each other on the network. For most setups that means the same boat Wi-Fi or LAN.
WilhelmSK uses Bonjour (mDNS) to discover compatible servers and devices automatically. Most home and boat routers pass mDNS without configuration; some enterprise or managed switches block it. If auto-discovery doesn't find your server, you can always enter the address manually — covered in each Connecting section below.
For monitoring from outside the boat's network (cellular, marina Wi-Fi, shore), see Remote Access further down.
Connecting to a Data Source¶
This is where most of your one-time setup happens. WilhelmSK can connect directly to a range of marine data products over your boat's network. All connections below are IP-based — Wi-Fi or Ethernet:
| Source | Best for |
|---|---|
| SignalK server | The flexible default — runs on a Raspberry Pi or similar, aggregates all your NMEA data, works with every WilhelmSK feature |
| Victron Venus | Victron Energy installations — batteries, inverters, solar, shore power. Local MQTT, VRM cloud MQTT, or VRM cloud SignalK |
| Actisense W2K | Direct NMEA 2000 over Wi-Fi via an Actisense W2K-1 or W2K-2 gateway |
| Yacht Devices YDWG | Direct NMEA 2000 over Wi-Fi via a Yacht Devices YDWG-02 gateway |
| Digital Yacht RAW | Generic connection for Yacht Devices products; does same thing as YDWG |
| NMEA 0183 over TCP/IP | Any device streaming raw NMEA 0183 sentences over a TCP socket |
| Multiple Connections | Aggregate two or more of the above into one combined source |
You can have several connections configured at once (e.g., local SignalK at the dock and Victron VRM cloud when away). Pick the section below that matches your installation.
SignalK¶
What it is¶
SignalK is an open marine-data standard. A SignalK server typically runs on a Raspberry Pi, NAS, or boat computer; it collects NMEA data from your instruments and makes it available over your local network. WilhelmSK connects to that server, subscribes to live data, and drives its gauges from the stream.
Two protocols are used together:
- REST — used at startup to discover the server's endpoints and fetch initial values.
- WebSocket — used for live streaming of instrument data (deltas). This is how gauges update in real time.
If you already have a SignalK server running on your boat and know its IP address or hostname, skip ahead to Auto-discovery or Manual connection below.
Running a SignalK server¶
If you don't have a SignalK server yet, common options on boats are:
Raspberry Pi (most common) — A dedicated Pi is the most popular choice. It draws very little power, handles the 24/7 server load easily, and can be wired directly to the boat's NMEA backbone. A Pi 3B+ or newer running Raspberry Pi OS is sufficient. The official installation instructions are at https://github.com/SignalK/signalk-server.
NAS or existing boat computer — If you already have a network-attached storage device or a Linux/Windows machine running continuously, SignalK can run there. Anything that can run Node.js works.
Mac or PC on the same network — A laptop or desktop on the boat's Wi-Fi is a valid option for testing or temporary use. You wouldn't normally leave a laptop running 24/7 at the nav station, but it's a convenient way to try the setup before committing to a Pi.
Auto-discovery (Bonjour)¶
If your SignalK server advertises itself via mDNS/Bonjour (which signalk-server-node does by default), WilhelmSK discovers it automatically. Open Settings → Connections and the server appears in the list within a few seconds. Tap it to connect — no manual entry required.
The app browses for four service types: _signalk-http._tcp, _signalk-https._tcp, _signalk-ws._tcp, and _signalk-wss._tcp. Discovering any one of these is enough. Vessel name, type, and MMSI are read from the server's TXT record and shown in the connection list.
Bonjour requires the phone/tablet to be on the same local network (same Wi-Fi or same VLAN) as the server. It does not work across VPN or different subnets without mDNS forwarding.
Manual connection¶
If Bonjour discovery isn't available — for example, when connecting over a VPN or to a server on a different subnet — tap Add Connection → SignalK and enter the server's host and port manually.
Fields to fill in:
- Host — IP address or hostname of the server (e.g.,
192.168.1.100orraspberrypi.local) - REST port — typically
3000for HTTP or443for HTTPS - WebSocket port — typically the same as the REST port
- SSL — toggle on if your server uses HTTPS/WSS
The app fetches the server's /signalk endpoint on first connect and auto-fills the REST and WebSocket endpoint paths. You rarely need to edit those fields.
Authentication¶
WilhelmSK supports three authentication modes for SignalK:
None — the default. Works if your server doesn't require authentication (common on private boat networks).
HTTP Basic — enter a username and password. Credentials are sent with each request using standard HTTP Basic authentication. The app also handles server certificate trust challenges, so self-signed certs work if you accept the prompt.
JWT token — if your server requires login (via /signalk/v1/auth/login), enter a username and password and the app will log in automatically on each connection, storing and reusing the JWT token. The token is sent as Authorization: JWT <token> on all subsequent requests.
iCloud sync and favorites¶
Manual connections (ones you added by hand rather than discovered via Bonjour) are synced to iCloud. If you add a connection on your iPhone, it appears on your iPad automatically without re-entering the details.
Each connection can be marked as a favorite. Favorites appear at the top of the connections list, making it easy to jump to your most-used server when you have multiple connections configured.
Victron Venus¶
Victron Energy's Venus OS (running on a Cerbo GX, Color Control GX, or compatible Raspberry Pi) exposes vessel electrical data — batteries, solar, inverters, shore power, tanks. WilhelmSK supports three connection paths to it: local MQTT, VRM cloud MQTT, and VRM cloud SignalK.
Local MQTT¶
What it is: A direct connection to the MQTT broker running on your Venus device on your local network.
When to use it: You're on the boat, connected to the same Wi-Fi as your Venus device. This gives the lowest latency and works without internet access.
How to configure: Tap Add Connection → Venus MQTT (Local). Enter:
- Host — IP address or hostname of your Venus device (e.g., 192.168.1.50 or cerbo.local)
- Port — MQTT port, typically 1883
- Username / Password — leave blank if your Venus device doesn't require authentication; otherwise use the credentials set in Venus OS
VRM Cloud (Victron Remote Monitoring)¶
What it is: A connection through Victron's hosted VRM portal (mqtt.victronenergy.com) to your Venus device, tunneled over the internet. Data is routed through Victron's MQTT brokers.
When to use it: You're away from the boat and want to check on your system remotely, or you want to monitor multiple vessels registered in your VRM account.
How to configure:
- Tap Add Connection → Venus VRM.
- Enter your VRM account username and password.
- Tap Refresh Installations. The app logs in to VRM and lists every installation registered to your account.
- Check the box next to the installation you want to monitor. Multiple installations can be checked — the app uses the first checked one for this connection.
- Save.
Under the hood the app connects to mqtt<N>.victronenergy.com:8883 using TLS. It keeps the connection alive by publishing a keepalive message every 62 seconds. You don't configure any of that manually.
Note: VRM cloud connections require internet access on both the phone and the Venus device. If the Venus device loses its cellular or marina Wi-Fi connection, the VRM connection drops.
VRM Cloud — SignalK endpoint¶
What it is: Reach your Venus device's SignalK server through the VRM cloud, instead of going through Victron's MQTT brokers. Picks up the same data the SignalK path would carry locally — custom paths, server plugins, and anything else SignalK offers — but tunneled over the internet via VRM.
When to use it: Same scenarios as the plain VRM MQTT variant (you're away from the boat, monitoring remotely), but you want the full SignalK feature set rather than the more limited MQTT view. If you only need standard Victron values (batteries, solar, etc.) the plain VRM MQTT path is simpler.
Prerequisite — Venus OS Large with Signal K enabled:
Signal K Server is only shipped in Venus OS Large, the extended firmware variant. Standard Venus OS does not include it. Steps on the Venus device (per Victron's Venus OS Large docs):
- Settings → General → Firmware → Online updates — set Image type to
Largeand run the update. - After the reboot, Settings → Signal K — enable it. This requires Installer access level (the default User level can't toggle it; promote yourself via Settings → General → Access Level).
- Verify the Signal K admin is reachable from the boat network at
http://venus.local:3000(or the Venus device's IP at port3000). - Confirm the Venus device is online in your VRM portal —
https://vrm.victronenergy.com/.
Once Signal K is running on the device and the device is online in VRM, WilhelmSK can reach it through the VRM relay.
How to configure:
- Tap Add Connection → Venus VRM Signal K.
- Enter your VRM account username and password.
- Tap Refresh Installations. The app logs in to VRM and lists every installation registered to your account.
- Check the box next to the installation whose Signal K server you want to reach. Checking the box authorizes WilhelmSK to use your VRM credentials to relay through to the Signal K server running on that installation. Multiple installations can be checked.
- Save.
Under the hood, on first connect the app calls VRM's /v2/auth/login for a token, then opens a Signal K proxy relay at /v2/installations/<siteId>/proxy-relay/signalk for the checked installation. From there it behaves like a normal Signal K connection — auto-discovers REST and WebSocket endpoints from the relayed server, subscribes to deltas, drives gauges from the stream.
Note: VRM Cloud SignalK requires internet access on both the phone and the Venus device, plus the Venus device must be online in VRM (the same constraint as VRM MQTT). It does not require the phone to be on the same network as the boat.
Data format note¶
Venus/MQTT data is converted to SignalK deltas internally using a JavaScript bridge (venus.js). The gauges you configure work the same way regardless of whether the source is SignalK or Venus — the connection type is transparent once you're past setup.
Actisense W2K¶
The Actisense W2K-1 picker entry works with both the Actisense W2K-1 and the newer W2K-2 NMEA 2000 Wi-Fi gateways. Both stream NMEA 2000 directly over a TCP server you configure on the device.
Setup¶
Recent W2K firmware no longer streams in a directly-usable format out of the box — you have to enable the gateway's DS2 server and set its output to N2K ASCII before anything can read it. The exact menus depend on firmware version; the steps below follow Signal K's W2K-1 configuration FAQ, which is the authoritative reference.
- Power up the gateway. By default it creates its own Wi-Fi access point named
w2k-<serial>(the serial is printed on the rear of the case, along with the Wi-Fi password). Connect your iOS device to that AP, or bring the W2K onto your boat's Wi-Fi via its admin UI. - Open the gateway's admin page at http://192.168.4.1/. Default login is
adminwith the password printed on the case. - Firmware ≥ 1.3878: under Settings → Data Server, activate the DS2 Server with Direction Both on port 60002; under Settings → Serial, set the Tx Format to "N2K ASCII for the DS2 Interface"; under Settings → Routing, enable DS2 for Source N2K and N2KV1 for Source DS2. Older firmware: configure a Server with format N2K ASCII, direction Both, protocol TCP, and note the port.
- In WilhelmSK, Settings → Connections → + and pick Actisense W2K-1. Enter the gateway's IP address and the TCP port (
60002on current firmware).
The same N2K ASCII TCP stream can instead feed a Signal K server (add it there as a "W2K-1 N2K ASCII (canboatjs)" NMEA 2000 connection), then connect WilhelmSK to that server — the recommended path if you want plugins, alarms, and history.
Vendor docs¶
- W2K-1: actisense.com/products/w2k-1
- W2K-2: actisense.com/products/w2k-2
Yacht Devices YDWG¶
The Yacht Devices YDWG-02 NMEA 2000 Wi-Fi gateway supports up to three configurable TCP/UDP servers. Server #1 ships pre-configured for NMEA 0183 on TCP port 1456, which works as-is with WilhelmSK's YDWG picker entry.
Setup¶
- Power up the gateway. Default Wi-Fi SSID and password are printed on the case. Connect your iOS device to that AP, or bridge the YDWG onto your boat's Wi-Fi via its admin UI.
- Admin UI at http://192.168.4.1/ or http://ydwg.local/ (mDNS supported). Default login
admin/admin. - Server #1's defaults work out of the box. If you've reconfigured it, note the IP, port, and protocol in the gateway's status page.
- In WilhelmSK, Settings → Connections → + and pick YDWG. Enter the gateway's IP and port
1456(or whatever you've set Server #1 to).
Vendor docs¶
Digital Yacht RAW¶
The Digital Yacht RAW picker entry is functionally identical to the YDWG entry — it's an alias of the same connection type, kept so that new products don't each need their own entry in the picker. Pick whichever name matches your hardware — the behavior is the same.
Setup¶
- Power up the gateway. Digital Yacht Wi-Fi units create their own AP —
DY-WiFi-xxxx(WLN30) orNAVLink-xxxx(NavLink2), with passwordPASS-xxxxmatching the 4-char SSID code. Join that AP from your iOS device, or bring the gateway onto your boat's Wi-Fi via its admin UI at http://192.168.1.1/ (no login on first connection from its own AP). - Digital Yacht gateways default to TCP port 2000 (UDP 2000 serves the same stream).
- In WilhelmSK, Settings → Connections → + and pick Digital Yacht RAW. Enter the gateway's IP and port
2000.
Compatible with Digital Yacht's Wi-Fi and Ethernet NMEA gateway lineup (WLN10 / WLN10SM, WLN30, NavLink2, LANLink, iKonvert in Wi-Fi mode). For any other device that streams NMEA 0183 over TCP — including the Yacht Devices YDEN-02 Ethernet gateway — this entry, YDWG, and NMEA 0183 are interchangeable; just enter the host and port.
Vendor docs¶
- Digital Yacht: digitalyacht.support — WLN30, NavLink2, LANLink
NMEA 0183 over TCP/IP¶
For any device that streams raw NMEA 0183 sentences over a TCP socket — multiplexers, AIS receivers, software bridges, custom gateways — use the NMEA 0183 picker entry.
Setup¶
In WilhelmSK, Settings → Connections → + and pick NMEA 0183. Enter:
- Host — IP or hostname of the device producing the NMEA 0183 stream
- Port — the device's NMEA-over-TCP port. The IANA-registered default is 10110, but many vendors override (Digital Yacht uses
2000, Yacht Devices uses1456— for those, use the dedicated picker entries above)
The wire format is standard NMEA 0183: $GPRMC,...*hh\r\n lines. "RAW" in vendor parlance just means "unfiltered pass-through" — same wire format as plain NMEA 0183.
Multiple Connections¶
If your boat has more than one data source — for example, a SignalK server for navigation data and a separate NMEA 2000 gateway for engine data — you can aggregate them into one combined connection. Each source feeds the same gauge layout.
In WilhelmSK, Settings → Connections → + and pick Multiple Connections. Add the individual connections (each already configured per the sections above), and the app merges their data streams.
Remote Access¶
By default WilhelmSK connects over the local Wi-Fi on the boat. If you want to monitor your vessel from shore, a marina Wi-Fi, or a cellular connection, you need to make the SignalK server reachable from off the boat. The two direct-exposure approaches below (port forwarding, reverse proxy) are common, but a VPN or tunnel service is usually the safer choice — see VPN and Tunnel Services and Signal K's own remote-access FAQ.
Port Forwarding (Simple)¶
Forward a port on your boat's router to the SignalK server's local IP and port (typically 3000). On your router's admin page, add a TCP port-forward rule:
- External port: any unused port (e.g. 3001, or 443 for HTTPS)
- Internal IP: the SignalK server's local IP (e.g. 192.168.1.100)
- Internal port: 3000
In WilhelmSK, add a manual SignalK connection using your router's public IP address (or a dynamic-DNS hostname if your ISP gives you a changing IP) and the external port you chose. Enable SSL only if your server is configured for HTTPS.
Port forwarding is quick to set up but exposes your SignalK server directly to the internet on that port. At minimum, enable authentication on the server (Settings → Security in the SignalK admin panel) and use JWT or HTTP Basic auth in WilhelmSK.
Reverse Proxy with nginx (Recommended)¶
A reverse proxy sits in front of SignalK, handles HTTPS termination, and can add authentication before requests reach the server. This is more work to set up but gives you a clean https:// URL, a valid TLS certificate (via Let's Encrypt), and optional Basic Auth as an additional layer.
A typical setup (as used with the pivac HVAC monitoring project):
- Install nginx on the machine running SignalK (or a Pi on the same network).
- Obtain a TLS certificate — Let's Encrypt via
certbotis the standard free option. - Forward TCP ports 80 and 443 from your router to the nginx machine.
- Configure an nginx
locationblock for SignalK. The critical part is the proxy headers — without these, SignalK constructs its WebSocket URL using its local address instead of your external hostname, which breaks the WilhelmSK connection:
location /signalk/ {
proxy_pass http://localhost:3000/signalk/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
-
In the SignalK admin panel, go to Server → Settings and enable "Trust Proxy". Without this, SignalK ignores the
X-Forwarded-Protoheader and still generatesws://WebSocket URLs, causing WilhelmSK to attempt an unencrypted connection on port 80 — which nginx immediately redirects (301), breaking the handshake. -
In WilhelmSK, add a manual connection using your external hostname (
https://yourhostname.example.com), port 443, with SSL enabled. The app will discover the server endpoints through the standard/signalkpath and connect via WSS.
VPN and Tunnel Services¶
Rather than exposing the server directly, you can join your phone and your boat to the same private network, or let a hosted service tunnel the connection for you. These avoid opening any inbound ports on your boat's router and are what the Signal K project's remote-access FAQ recommends:
- Tailscale — a zero-config WireGuard-based VPN. Install it on the boat's server and on your iPhone, and the server appears at a stable private IP from anywhere. The simplest option for most boats.
- ZeroTier — a peer-to-peer mesh VPN, similar in effect to Tailscale; both put your devices on one virtual LAN with no port forwarding.
- ngrok — a tunnel service that gives the local server a public HTTPS URL without touching the router. Good for occasional access.
- remote.it — a remote-access platform that brokers connections to the server without inbound ports.
With any of these, connect WilhelmSK using the address the service assigns (a Tailscale/ZeroTier private IP, or an ngrok/remote.it hostname) and the SignalK port, exactly as you would on the local network.
Tips¶
Multiple connections: WilhelmSK supports configuring multiple connections. You can have a SignalK connection for use at the dock, a VRM cloud connection for remote monitoring, and a local Venus connection all saved in the list. Switch between them from the connections screen.
Connection log: If a connection fails, tap it in the list and look for a connection log option. The log shows each authentication and handshake step, which helps diagnose JWT login failures, certificate issues, or wrong-port problems.
Watch and widget access: Manual connections synced to iCloud are also available to the Apple Watch app and home screen widgets. The watch uses the same connection settings you configured on the iPhone.
SSL and self-signed certificates: If your server uses HTTPS with a self-signed certificate, the app will prompt you to trust it on first connection. Accept the prompt and the certificate is trusted for future sessions. Rejecting it will prevent connection.
Not Just for Boats¶
WilhelmSK works with any SignalK data source, not only marine instruments. SignalK is a generic key-value protocol with a defined path namespace; anything that can push data to a SignalK server can be displayed in the app.
A concrete example is pivac, a Raspberry Pi sensor collector for HVAC and home automation. pivac reads temperature sensors, relay states, thermostat data (via a Honeywell RedLink cloud API), hydronic pressure gauges, and power monitors, then pushes delta messages to a local SignalK server over WebSocket. WilhelmSK connects to the same server and displays all of that data using the same gauge system as a marine installation — water temperature gauges showing HVAC supply/return/outdoor temperatures, a switch bank showing relay states, thermostat gauges for thermostat setpoints, and custom text gauges for boiler status.
If you have sensors or automation equipment that can push data to SignalK, WilhelmSK can display it. See Custom SignalK Paths for how to configure gauges for non-marine SignalK paths.
iOS and iPadOS¶
WilhelmSK on iPhone and iPad is the primary interface for configuring the app, managing layouts, and viewing live instrument data. This guide covers navigation, customization, widgets, and notifications.
Navigation¶
The Sidebar¶
The sidebar is the app's main navigation panel. Swipe right from the left edge (or tap the hamburger menu) to open it. It contains three sections:
- Gauges — returns to the live gauge display
- Settings — connection, appearance, units, notifications, and advanced options
- Log — raw SignalK message log for debugging
Swipe left or tap anywhere on the main panel to close the sidebar.
Layouts and the Layout Selector¶
A layout is a named collection of pages. You might have a "Sailing" layout with wind and performance gauges, a "Motoring" layout with engine and fuel gauges, and an "At Anchor" layout with depth and battery. Switch between layouts in the sidebar's layout list.
Each layout is independent — its pages, gauge arrangement, and gauge configuration are stored separately. You can create as many layouts as you need.
Pages and the Gauge Grid¶
Within a layout, data is organized into pages. Swipe left and right (iPhone/iPad portrait) or up and down (iPad landscape) to move between pages. Each page displays a configurable grid of gauges.
Pages use named templates that control how space is divided:
| Template | Description |
|---|---|
| Basic | Equal-size grid cells |
| LargeBottomView | One large gauge on top, smaller gauges below |
| LargeCenterGauge | Large gauge in the center with smaller gauges around it |
| MFD | Multi-function display style with many gauges |
| FullScreen | Single gauge fills the page |
Interacting with Gauges in the Live View¶
Double-Tap: Fullscreen¶
Double-tap any gauge to expand it to fill the entire screen. The status bar hides for a cleaner view. Double-tap again to return to the normal page grid.
Long-Press: Gauge Settings and Type¶
Long-press any gauge (hold for about a second) to open a full gauge settings panel. From here you can: - Change the gauge type (switch from, say, a wind dial to a depth gauge) - Set the SignalK path the gauge reads - Adjust display options — digital vs analog, title, units, decimal places - Configure alarm zones — color thresholds that turn the gauge red/yellow when a value is out of range
On iPad, the settings panel opens as a split-view overlay. On iPhone, it pushes as a navigation stack.
Long-press is disabled when Lock Gauges is on (Settings → Lock Gauges). Enable the lock when underway to prevent accidental changes.
Layout Manager and Editor¶
The Layout Manager is the screen that controls which pages appear in your layout and how they are structured. It has three sections, each with a distinct purpose:
Your Pages — the pages currently active in your layout, in the order they appear when you swipe left and right. Drag pages within this section to reorder them. Drag a page down into Custom Page Templates to save it as a reusable template.
Builtin Page Templates — read-only factory templates supplied by the app. You cannot edit these directly. Drag one up into Your Pages to add a copy to your layout. Drag one down into Custom Page Templates to create your own editable copy of it.
Custom Page Templates — your personal reusable templates. You can edit these freely, and you can drag them up into Your Pages to use them.
The final item in Your Pages and in Custom Page Templates is an Add placeholder. Tap it to create a new blank page or template.
Tapping a Page from "Your Pages" → Page Config Mode¶
When you tap a page from Your Pages, the editor opens in page config mode. This mode shows you the current page layout and lets you make gauge-level changes, but it does not let you restructure the slot layout (positions and sizes).
What you see: Save and Cancel buttons. An Edit Template or Convert To Template button. What you do not see: Add (+), Delete (−), Width/Height fields, Add Grid, or Snap.
| Button | What it does |
|---|---|
| Edit Template | Opens the underlying layout template in template mode so you can add, remove, or reposition slots. Changes apply to all pages sharing that template. |
| Convert To Template | Shown for built-in templates instead of Edit Template. Creates a personal editable copy of the template and immediately opens it in template mode. |
| Save | Saves gauge-level changes for this page. |
| Cancel | Discards changes. |
Dragging is disabled entirely in page config mode — the editor does not move slots when you pan.
Tapping a Template from "Custom Page Templates" → Template Mode¶
When you tap a template from Custom Page Templates, the editor opens in template mode — the full structural editor. This is where you control how many gauge slots a template has, where they are, and how large they are.
Controls:
| Control | What it does |
|---|---|
| + (Add) | Adds a new gauge slot at the top-left, sized to match the selected slot if one is selected, otherwise 200×200. Drag it into position after adding. |
| − (Delete) | Removes the selected slot. If slots are grouped via multi-select, removes all of them. |
| Add Grid | Opens a grid tool with sliders for columns, rows, and cell size (as % of screen). The resulting grid appears as a movable group. |
| Width / Height | Exact pixel dimensions for the selected slot. Type and press Return. Updates live as you drag or pinch. |
| Snap | When on (default), slots snap within 10 pixels of adjacent slots and screen edges while dragging. |
| Multi | Multi-select mode. When on, tap additional slots to add them to a movable group; tap a grouped slot to remove it. Toggle off to commit positions. |
| Share | Saves the template, then offers: Share... (sends as .wlyt via AirDrop, Mail, Messages, or Files) or Send to device... (pushes to another WilhelmSK device on the same network via Bonjour). |
| Save | Saves all structural changes. |
| Cancel | Discards all changes. |
Gestures in template mode:
| Gesture | Effect |
|---|---|
| Tap | Selects a slot (red border). Tapping an already-selected slot cycles to the one underneath if slots overlap. |
| Drag from slot interior | Moves the slot. |
| Drag from bottom-right corner | Resizes the slot — the bottom-right corner is the resize handle. |
| Pinch | Resizes the slot from its center. |
Changing Which Gauge a Slot Displays¶
The layout editor controls positions and sizes only. To change which gauge type fills a slot — or to configure its SignalK path, display options, or alarm zones — long-press the gauge in the normal live view. See Long-Press: Gauge Settings and Type.
Editing Layout Files on Your Computer¶
WilhelmSK stores layouts as .wlyt files — plain JSON. For complex layouts, editing the JSON directly on a Mac is often faster than dragging gauges on a small screen.
Getting the file off your device:
1. Open the Files app on your iPhone or iPad.
2. Tap On My iPhone (or On My iPad) → WilhelmSK. Saved layout files appear here.
3. Long-press a .wlyt file and choose Share → AirDrop to send it to your Mac, or copy it to iCloud Drive for Finder access.
Alternatively, connect your device via USB, open Finder on the Mac, select your device, click Files, and drag the .wlyt file out.
Editing:
The format is JSON. Open it in any text editor. The top-level layout key contains a pages array; each page has a pageLayout (template name) and a config dictionary keyed by gauge slot index. The two fields you'll most often edit are the SignalK path and the className (gauge type). See Custom SignalK Paths for path conventions.
Putting it back:
1. AirDrop the edited .wlyt back to your iPhone or iPad, or place it in a Files location you can access from the device.
2. Tap the file. iOS prompts you to open it with WilhelmSK.
3. WilhelmSK imports it and adds it to your layout list.
You can also share a layout directly from within the app — tap Share in the layout editor toolbar to send the current layout via AirDrop, Mail, Messages, or any available share target.
Settings Reference¶
The Settings menu is reached from the sidebar. The following sections describe every option.
Connections¶
Covered in detail in Connecting to a Data Source.
Appearance¶
Theme: - Theme — the active color palette. Tap to choose from built-in and custom themes. - Day — the theme used for the light/day mode when Auto is selected. - Night — the theme used for the dark/night mode when Auto is selected. - Force Dark Appearance — forces the dark theme regardless of system appearance setting. - Apple — segmented control: Light | Dark | Auto. Sets whether the app follows the iOS system appearance toggle.
Display: - Text Shadow — adds a subtle drop shadow to gauge labels for readability over busy backgrounds. - Segmented Digital Font — uses the app's built-in digital/7-segment font for digital readouts. - Digital Font — shows the current digital font name; tap to open the font picker. - Title Display — opens font settings for gauge titles (font face, size, color, position). - Units Display — opens font settings for gauge unit labels. - Freshness — where to show the data freshness indicator on each gauge: None, Top-Left, Top-Right, Bottom-Left, Bottom-Right, Top, or Bottom. - Analog Gauge Padding — spacing (in points) between the gauge edge and the dial face for analog gauges. - Digital Gauge Padding — spacing for digital readout gauges. - Border Width — width of the border drawn around each gauge. - Border Rounding — corner radius for gauge borders. - Border Color — color picker for the gauge border color.
Behavior: - Keep Screen From Locking — prevents the screen from dimming and locking while the app is in the foreground. Useful at the helm. - Lock Gauges — disables long-press gauge editing so you can't accidentally reconfigure a gauge while underway. - Different Layouts for Portrait and Landscape (iPad only) — when on, the app maintains separate page layouts for portrait and landscape orientations. - Don't Throttle Display — disables the frame rate throttling that the app applies when running on battery. May increase battery drain. - Only When Plugged In — available when Don't Throttle is on; only disables throttling when the device is charging.
Map and Track:
- Use Device Location/Heading — segmented: Never | Always | Not In Signal K | Not At Boat. Controls whether the iOS device's GPS/compass is used for your vessel position and heading, or whether the app uses Signal K data only.
- Use Device Attitude (pitch/roll) — segmented: Never | Always | If Not In Signal K. Whether to use the device's accelerometer for pitch and roll gauges.
- Show Track — displays a track line of past positions on map gauges (requires the signalk-to-influxdb plugin and a compatible server). When enabled: Timespan (how far back to show, e.g. 1h) and Resolution (sampling interval, e.g. 1m).
- Track Color — color picker for the position track line.
- Show Course Vector — draws a line ahead of your vessel showing current course over ground. Color is configurable.
- Show AWA Vector — draws the apparent wind angle vector. Color is configurable.
- Show TWA Vector — draws the true wind angle vector. Color is configurable.
- Show Route — displays the active navigation route on map gauges. Color is configurable.
- Show Notes — shows ActiveCaptain community notes on map gauges.
Map Objects: - My Ship Size — slider controlling the size of your vessel icon on map gauges. - My Ship Transparency — slider (0–100%) for vessel icon transparency. - AIS Target Size — slider for AIS target icons. - AIS Transparency — slider for AIS icon transparency. - POI Size — slider for point-of-interest markers (ActiveCaptain, Navionics). - POI Transparency — slider for POI marker transparency.
Navionics (if Navionics SDK is active): - Mode — chart rendering mode (standard, fishing, satellite overlay, etc.). - Contour Density — density of depth contour lines. - Easy View — high-contrast chart rendering for bright sunlight. - Shallow Area — slider setting the depth threshold below which areas are highlighted as shallow. - Depth Shading — slider controlling depth shading intensity. - Depth Contours — slider controlling contour line density (or "ALL" for all contours).
ActiveCaptain: - Show On Maps — shows ActiveCaptain marina, anchorage, and hazard markers on map gauges. - Download Over Wi-Fi Only — prevents downloading ActiveCaptain data over cellular. - Disable Updates — stops the app from downloading updated ActiveCaptain data. - Login / Logout — authenticate with your Garmin/ActiveCaptain account for full access. - Force Update — manually triggers a data download. - Delete Data — removes cached ActiveCaptain data from the device. - Status fields show the last update date and your ActiveCaptain captain name and points.
Themes¶
Opens the theme list. The app ships with built-in themes (Dark, Light, and variants). Tap a theme to apply it. A theme editor lets you create custom themes by adjusting background, text, and accent colors and saving them under a name.
Layouts¶
Opens the Layout Manager where you manage your layouts and pages. See Layout Manager and Editor for full detail.
Old Layouts¶
Provides access to layouts created in an older format. If you have layouts from a previous version of the app, they appear here and can be migrated to the current format.
Notifications¶
- Enable Signal K Alarms — shows in-app alert banners for
vessels.self.notifications.*paths received over the active connection. No server plugin required. This is the primary alarm display mechanism. - Enable Local Push — enables push notifications delivered via the WilhelmSK local push provider (requires the push provider server plugin). Notifications arrive even when the app is in the background.
- Enable Remote Push — enables APNs remote push notifications (for cloud-relay scenarios; requires additional server-side configuration).
- Use V2 Notifications API — uses the Signal K v2 notifications API if the server supports it, instead of the v1
notifications.*delta path. - Device Token — read-only indicator showing whether the app has successfully registered an APNs device token (displays "Has Device Token" or "No Device Token").
Anchor¶
Opens the anchor alarm control screen. See Anchor Alarm in the Alarms section for full detail.
The settings screen also provides: - Mode — Automatic (the app calculates the anchor position from current GPS position when you tap Drop) or Manual (you enter latitude/longitude directly). - Drop Anchor — records the current position as the anchor location and activates monitoring. - Set Radius — sets the alarm radius (in your configured distance unit). - Raise Anchor — clears the anchor position and deactivates monitoring. - Rode Length — the amount of anchor chain/rope deployed (used by the server plugin to refine the alarm radius). - Anchor Depth — the water depth at the anchor location. - An embedded map shows the anchor position and current vessel position relative to the alarm radius.
Units¶
Sets the display unit for each measurement category. Changes apply globally to all gauges.
| Category | Options |
|---|---|
| Long Distance | Nautical miles, Statute miles, Kilometers |
| Short Distance | Feet, Meters |
| Wind Speed | Knots, mph, km/h, m/s |
| Speed | Knots, mph, km/h |
| Depth | Feet, Meters, Fathoms |
| Fuel / Volume | Gallons, Liters |
| Temperature | Fahrenheit, Celsius |
| Engine Pressure | PSI, Bar, kPa |
| Atmospheric Pressure | inHg, hPa, mbar |
| Position | Degrees/Minutes/Seconds, Decimal Degrees |
| Rate of Turn | Degrees/min, Degrees/sec |
| Flow Rate | Gallons/hour, Liters/hour |
| Fuel Economy | mpg, L/100km |
| Energy | kWh, Joules |
Today / Widget Editor¶
Opens the widget editor for the iOS Today widget (legacy) and for configuring which gauges appear in WidgetKit home screen widgets. Drag gauges to reorder them, or tap a gauge entry to choose a different gauge type or SignalK path.
Help / Documentation¶
Opens this documentation inside the app. WilhelmSK can show the docs from either of two sources:
- SignalK Server — served by the signalk-wilhelmsk-docs plugin running on the server you're connected to. This works even without an internet connection (handy on the water), as long as the plugin is installed.
- GitHub (web) — the public documentation site at
https://dglcinc.github.io/signalk-wilhelmsk-docs/. Always available wherever you have internet.
The first time you open Help / Documentation, you're asked to choose a source. After that, the row goes straight to the documentation using your saved choice — it does not ask again. If you picked SignalK Server but the plugin isn't installed on the connected server, WilhelmSK offers to open the web documentation instead.
To change your source later, use Documentation Source (below) — that's the only place the chooser reappears.
Documentation Source¶
Shows the documentation-source chooser directly, so you can switch between SignalK Server, GitHub (web), and None at any time. Choosing None turns off in-app documentation; Help / Documentation will then prompt you to pick a source again the next time you open it.
Share Settings¶
Exports your current app settings — connections, layout names, unit preferences, and appearance settings — as a .wsettings file shared via the system share sheet (AirDrop, Mail, Files, etc.). Recipients can import the file by opening it with WilhelmSK. Useful for transferring your configuration to a new device or sharing with a crew member.
Watch Layout (shown when Apple Watch is paired)¶
Opens the watch gauge editor. The screen shows a list of gauges configured for the Apple Watch. Drag to reorder. Tap a gauge to change its type or SignalK path. Changes sync to the watch the next time a WCSession connection is established.
Server Plugins (shown when server supports plugins)¶
Displays a list of SignalK server plugins installed on the connected server. Tap a plugin to view and edit its configuration — boolean toggles, text fields, number fields, and enum selectors, depending on the plugin's settings schema. Changes are sent to the server immediately.
Cloud / Vessel Selector (shown when multiple vessels are detected)¶
Displays a list of vessels currently visible on the Signal K network (other vessels broadcasting AIS or connected to the same server). Tap a vessel to switch the app's viewing context to that vessel — all gauges will then display that vessel's data instead of your own. The selected vessel is highlighted. Tap your own vessel to return to the default vessels.self context.
Shutdown Server (shown when signalk-server-shutdown plugin is installed)¶
Sends a shutdown command to the Signal K server after a confirmation alert. Use with caution — the server will stop running and you will lose all data until it restarts.
Sidebar: Additional Items¶
Beyond the Settings menu, the sidebar contains:
Playback (shown when signalk-to-influxdb plugin is detected) — switches the app into playback mode, replaying historical instrument data from the InfluxDB database. A playback control bar appears at the top of the screen. Tap Gauges or any other sidebar item to exit playback mode.
AR View (shown on supported devices) — opens an augmented reality overlay that displays instrument data overlaid on the device camera view.
iPad-Specific Features¶
Split View and Slide Over¶
WilhelmSK runs in Split View and Slide Over alongside other apps. When the app is in a compact window (Slide Over or a narrow Split View column), it automatically switches to a single-column layout optimized for the reduced space. Full-size layouts are restored when the window expands.
External Display¶
On iPads with Stage Manager enabled, you can move the WilhelmSK window to an external monitor or connected display. The app resizes to fill the available window.
Orientation¶
The iPad layout adapts to both portrait and landscape. Gauge grids reflow when orientation changes so content remains visible without manual adjustment.
WidgetKit Widgets¶
WilhelmSK provides home screen and lock screen widgets so you can glance at instrument data without opening the app. Widgets read from the app's shared data store, which the app updates while it's running.
Available Widgets¶
| Widget | What it shows |
|---|---|
| Gauge | A single analog or digital gauge (speed, depth, heading, etc.) |
| Battery | Battery voltage and charge state |
| Generic Gauge | Any SignalK path you configure |
| Switch | State of a switch or relay |
| Multi-Switch | State of multiple switches |
On iOS 18 and later, WilhelmSK also provides Controls that appear in Control Center:
- Anchor drop / raise / lock radius
- Autopilot tack and heading
- Switch and multi-switch toggles
- Stereo control
Adding Widgets¶
Long-press the home screen to enter jiggle mode, then tap + and search for "Wilhelm". Choose a widget and size, then tap Add Widget. Tap the widget to configure which gauge or path it displays.
Update Frequency¶
Widgets update on a schedule (approximately every minute while the app is in the foreground and has fresh data). iOS may throttle updates based on battery level and usage patterns, so a widget reading may be up to a few minutes behind the live app display. Widgets are not a substitute for the live gauge view during active navigation — open the app for real-time data.
Controls (iOS 18+) respond immediately when tapped because they send a command directly to the app's shared data, not through a widget timeline.
Push Notifications¶
WilhelmSK can receive push notifications for SignalK alarm conditions — anchor drag, depth threshold, battery low, custom path alarms, and any vessels.self.notifications.* path published by your server.
How It Works¶
The app connects to a UPN (Universal Push Notifications) provider — a lightweight server process running alongside your SignalK server. When the server raises an alarm notification, the UPN provider forwards it to your device via Apple Push Notification service (APNs), so you receive the alert even when the app is in the background or your device is asleep.
Server Plugin Required¶
Push notifications require the WilhelmSK UPN server plugin installed on your SignalK server. See Server Plugins for the full dependency table and setup link.
Setup Steps¶
- Install the UPN server plugin on your SignalK server.
- In WilhelmSK, go to Settings → Notifications.
- Enable Local Push Notifications and enter the UPN server's host address and port.
- Grant notification permission when iOS prompts you.
The app registers your device token with the UPN server automatically. If the connection drops, the app retries with exponential backoff (10 seconds, then 5 minutes, then 25 minutes).
Notification Settings¶
In Settings → Notifications you can independently enable or disable:
- SignalK Alarms — in-app alert banners for
notifications.*paths (no server plugin required) - Local Push — UPN server push (requires plugin, works when app is backgrounded)
- Remote Push — APNs remote notifications (for future cloud-relay support)
What Triggers a Notification¶
Any SignalK vessels.self.notifications.* path can produce an alert. Common triggers:
- Anchor alarm (
notifications.navigation.anchor) - Depth alarm (
notifications.environment.depth.*) - Server-configured threshold alarms on any path
- Custom alarms from server-side plugins
The alarm indicator in the app's top bar lights up for any active unacknowledged alarm. Open the alarm panel to acknowledge or silence individual alarms.
Shortcuts and Siri¶
WilhelmSK exposes its core actions to Apple's Shortcuts app, so you can trigger them from a Control Center button, an Automation, the Share Sheet, or by voice through Siri — without opening the app. These features require a SignalK connection and the signalk-wilhelmsk-plugin on the server; they don't work with the non-SignalK connection types.
Available actions¶
Build shortcuts in the Shortcuts app from any of these WilhelmSK actions:
- Set a Multi Switch — choose a state on a multi-position switch (e.g. set a Victron inverter to On, Charge Only, etc.)
- Flip a Switch — turn a switch on or off
- Toggle a Switch — flip a switch to its opposite state
- Launch WilhelmSK — open the app
- Drop / Set / Raise Anchor — control the anchor alarm
- Control a Fusion stereo — power, source, transport, volume
- Send a PUT to any path — write a value to any SignalK path
- Get the value of a path — read the current value of any SignalK path
- Control an autopilot — set state and heading, or advance to the next waypoint
Because these are standard Shortcuts actions, you can drop them into Control Center, attach them to Automations (time, location, NFC tag, etc.), or run them from your Home Screen.
Siri commands¶
WilhelmSK ships built-in Siri phrases that work as soon as the app is installed:
- "Drop the anchor in WilhelmSK"
- "Raise the anchor in WilhelmSK"
- "Set the anchor in WilhelmSK"
- "Tack to port in WilhelmSK"
- "Tack to starboard in WilhelmSK"
- "Toggle the [switch display name] in WilhelmSK"
- "Turn the autopilot ten degrees to port in WilhelmSK"
- "Turn the autopilot one degree to starboard in WilhelmSK"
Tip: if you create your own shortcut and give it a custom name, Siri runs it by that name — so you can drop the "in WilhelmSK" suffix and say something shorter and more natural.
watchOS¶
WilhelmSK includes a native Apple Watch app for glancing at instrument data from your wrist. It shows the same gauge types as the iPhone — wind, speed, depth, battery, switches, autopilot — but on a compact watch face.
Requirements¶
- Apple Watch paired to an iPhone running WilhelmSK
- watchOS 9 or later (the SwiftUI watch app)
- The iPhone must be awake and within Bluetooth or Wi-Fi range when the watch app starts or needs to refresh data
The watch app communicates with the iPhone via Watch Connectivity (WCSession). It does not have its own independent network connection to the SignalK server — all data flows through the phone.
Initial Setup¶
Install the watch app from the Watch app on iPhone (look for WilhelmSK in the Available Apps section). Once installed, the watch app opens and sends a request to the phone for the current connection and gauge configuration.
The phone must be awake and reachable when the watch app first launches. If the phone is asleep or out of range, the watch displays a spinner and waits. Once the phone responds, the gauge layout is pushed to the watch and data starts flowing.
If you see the message "Please configure gauges in WilhelmSK Settings → Watch Layout", the phone has not sent a gauge configuration yet. Open WilhelmSK on the iPhone and set up the Watch Layout (see below).
Configuring Watch Gauges¶
Watch gauges are configured from the iPhone, not from the watch itself.
In WilhelmSK on iPhone, go to Settings → Watch Layout. The Watch Layout screen has three sections:
| Section | Behavior |
|---|---|
| Normal | The default set of gauges shown when you open the watch app |
| Swipe Up | The gauge set shown when you swipe up on the watch face |
| Swipe Down | The gauge set shown when you swipe down on the watch face |
Tap any section to add or remove gauges. Once you save, the phone pushes the new configuration to the watch automatically.
Available Gauge Types¶
The watch supports a subset of gauge types — those that fit on a small display and update meaningfully at the watch's refresh rate:
| Gauge | Description |
|---|---|
| Graphic Gauge | A single value with digital, circle, or analog display style |
| Watch Grid | Up to 6 small readings on one screen (good for a combined overview) |
| Switch Gauge | On/off state of a single switch or relay |
| Switch Bank | State of a group of switches |
| Multi-Switch | Multiple switches with toggle controls |
| Anchor Gauge | Current anchor position and radius |
| Anchor Alarm Control | Drop, raise, and lock-radius controls |
| Electrical Overview | Battery bank summary |
| Autopilot Control | Engage/disengage and heading adjust |
Update Rate¶
The watch polls for new data on a ~2-second interval (configurable from iPhone settings). Each tick the watch app requests fresh values from the phone, which in turn pulls from the active connection.
The watch face includes a freshness indicator — a small animated circle that changes color as data ages. If the indicator stops animating, the phone is no longer sending updates (it may be asleep, out of range, or the connection dropped).
When you background the watch app or lower your wrist, the polling timer pauses. It resumes when you raise your wrist and the app returns to the foreground.
Complications and Widgets¶
The watch app supports WidgetKit-based watch complications for the watch face. These display a single gauge reading in a corner, inline, or modular complication slot.
Complications update on the WidgetKit schedule (~15 minutes), not at the 2-second live rate. They are useful for a persistent glance at a slowly-changing value (battery charge, tank level) rather than live navigation data.
To add a complication: long-press your watch face → Edit → tap a complication slot → scroll to WilhelmSK → choose which gauge to show.
Known Quirks¶
Non-SignalK connections go stale if the phone is out of range. SignalK connections keep working independently — the watch talks to the server directly over Wi-Fi or cellular even when the phone is unreachable (see below). For non-SignalK sources, which route through the phone, moving beyond Bluetooth range while off the phone's Wi-Fi stops the updates: the freshness indicator changes color and the last-received data remains visible but frozen.
Phone must be awake for the first sync. The WCSession-based configuration push requires the phone to be active. If you open the watch app and the phone is asleep, the gauge layout may not load until the phone wakes.
Non-SignalK connections always require the phone. The watch app routes all non-SignalK data (Victron MQTT, Actisense W2K, Yacht Devices YDWG, Digital Yacht RAW, generic NMEA 0183) through the phone — it cannot speak those protocols directly. The phone must be reachable for these connections to work on the watch.
SignalK connections keep working without the phone. The watch caches the auth token and connection details it obtained from the phone on its last sync, and reuses them to reach the server on its own. As long as the watch can reach the server (same Wi-Fi, or over cellular), SignalK data keeps flowing even when the phone is out of range or unreachable — only the initial setup sync needs the phone.
Gauges¶
WilhelmSK organizes its display into layouts, pages, and gauges — each layer letting you customize what data you see and how.
Concepts¶
Gauge — a single instrument panel: a wind dial, a depth readout, a tank indicator, a map. Each gauge subscribes to one or more SignalK paths and updates in real time.
Page — a screen that holds a grid of gauges. You swipe between pages. Each page has a layout that controls how many gauges fit (1 large, 2 side-by-side, a 2×2 grid, etc.).
Layout — a named collection of pages. You might have a "Sailing" layout with wind-heavy pages and a "Motoring" layout showing engine gauges. Switch layouts from the sidebar.
Adding and Removing Gauges¶
To change the structure of a page (add or remove slots, resize, reposition):
- Open the Page Manager and navigate to your layout templates.
- Tap a custom template to open it in template mode. If you only have pages (not templates), open a page and tap Convert To Template to create an editable copy.
- Use the + button to add a slot, − to remove the selected slot, or Add Grid to insert a grid of slots at once.
- Drag slots into position; drag from the bottom-right corner or pinch to resize.
- Tap Save.
See the Layout Manager and Editor section for a full control reference.
Changing a Gauge Type¶
Long-press any gauge in the normal live view (not the editor) to open its full settings panel. From there you can change the gauge type, the SignalK path, display options, and alarm zones. This is the primary way to configure what any given slot displays — the layout editor controls position and size only.
Full-Screen Mode¶
Double-tap any gauge to expand it to fill the page. Double-tap again (or tap Back) to return to the normal grid. Full-screen is useful for analog wind dials or charts where detail matters.
Display Modes¶
Many gauges offer both analog and digital display modes. Open a gauge's options (tap the gear icon in edit mode) to switch. Some gauges — particularly wind — also let you choose what reference (apparent vs. true vs. ground) to display.
The Generic Gauge (Any SignalK Path)¶
The Text gauge (also listed as TextGaugeConfig) displays any numeric or string value from any SignalK path. Use it for custom sensor data, non-standard NMEA paths, or any value the app doesn't have a dedicated gauge for.
To configure it:
1. Add a Text gauge to a page.
2. Tap its settings (gear icon in edit mode).
3. Enter the full SignalK path (e.g., environment.inside.thermostat.KIDS_ROOM.temperature).
4. Set the number format (e.g., %0.1f for one decimal place) and a label.
See Custom SignalK Paths for a worked example using non-marine data.
Gauge Reference¶
The tables below list all gauge categories and types, a short description of what each shows, and their primary SignalK paths. Paths marked with * are instance wildcards — configure the specific instance (e.g., propulsion.0 or propulsion.port) in the gauge settings.
Wind¶
| Gauge | Displays | SignalK Path(s) |
|---|---|---|
| AWA | Apparent wind angle on a wind dial | environment.wind.angleApparent |
| AWA & COG | Apparent wind angle with a course-over-ground reference needle | environment.wind.angleApparent + navigation.courseOverGroundTrue |
| AWA & TWA | Apparent and true wind angle together on one dial | environment.wind.angleApparent + environment.wind.angleTrueWater |
| AWA & GWA | Apparent and ground wind angle together on one dial | environment.wind.angleApparent + environment.wind.angleTrueGround |
| AWA CH (Close Hauled) | Apparent wind angle on a ±60° close-hauled scale (port red / starboard green) | environment.wind.angleApparent |
| AWS | Apparent wind speed | environment.wind.speedApparent |
| TWA | True wind angle on a wind dial | environment.wind.angleTrueWater |
| TWS | True wind speed | environment.wind.speedTrue |
| TWD | True wind direction (compass) | environment.wind.directionTrue |
| GWA | Ground wind angle on a wind dial | environment.wind.angleTrueGround |
| GWS | Ground (over-ground) wind speed | environment.wind.speedOverGround |
| GWD | Ground wind direction (compass) | environment.wind.directionGround |
| TWA or GWA | True wind angle when available, otherwise ground wind angle | environment.wind.angleTrueWater (falls back to angleTrueGround) |
| Drift | Current speed (drift) | environment.current.drift |
| Set | Current direction (set) | environment.current.setTrue |
Navigation¶
| Gauge | Displays | SignalK Path(s) |
|---|---|---|
| SOG | Speed over ground — analog dial with digital readout | navigation.speedOverGround |
| COG | Course over ground on a compass-rose dial | navigation.courseOverGroundTrue |
| Speed | Boat speed through the water (paddle/log) — analog dial | navigation.speedThroughWater |
| Heading | True heading on a compass-rose dial | navigation.headingTrue |
| Magnetic Heading | Magnetic heading on a compass-rose dial | navigation.headingMagnetic |
| Head Wind COG | Triple-needle compass: true heading + apparent-wind direction + course over ground on one dial | navigation.headingTrue + environment.wind.angleApparent + navigation.courseOverGroundTrue |
| MHDG Wind COG | Same triple-needle compass referenced to magnetic heading (magnetic COG derived from variation) | navigation.headingMagnetic + environment.wind.angleApparent + navigation.courseOverGroundTrue + navigation.magneticVariation |
| Position | Latitude / longitude readout tile | navigation.position |
| XTE | Cross-track error off the active leg — digital readout | navigation.courseGreatCircle.crossTrackError |
| DTW | Distance to the next waypoint — digital readout | navigation.courseGreatCircle.nextPoint.distance |
| Time To Wypt | Time to the next waypoint (HH:mm:ss), read directly from the server | navigation.courseGreatCircle.nextPoint.timeToGo |
| ETA Time | Estimated time of arrival (clock time) | navigation.courseGreatCircle.activeRoute.estimatedTimeOfArrival |
| Rate Of Turn | Rate of turn on an analog dial (±40, red→green zones) | navigation.rateOfTurn |
| Pitch | Vessel pitch on an inclinometer dial (±90°) | navigation.attitude → pitch |
| Roll | Vessel roll / heel on an inclinometer dial (±90°) | navigation.attitude → roll |
| Yaw | Vessel yaw on a compass-rose dial | navigation.attitude → yaw |
| GNSS Date/Time | Date and time readout (configurable format) | navigation.datetime |
Depth & Environment¶
| Gauge | Displays | SignalK Path(s) |
|---|---|---|
| Depth | Water depth below the surface — digital/bar, with a draft marker | environment.depth.belowSurface (falls back to belowTransducer + surfaceToTransducer) |
| Water Temperature | Sea-water temperature on an analog dial | environment.water.temperature |
| Atmospheric Pressure | Barometric pressure on an analog dial (scale auto-adjusts to inHg/mbar/mmHg) | environment.outside.pressure |
| Tide | Next high / low / current tide heights and times | environment.tide |
To show outside air temperature, point a Water Temperature or generic gauge at environment.outside.temperature — there is no separate air-temperature gauge type.
Engine & Propulsion¶
| Gauge | Displays | SignalK Path(s) |
|---|---|---|
| RPM | Engine speed on an analog dial (with x1/x10/x100 scaling) | propulsion.*.revolutions |
| Coolant Temperature | Engine coolant temperature on an analog dial | propulsion.*.temperature |
| Oil Pressure | Engine oil pressure on an analog dial | propulsion.*.oilPressure |
| Oil Temperature | Engine oil temperature on an analog dial | propulsion.*.oilTemperature |
| Alternator Voltage | Alternator output voltage on a dial | propulsion.*.alternatorVoltage |
| Engine Runtime | Cumulative engine hours — digital HH:mm:ss | propulsion.*.runTime |
| Fuel Rate | Instantaneous fuel-consumption rate — digital/bar | propulsion.*.fuel.rate |
| Engine Load | Engine load as a percentage dial | propulsion.*.engineLoad |
| Engine Torque | Engine torque as a percentage dial | propulsion.*.engineTorque |
| Fuel Economy | Distance per volume (or, inverted, volume per distance) read from the server | propulsion.*.fuel.economy |
* is a placeholder for the engine instance — the gauge auto-resolves port, 0, 1, or starboard; set a specific instance in gauge settings.
Tanks¶
| Gauge | Displays | SignalK Path(s) |
|---|---|---|
| Fuel | Fuel-tank level on an analog percentage dial | tanks.fuel.*.currentLevel |
| Fresh Water | Fresh-water-tank level on an analog dial | tanks.freshWater.*.currentLevel |
| Black Water | Black-water (sewage) tank level on an analog dial | tanks.blackWater.*.currentLevel |
| Waste Water | Grey / waste-water tank level on an analog dial | tanks.wasteWater.*.currentLevel |
| WavyTank | Any tank level, shown as an animated "wavy" liquid fill | any tanks.*.currentLevel |
The Fuel / Fresh / Black / Waste Water gauges are all the same gauge class pre-pointed at a different tank path; point any of them at another tanks.*.currentLevel instance in gauge settings.
Both percentage and volume (liters/gallons) display modes are available. Configure the tank instance number in gauge settings.
Electrical¶
| Gauge | Displays | SignalK Path(s) |
|---|---|---|
| Starter Battery | Battery voltage on an analog dial (10–16 V, low/ok/over zones) | electrical.batteries.1.voltage |
| House Battery | Battery voltage on an analog dial (10–16 V) | electrical.batteries.0.voltage |
| Voltage 24V | Battery voltage on a 24 V-range dial (20–32 V) | a *.voltage path (no preset) |
| Generic Amps | Current (charge / discharge) in amps — digital/bar/dial | any current path, e.g. electrical.batteries.*.current |
| Generic Watts | Power in watts — digital/bar/dial | any power path, e.g. electrical.batteries.*.power |
| Generic Charge | Battery charge in amp-hours — digital/dial | any charge (Ah) path |
| Generic kWh | Stored energy in kWh — digital/bar/dial | any energy path |
| Charger Mode | Charger state (bulk / absorption / float) as a colored status bar | a charger-mode string path, e.g. electrical.chargers.*.chargingMode |
| Battery Overview | Multi-value tile: state of charge, voltage, current, time remaining, plus charger and solar | multi-path summary |
| Electrical Overview | Large multi-section tile: battery, inverter, charger, solar, alternator, DC loads, grid and system state | multi-path summary |
The "Generic" gauges (Amps, Watts, Charge, kWh) and Voltage 24V ship with a unit and scale but no preset path — assign the SignalK path yourself when you add the gauge. For battery state of charge (%), point a Percent or generic gauge at electrical.batteries.*.capacity.stateOfCharge. ("Starter Battery" is battery instance 1 and "House Battery" is instance 0 by default; change the instance in gauge settings.)
Switches and Relays¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| SwitchBank | Control. A bank/grid of switches from one switches subtree — toggle each on/off, with optional dimming and colored (hue / saturation / Kelvin) lighting | electrical.switches.{bank} subtree |
| SwitchGauge | Control. A single switch/relay you toggle on/off; also supports dimming and color | electrical.switches.{bank}.{switch}.state |
| SwitchLED | Control + indicator. A switch you toggle, paired with a separate LED that reflects a different feedback path | a switch .state path + a separate LED .state path |
| LEDGauge | Read-only. A single LED status indicator with configurable on/off colors | any state path, e.g. electrical.switches.*.state |
| LEDBank | Read-only. A bank/grid of LED status indicators from one subtree | electrical.switches.{bank} subtree |
| MultiSwitch | Control. A single multi-state selector — choose one of several values; includes an accidental-tap guard | a multi-state path (with possibleValues) |
| Slider | Control. A dimmer/level slider for a continuous (ratio or ranged) value | any PUT-able ratio/ranged path |
The Switch / MultiSwitch / Slider gauges write* values back to the server (the path must support PUT); LED gauges only display.
Autopilot¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| AutoPilotControl | Control. Full autopilot panel — engage/standby, auto/wind modes, adjust heading, tack/confirm; issues commands via the vendor-agnostic autopilot server plugin. Can select among multiple pilots | steering.autopilot.state, steering.autopilot.target.* (commands via plugin) |
| RudderAngle | Read-only analog dial of rudder angle (±45°, green→red zones) | steering.rudderAngle |
AIS¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| AIS Targets | Sortable table of nearby vessels — toggle columns for type, distance, speed, COG and state | vessels.* (+ own navigation.position) |
AIS targets also appear as an overlay on the Map, Google Map and Navionics gauges. (The picker may list a second "AISTargetsTable" entry; it is a leftover with no gauge behind it and does nothing — use AIS Targets.)
Maps and Charts¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| Map (Apple Maps) | Embedded Apple Maps with own-vessel position, anchor circle, COG/heading and next waypoint; map/satellite/hybrid and course/head/north-up modes | navigation.position (+ anchor, COG, heading, next waypoint) |
| Google Map | The same position map rendered with Google Maps | navigation.position (+ anchor, COG, heading, next waypoint) |
| Navionics | Embedded Navionics marine chart — requires a Navionics chart subscription | navigation.position (+ anchor, COG, heading, next waypoint) |
| Freeboard-SK | Embedded web view of the server's Freeboard-SK chartplotter — requires the Freeboard-SK webapp on the server | server URL (not a SignalK path) |
| Raymarine MFD | Embedded view of a Raymarine multifunction display — requires a compatible Raymarine MFD on the network | MFD on the network (not a SignalK path) |
Camera¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| IP Camera | Embedded live video from an IP camera — HTTP/MJPEG or RTSP (decoded with FFmpeg) | camera URL (not a SignalK path) |
Fusion Stereo¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| Fusion | Control. Full Fusion stereo: power, source select, transport (play/pause/next/prev) and per-zone volume; sends commands through the Fusion server plugin | entertainment.device.fusion1.* (commands via plugin) |
Utility¶
| Gauge | Notes | SignalK Path(s) / Source |
|---|---|---|
| Text | Generic digital readout for any SignalK path — numeric or string. The base for many built-in text gauges | any path |
| Ratio | Generic dial that shows a decimal-ratio (0–1) value as a percentage | any 0–1 ratio path |
| Percent | Generic dial for a value already in 0–100 percent (no ratio conversion) | any percent path |
| Volume | Volume readout (m³ source converted to your units), with bar/analog styles | any volume (m³) path |
| Image | Static image tile | none — static |
| Label | Static text-label tile | none — static |
| Web | Embedded web view | a URL (not a SignalK path) |
| Empty | Blank placeholder slot | none |
| GaugeStack | Stacks multiple gauges vertically in one slot | none — container |
| Scrollable | A scrollable/paged container holding several gauges | none — container |
| Time HHMM | Formats a path value as HH:mm — seconds-of-day or an ISO-8601 time (12/24-hour), not a wall clock |
any time / seconds path |
| Thermostat | Thermostat control — reads temperature, state, setting and mode, and writes the setpoint and mode back to the server (for compatible HVAC systems) | environment.inside.* — temperature, state, thermostat.setting, thermostat.mode |
| StaticThermostat | Read-only thermostat — displays temperature, relative humidity, state and setpoint. Unlike Thermostat, it does not write changes back and adds a humidity reading. Use this for an HVAC source that publishes humidity or that you don't want to control from the app |
environment.inside.* — temperature, humidity, state, setting |
| WatchGridGauge | Multi-value grid tile (default 6 cells); primarily used on Apple Watch layouts | the paths of its child gauges |
| AnchorAlarmControl | Control. Drop/raise the anchor and set the alarm radius (works with the anchor-alarm server plugin) | navigation.anchor.* |
| Anchor | Read-only anchor view — position, drag distance and track | navigation.anchor.*, navigation.headingTrue |
| Tide | Tide height and prediction | environment.tide |
| MultiGauge | Composite tile combining several readings in one slot | multiple (composite) |
Alarms and Notifications¶
WilhelmSK surfaces two kinds of alarms: server-side notifications raised by the SignalK server (or its plugins) and delivered to the app over the live data stream, and local zone alarms configured per gauge on the device. The anchor alarm is a special case that bridges both: the app sends a drop-anchor command to a server plugin, and the plugin raises a SignalK notification when the vessel drifts.
The Alarm Indicator¶
The alarm button in the top bar gives you a persistent status summary:
- Red — one or more unacknowledged alarms at
alarmoremergencyseverity are active. - Yellow — one or more unacknowledged warnings at
warnoralertseverity are active. - Gray / dimmed — no active alarms, or all notifications have been acknowledged.
When alarms are active, a scrolling marquee next to the button shows the vessel name and the notification message. If multiple alarms are active, it cycles through them every four seconds. The background color of the marquee matches the severity: yellow for warnings, red for alarms.
Tapping the alarm button opens the Alerts list, which shows every active notification with its path, message, and timestamp. From there you can act on each alarm individually.
Server-Side Alarms¶
SignalK represents alarms and notifications as values under the notifications.* path hierarchy. Any value published there — by the server itself, by an instrument, or by a plugin — appears in WilhelmSK as a notification.
Severity levels¶
| State | Meaning | Indicator color |
|---|---|---|
normal |
Condition resolved | None |
alert |
Advisory — attention needed | Yellow |
warn / warning |
Warning — action may be needed | Yellow |
alarm |
Alarm — action required | Red |
emergency |
Critical — immediate action required | Red |
Responding to a notification¶
In the Alerts list, each notification offers up to three actions depending on what the server allows:
- Silence — suppresses audio for this notification without acknowledging it. On servers that support the SignalK v2 notifications API, the silence is sent back to the server (
POST /notifications/{id}/silence). On v1 servers, the method list is cleared locally. - Acknowledge — marks the notification as seen. On v2 servers this is confirmed server-side (
POST /notifications/{id}/acknowledge). Acknowledged notifications no longer count toward the alarm indicator. - Clear — removes the notification entirely. On v2 servers this sends
DELETE /notifications/{id}; on v1 servers the state is set tonormal.
Which actions appear depends on the notification's canSilence, canAcknowledge, and canClear flags sent by the server.
Security access requests¶
If the SignalK server is configured with access control, connection requests from new clients appear in the Alerts list as notifications.security.accessRequest.* notifications. You can approve or deny them directly from the app.
Local Zone Alarms¶
Each gauge in WilhelmSK can have zones — value ranges that map to a severity state. Zones are stored as SignalK metadata (path.meta.zones) and are applied whenever the gauge value falls within the configured range.
What zones do¶
When a value enters a zone, the gauge changes color to reflect the severity (green for normal, yellow for warn/alert, red for alarm/emergency). If the zone's method includes sound, the app also plays an alert tone.
Configuring zones¶
- Long-press a gauge to open the gauge editor.
- Navigate to the Zones section.
- Tap the + button to add a zone, or tap an existing zone to edit it.
Each zone has:
- State — the severity level (normal, alert, warn, alarm, emergency).
- Lower / Upper — the value range (in the gauge's configured units). The zone matches when lower ≤ value < upper.
- Message — the text shown in the alarm indicator when this zone is active.
- Label — a short label for the zone (e.g., "Low Voltage", "Overheat").
- Visual / Sound — whether the zone triggers a color change, an audio alert, or both.
Zones you configure in the app are stored locally and applied on top of any metadata the server provides.
Anchor Alarm¶
The anchor alarm lets you drop a virtual anchor and receive an alert if the vessel drifts beyond a set radius.
Requires the server plugin: The anchor alarm depends on the
@signalk/signalk-anchoralarm-pluginrunning on your SignalK server. Without it, the drop/raise commands have no effect.
Setting the anchor¶
- Open the Anchor Alarm panel (available as a gauge type, or from the top bar anchor button if shown).
- Set the alarm radius in meters — the maximum distance the vessel is allowed to drift from the drop point.
- Tap Drop Anchor. The app sends the current GPS position and radius to the server plugin, which begins monitoring.
The anchor button in the top bar changes color to confirm: - Green — anchor is down with a valid radius set. - Yellow — anchor is down but no radius has been configured. - Text color — no anchor is currently dropped.
When the alarm fires¶
If the vessel drifts beyond the configured radius, the server plugin raises a notifications.anchoralarm.* notification. This appears in the alarm indicator (red) and the marquee text, and triggers a local alert on the device.
Raising the anchor¶
Tap Raise Anchor in the anchor panel. This sends a raise command to the plugin, which clears the anchor position and stops monitoring.
Push Notifications¶
Push notifications let the app alert you even when it is in the background or the device screen is off.
Requires a server plugin. Remote push notifications require the WilhelmSK push plugin running on your SignalK server. See Server Plugins for setup instructions and the plugin repository link.
How it works¶
WilhelmSK includes a Local Push Provider (a Network Extension) that maintains a persistent TCP connection to the SignalK server. When a notification arrives on that connection, the provider delivers it as a local iOS/iPadOS notification — even if the main app is suspended.
For remote push (when the device is off the same network as the server), the server plugin routes notifications through AWS SNS using the device token registered by the app at launch.
Enabling push notifications¶
- Go to Settings → Notifications in the app.
- Enable SignalK Alarms (master toggle for all server notifications — on by default).
- Enable Local Push to receive notifications when the app is backgrounded on the same network.
- Enable Remote Push to receive notifications away from the boat network (requires the server-side push plugin).
If local push notifications are not being delivered, check that iOS has granted the app notification permission (Settings → WilhelmSK → Notifications).
Reconnection behavior¶
The local push provider uses exponential backoff if the server connection drops: it retries after 10 seconds, then 60 seconds, then every 5 minutes. Notifications sent while disconnected are not replayed.
Server Plugins¶
Several advanced WilhelmSK features require companion plugins running on your SignalK server. This page lists every optional dependency, what it unlocks, and where to find it.
Base requirement: All plugins listed here run on signalk-server-node. See the canonical setup guide for installing signalk-server-node and adding plugins.
Plugin dependency matrix¶
| Feature | Plugin name | Plugin repo | Notes |
|---|---|---|---|
| Watch, widgets, Shortcuts & Siri | signalk-wilhelmsk-plugin |
sbender9/signalk-wilhelmsk-plugin | Required for the Apple Watch app, Watch & Home Screen widgets, and the Shortcuts/Siri integration |
| Server-side alarms | (built into the server) | — | Configure zones on the server; it writes notifications.* which WilhelmSK reads and displays. The old signalk-zones plugin is deprecated |
| Push notifications | signalk-push-notifications |
sbender9/signalk-push-notifications | Local push via persistent TCP; remote push via AWS SNS when off-network |
| Anchor alarm | signalk-anchoralarm-plugin |
sbender9/signalk-anchoralarm-plugin | Monitors vessel position and raises notifications.anchoralarm.* on drift |
| Autopilot control | @signalk/signalk-autopilot |
SignalK/signalk-autopilot | Vendor-agnostic autopilot control panel: mode, heading/wind target, tack/gybe, advance waypoint |
| Fusion stereo control | signalk-fusion-stereo |
sbender9/signalk-fusion-stereo | Required for the Fusion stereo gauge: power, source, transport, per-zone volume |
| AIS targets | (none required) | — | AIS data flows through SignalK natively as vessels.*; no plugin needed |
| Track overlay | (a Tracks-API plugin) | — | Requires a plugin that provides the Signal K Tracks API; WilhelmSK reads the track from it |
| Freeboard-SK integration | freeboard-sk |
SignalK/freeboard-sk | Requires the Freeboard-SK plugin installed on the server; WilhelmSK links to it |
| In-app documentation (offline) | signalk-wilhelmsk-docs |
dglcinc/signalk-wilhelmsk-docs | Serves this documentation site from the server so Help / Documentation works without an internet connection |
Feature details¶
Watch, widgets, Shortcuts & Siri (signalk-wilhelmsk-plugin)¶
The signalk-wilhelmsk-plugin adds the server-side support WilhelmSK's companion features need. It's required for the Apple Watch app, the Watch and Home Screen widgets, and the Shortcuts and Siri integration — without it, those features can't talk to the server. Install it from the SignalK App Store (server admin panel → App Store) and restart the server; there's nothing to configure. These features all require a SignalK connection.
Server-side alarms¶
SignalK zone alarms let the server watch any data path and emit a notification when a value crosses a threshold. WilhelmSK monitors notifications.* and surfaces active alarms in the alarm indicator at the top of the screen. Without server-side zones you only see alarms that originate from connected instruments themselves.
Zones are now built into signalk-server — no plugin required. Configure one or more zones on a path (e.g. environment.water.temperature) in the server's data/metadata settings, and the next time the value crosses the boundary WilhelmSK will alert. (The standalone signalk-zones plugin that older setups used is deprecated.)
Push notifications (signalk-push-notifications)¶
Push notifications deliver alarm alerts to your iPhone even when the WilhelmSK app is backgrounded or the phone is off the boat's Wi-Fi. The plugin handles two delivery paths:
- Local push — a persistent TCP connection from the app to the server; works on the same network, no internet required.
- Remote push — routes through AWS SNS; requires a brief one-time setup linking your Apple ID to the plugin's AWS backend.
See the setup guide for the AWS configuration steps.
Anchor alarm (signalk-anchoralarm-plugin)¶
The anchor alarm gauge in WilhelmSK shows a Drop Anchor button that sets a GPS fix and radius. The plugin watches the vessel's position and publishes a notifications.anchoralarm.* notification when the vessel drifts beyond the set radius. WilhelmSK picks that notification up through the standard alarm path, so you see and hear the alert even if the app is backgrounded (combined with the push notifications plugin).
Autopilot control (@signalk/signalk-autopilot)¶
WilhelmSK's autopilot control panel drives the vendor-agnostic @signalk/signalk-autopilot plugin, which presents one common SignalK autopilot interface regardless of the underlying brand (Raymarine, and others supported by the plugin and its providers). It exposes engage/standby, auto and wind modes, heading/wind target adjustment, tack/gybe, and advance-waypoint to the app. Without it the autopilot gauge is read-only — it displays current pilot state but cannot send commands.
Fusion stereo control (signalk-fusion-stereo)¶
The Fusion stereo gauge requires the signalk-fusion-stereo plugin on the server. With your Fusion head unit on the NMEA 2000 network and the plugin installed, WilhelmSK can control power, source selection, transport (play/pause/next/prev), and per-zone volume. Install it from the SignalK App Store and restart the server.
AIS targets¶
AIS vessel data arrives through your AIS receiver, is decoded by SignalK, and appears in the vessels.* tree. WilhelmSK reads that data directly. No plugin is required.
Track overlay¶
To draw your vessel's track on the chart, WilhelmSK reads the Signal K Tracks API, which is supplied by a server plugin. Install any plugin that provides the Tracks API and WilhelmSK will pick the track up automatically — we don't recommend a specific one here, since the available options change. Without such a plugin there is no track to overlay.
Freeboard-SK integration¶
Freeboard-SK is a browser-based chart plotter that runs alongside signalk-server. It's delivered as a server plugin — install Freeboard-SK from the SignalK App Store, and WilhelmSK can then open a Freeboard-SK session in the in-app browser using the server's address.
In-app documentation (signalk-wilhelmsk-docs)¶
WilhelmSK can show this documentation inside the app, served straight from your own SignalK server. The signalk-wilhelmsk-docs plugin bundles the entire documentation site and serves it at /signalk-wilhelmsk-docs/, so Help / Documentation works even when the boat has no internet connection — the same guide you're reading now, available offline at the helm.
Install WilhelmSK Documentation from the SignalK App Store (server admin panel → App Store) and restart the server. There are no configuration options; the docs are available as soon as the plugin is installed. In the app, set Settings → Documentation Source to SignalK Server to use it. If the plugin isn't installed on the server you're connected to, WilhelmSK falls back to the public web documentation instead.
Unlike the feature plugins above, this one doesn't unlock any in-app capability — it just makes the help content available locally. The web documentation is always there as a fallback, so the plugin is optional but handy for boats that are often offline.
Installing plugins¶
- Open the SignalK server admin panel (typically
http://<server-ip>:3000). - Go to App Store and search for the plugin by name.
- Install and restart the server.
- Open the plugin's settings page and configure as needed.
- Reconnect WilhelmSK — the new feature should appear automatically.
For a complete walkthrough of first-time server and plugin setup, see the wilhelmsk-node-server-setup guide.
Custom SignalK Paths¶
WilhelmSK is not limited to marine data. Any value available on a SignalK server can be displayed using a generic gauge — temperature sensors, relay states, pressure readings, power meters, or anything else a plugin pushes into the SignalK data model.
This guide covers how to configure gauges for arbitrary SignalK paths and walks through a complete non-marine example: a home HVAC and utility monitoring system.
SignalK Path Naming Conventions¶
Every value in SignalK is identified by a dot-separated path. The structure follows a defined hierarchy:
Examples:
- environment.inside.thermostat.KIDS_ROOM.temperature — temperature at a named thermostat
- electrical.batteries.house.voltage — house battery bank voltage
- hvac.boiler.sentry.gasInputValue — gas input to a boiler (non-marine)
The top-level segment is conventionally the vessel context (vessels.self is implied). Paths from the SignalK specification are standardised. Custom paths — created by plugins or third-party integrations — can use any naming, as long as they are unique within the server.
Units and Metadata¶
SignalK paths carry metadata alongside their values. The meta.units field tells clients what unit the value is in (e.g. K for Kelvin, m/s for speed). WilhelmSK uses this metadata to convert and display values in the units you select in preferences.
If a custom path does not include metadata, the app displays the raw value. For temperature paths, the server is expected to publish in Kelvin; the app converts to °C or °F based on your unit preference.
Gauge Types for Custom Paths¶
Several built-in gauge types accept arbitrary paths:
| Gauge type | Best for | Notes |
|---|---|---|
Generic Number (TextGaugeConfig) |
Any numeric or string value | Configurable format string; no unit conversion |
| WaterTempGauge | Temperature values in Kelvin | Converts to °C/°F per preferences; works for any temperature path |
| WattsGauge | Power in watts | Works for any *.power or *.watts path |
| SwitchBank | Binary on/off relay states | Reads a path prefix; each child key becomes a labelled switch |
The Generic Number gauge is the most flexible: it displays any value at any path, formatted as a number or string. Use the specialised gauges (WaterTempGauge, WattsGauge) when you want unit conversion built in.
Configuring a Generic Number Gauge¶
In the app (Layout Editor)¶
- Open the layout editor by long-pressing any gauge slot.
- Tap the slot you want to configure.
- Scroll to Generic in the gauge picker and select Generic Number.
- Enter the full SignalK path (e.g.
electrical.ac.arduinoThermPSI.psi). - Set the display title and numeric format.
- Tap Done.
In a .wlyt layout file¶
Layout files are JSON. A Generic Number gauge entry looks like this:
"12": {
"className": "TextGaugeConfig",
"path": "electrical.ac.arduinoThermPSI.psi",
"title": "Hydronic PSI",
"valueLabelFormat": "%0.0f",
"integerDigits": 0,
"decimalDigits": 0,
"defaultTitle": "Generic Number"
}
Key fields:
| Field | Description |
|---|---|
className |
Always "TextGaugeConfig" for the generic gauge |
path |
Full SignalK path to the value |
title |
Label shown on the gauge face |
valueLabelFormat |
Printf-style format: "%0.0f" for integers, "%0.2f" for two decimal places, "%s" for strings |
integerDigits |
Digits before the decimal point (for layout sizing) |
decimalDigits |
Digits after the decimal point |
Worked Example: Home HVAC and Utility Monitoring with pivac¶
pivac is a Raspberry Pi-based data collection system that monitors a residential HVAC system, thermostats, boiler, and electrical circuits and publishes all readings to a local SignalK server. WilhelmSK connects to that server and displays the home data exactly as it would display boat data — no special configuration needed on the app side.
What pivac publishes¶
| SignalK path | What it represents |
|---|---|
environment.inside.thermostat.KIDS_ROOM.temperature |
Thermostat temperature reading, Kids Room |
environment.inside.thermostat.KIDS_ROOM.humidity |
Thermostat humidity reading, Kids Room |
environment.inside.hvac.IN.temperature.value |
Air handler supply air temperature |
environment.inside.hvac.OUT.temperature.value |
Return air temperature |
hvac.boiler.sentry.waterTemp |
Hydronic boiler water temperature |
electrical.ac.arduinoThermPSI.psi |
Hydronic system pressure (PSI) |
electrical.ac.arduinoPSI.psi |
Potable domestic hot water pressure (PSI) |
hvac.boiler.sentry.gasInputValue |
Gas input to boiler (BTU or flow rate) |
hvac.boiler.sentry.status |
Boiler control status (string) |
electrical.ac.switch.utility |
Relay bank for utility control switches |
Layout configuration¶
The pivac WilhelmSK layout (wilhelmsk/iphone.wlyt) demonstrates mixing gauge types on a single page:
Thermostat gauges read temperature, state, and setpoint from related paths under a shared prefix. There are two classes: Thermostat, which also reads mode and writes the setpoint/mode back to the server, and StaticThermostat, which additionally reads humidity and writes the setpoint but has no mode control. Because pivac publishes a per-room humidity reading, this layout uses StaticThermostat:
"10": {
"className": "StaticThermostat",
"title": "Kids Room",
"temperature": "environment.inside.thermostat.KIDS_ROOM.temperature",
"humidity": "environment.inside.thermostat.KIDS_ROOM.humidity",
"state": "environment.inside.thermostat.KIDS_ROOM.state",
"setting": "environment.inside.setting"
}
Temperature gauges use WaterTempGauge for any Kelvin temperature path — including non-marine ones like HVAC supply air:
"2": {
"className": "WaterTempGauge",
"path": "environment.inside.hvac.IN.temperature.value",
"title": "HVAC In",
"type": 1
}
Generic numeric gauges display PSI readings, gas input, and other values without a dedicated gauge class:
"12": {
"className": "TextGaugeConfig",
"path": "electrical.ac.arduinoThermPSI.psi",
"title": "Hydronic PSI",
"valueLabelFormat": "%0.0f",
"integerDigits": 0,
"decimalDigits": 0,
"defaultTitle": "Generic Number"
},
"16": {
"className": "TextGaugeConfig",
"path": "hvac.boiler.sentry.status",
"title": "Boiler Status",
"valueLabelFormat": "%s",
"integerDigits": 0,
"decimalDigits": 0,
"defaultTitle": "Generic Number"
}
Switch banks map a path prefix to a row of toggle controls:
"11": {
"className": "SwitchBank",
"path": "electrical.ac.switch.utility",
"title": "Control Relays"
}
Result¶
A single WilhelmSK layout page shows room temperatures, HVAC duct temperatures, boiler status, system pressures, and relay controls — all pulled from a home automation system with no changes to the app. The SignalK protocol is the only interface.
Tips for Working with Custom Paths¶
Browse available paths first. Open the SignalK server's data browser (usually at http://<server>:3000/signalk/v1/api/vessels/self) to see what paths are available and what format the values take before configuring gauges.
Match the value type to the format string. Numeric values need %0.Nf (where N is decimal places); string values need %s. Mixing these causes the gauge to show nothing or display incorrectly.
Temperature paths expect Kelvin. If you use WaterTempGauge for a custom temperature path, the server must publish the value in Kelvin (as the SignalK spec requires). If your plugin publishes in Celsius or Fahrenheit, use TextGaugeConfig with a %0.1f format instead and set the title to include the unit.
Use SwitchBank for grouped binary states. If your plugin publishes several on/off values under a common path prefix (e.g. electrical.ac.switch.utility.pump, electrical.ac.switch.utility.fan), a single SwitchBank gauge pointing at the prefix (electrical.ac.switch.utility) will display all of them as labelled toggles.