Boat project

Sea & Sea web dashboard

A browser-based live dashboard connecting directly to Signal K via WebSocket. Four pages: tanks, power, tides and environment. Designed to run full-screen on a phone mounted at the helm.

What it does

This is a set of plain HTML/CSS/JavaScript files that run in any browser on the boat's local network. There is no backend, no server-side rendering, no build step — just static files. The browser connects directly to the Signal K WebSocket stream and updates the display in real time. Tide data comes from a local Node.js tide service running on the Raspberry Pi alongside Signal K. The primary target device is a Nothing Phone 3a Pro mounted at the helm, but it works on any modern browser.

File structure

FilePurpose
dashboard.htmlMain dashboard page. Four page containers (tanks, power, tides, environment), a fixed bottom navigation bar, and all live data elements. Load this in the browser.
script.jsAll application logic: WebSocket connection to Signal K, tide API fetch, update functions for every data element on every page, page navigation handlers.
style.cssDark theme mobile-first CSS. No scroll on any page. Fixed bottom nav bar. Visual tank gauges via CSS height/fill.
config.jsConnection configuration — Signal K WebSocket URL and tide service URL. Edit this file to point at your own setup.
index.htmlSimple redirect/landing page to dashboard.html

Configuration — the only file you need to edit

All connection settings are in config.js:

window.APP_CONFIG = {
  signalKUrl: 'ws://10.1.1.12:3000/signalk/v1/stream',
  tideUrl: 'http://10.1.1.12:3123/tide'
};

Change 10.1.1.12 to the IP address of your Signal K server. Change port 3000 if your Signal K runs on a different port. The tideUrl points to a small local Node.js service that serves tide data from the Admiralty API — replace with any URL that returns tide JSON in the expected format, or remove tide functionality if not needed.

Per-device overrides are supported: set window.APP_CONFIG before config.js loads to override the defaults for a specific device without editing the shared file.

Signal K paths consumed

PageSignal K pathDisplay usage
Tankstanks.water.port.currentLevelPort water tank gauge and percentage
Tankstanks.water.centre.currentLevelCentre water tank gauge
Tankstanks.water.starboard.currentLevelStarboard water tank gauge
Tankstanks.fuel.port.currentLevelPort fuel tank gauge
Tankstanks.fuel.starboard.currentLevelStarboard fuel tank gauge
Tanksenvironment.inside.temperature.port_water_tankPort tank compartment sensor
Tanksenvironment.inside.humidity.port_water_tankPort tank compartment humidity
Powerelectrical.batteries.bmv712.voltageHouse battery voltage
Powerelectrical.batteries.starter.voltageStarter/generator battery voltage
Powerelectrical.solar.MPPTport.panelPowerPort solar panel power (W)
Powerelectrical.solar.MPPTstarboard.panelPowerStarboard solar panel power (W)
Powerelectrical.solar.MPPTport.yieldTodayPort solar yield today (Wh)
Powerelectrical.solar.MPPTstarboard.yieldTodayStarboard solar yield today (Wh)
Tidesenvironment.depth.belowKeelCurrent depth
Tidesenvironment.water.temperatureWater temperature (K → °C)

How the WebSocket connection works

On page load, script.js opens a WebSocket connection to the Signal K stream URL from config.js. Signal K immediately begins sending all data updates as JSON messages. The script maintains a data store object and updates it on every message received. Each page has update functions that read from this store and update the DOM.

Automatic reconnection is handled — if the WebSocket drops (e.g. Signal K restarts), the script waits a few seconds and reconnects. A connection status indicator shows the current state.

Tide data is fetched via HTTP from the local tide service on page load and every 10 minutes. The tide service (running on the Raspberry Pi) calls the UK Admiralty API and caches the result, so the dashboard doesn't need internet access or an API key directly.

Deploying to your own boat

  1. Copy the four files (dashboard.html, script.js, style.css, config.js) to any web server accessible on your boat network, or simply open dashboard.html directly as a file (file://...) — the WebSocket connection works either way as long as the browser can reach the Signal K server.
  2. Edit config.js to point at your Signal K server IP and port.
  3. If you don't have the local tide service, you can remove the tide fetch call from script.js or replace tideUrl with any compatible endpoint.
  4. Open dashboard.html in the browser, add it to the home screen for a full-screen experience on mobile.

The dashboard works entirely offline once loaded — it only needs network access to reach the Signal K server, which is on the boat's local WiFi. No internet connection is required during normal use.

Adding your own data points

The pattern throughout script.js is consistent: add a new path to the WebSocket message handler (where paths are matched and values stored), then add an update call to the relevant page's update function, and add the corresponding HTML element in dashboard.html. The architecture document in the repo (ARCHITECTURE.md) lists all current and planned data points with their Signal K paths.

The environment page is currently a placeholder — it is intended for additional sensors such as cabin temperature, barometric pressure and wind, as more ESP32 devices are added to the boat.