Preparing search index...

    Unit Preferences

    This guide describes the unit preferences mechanism in Signal K Server.

    The Unit Preferences system simplifies client development by managing unit preferences centrally, on the server across all unit preferences aware client applications. As a developer, you don't need to maintain user preference settings in your application and can use the settings and conversion formulas provided by the server.

    When you fetch metadata for a path (e.g., vessels.self.navigation.speedOverGround), the server checks the active unit preferences and includes a displayUnits object in the meta data.

    Request the metadata for any path:

    GET /signalk/v1/api/vessels/self/navigation/speedOverGround/meta

    Response Example:

    {
    "units": "m/s",
    "description": "Speed over ground",
    "displayName": "SOG",
    "displayUnits": {
    "category": "speed",
    "targetUnit": "kn",
    "formula": "value * 1.94384",
    "inverseFormula": "value / 1.94384",
    "symbol": "kn",
    "displayFormat": "0.0"
    }
    }

    The displayUnits object provides everything you need to display the value:

    • category: The unit category this path belongs to (e.g., "speed", "depth", "temperature").
    • targetUnit: The unit the user wants to see (e.g., "kn" for knots).
    • formula: A Math.js expression to convert the raw SI value to the target unit. The variable value represents the input.
    • inverseFormula: A Math.js expression to convert back from the display unit to SI (useful for user input).
    • symbol: The symbol to display next to the value.
    • displayFormat: (Optional) A format pattern for consistency (e.g., "0.0" for one decimal place).

    When subscribing to the WebSocket stream, add sendMeta=all to receive metadata once for each path (sent with the first delta for that path, and again only if it changes):

    const ws = new WebSocket('ws://localhost:3000/signalk/v1/stream?subscribe=none')

    ws.onopen = () => {
    ws.send(
    JSON.stringify({
    context: 'vessels.self',
    subscribe: [
    {
    path: 'navigation.speedOverGround',
    policy: 'instant',
    sendMeta: 'all'
    }
    ]
    })
    )
    }

    Delta with Metadata:

    {
    "context": "vessels.urn:mrn:signalk:uuid:...",
    "updates": [
    {
    "values": [
    {
    "path": "navigation.speedOverGround",
    "value": 5.14,
    "meta": {
    "units": "m/s",
    "description": "Speed over ground",
    "displayUnits": {
    "category": "speed",
    "targetUnit": "kn",
    "formula": "value * 1.94384",
    "inverseFormula": "value / 1.94384",
    "symbol": "kn",
    "displayFormat": "0.0"
    }
    }
    }
    ]
    }
    ]
    }

    Using sendMeta=all eliminates the need for separate REST calls to fetch metadata.

    1. Get the value and metadata - Either subscribe to the WebSocket stream with sendMeta=all (recommended), or poll the REST API and fetch metadata separately.
    2. Check for displayUnits - If present, the user has unit preferences configured.
    3. Convert the value - Evaluate the formula expression with the SI value as value.
    4. Display the result - Show the converted value with the provided symbol and displayFormat.

    This ensures that if the user changes their preferences (e.g., from "Knots" to "m/s" or "km/h") on the server, your application automatically reflects those changes without any code updates.

    The unit preferences system exposes the following REST API endpoints:

    Method Endpoint Description
    GET /signalk/v1/unitpreferences/config Get the current configuration
    PUT /signalk/v1/unitpreferences/config Update the configuration
    GET /signalk/v1/unitpreferences/categories Get all unit categories (merged standard + custom)
    GET /signalk/v1/unitpreferences/definitions Get all unit definitions (merged standard + custom)
    GET /signalk/v1/unitpreferences/custom-definitions Get custom unit definitions only
    PUT /signalk/v1/unitpreferences/custom-definitions Update custom unit definitions
    GET /signalk/v1/unitpreferences/custom-categories Get custom category mappings only
    PUT /signalk/v1/unitpreferences/custom-categories Update custom category mappings
    GET /signalk/v1/unitpreferences/presets List all available presets (built-in and custom)
    GET /signalk/v1/unitpreferences/presets/:name Get a specific preset by name
    PUT /signalk/v1/unitpreferences/presets/custom/:name Create or update a custom preset
    DELETE /signalk/v1/unitpreferences/presets/custom/:name Delete a custom preset
    GET /signalk/v1/unitpreferences/active Get the currently active preset
    GET /signalk/v1/unitpreferences/default-categories Get the default category mappings

    Signal K Server allows you to define your preferred units for different categories of data (e.g., Speed, Depth, Temperature) centrally. These settings are applied across all compatible apps and dashboards.

    You can configure your unit preferences in the Signal K Server Admin UI.

    1. Open the Server Admin interface.
    2. Navigate to Server > Configuration > Settings.
    3. Scroll down to the Unit Preferences section.

    The simplest way to configure units is to select a Preset. A preset is a collection of unit preferences for all standard categories.

    Available presets:

    • Metric: km/h, kilometers, meters, Celsius, liters.
    • Imperial (US): mph, miles, feet, Fahrenheit, US gallons.
    • Imperial (UK): mph, miles, feet, Celsius, UK gallons.
    • Nautical (Metric): knots, nautical miles, meters, Celsius, liters.
    • Nautical Imperial (US): knots, nautical miles, feet, Fahrenheit, US gallons.
    • Nautical Imperial (UK): knots, nautical miles, feet, Celsius, UK gallons.

    Preferences are stored per user. If you log in with your user account, your unit settings will follow you across different devices. If no user is logged in (or for anonymous users), the server's global default preset (configured by the administrator) is used.

    Advanced users can upload Custom Presets to define specific combinations of units that aren't covered by the built-in options.

    In addition to category-wide settings (e.g., "All speeds in Knots"), you can override units for specific data paths. For example, you might want Boat Speed in Knots but Wind Speed in Meters/Second.

    These overrides are typically managed by editing the server configuration. When a specific path has an override, it takes precedence over the general category setting in your active preset.


    Unit categories are the mechanism that allows the server to apply unit preferences to a wide range of data paths without needing configuration for every single path.

    1. Categorization: Every numeric Signal K path is assigned to a Category (e.g., speed, temperature, depth). This assignment is defined in the server's default configuration but can be customized.
    2. Base Unit: The category defines the Base Unit (usually the SI unit) that the raw data is expected to be in. For example, the speed category expects m/s.
    3. Target Unit: Your active Preset defines a Target Unit for each category. For example, your preset might map the speed category to kn (knots).
    4. Conversion: When data is requested, the server looks up the path's category, finds the target unit from your preset, and provides the conversion formula.

    This system means that if you set your speed preference to Knots, it applies to Boat Speeds, Wind Speeds and any other path assigned to the speed category.

    The following categories are available by default:

    • speed: Speed measurements (Base: m/s). Examples: navigation.speedOverGround, environment.wind.speedTrue.
    • distance: Longer distances (Base: m). Examples: navigation.log, navigation.courseRhumbline.nextPoint.distance.
    • depth: Vertical distances/depths (Base: m). Examples: environment.depth.belowTransducer, environment.depth.belowKeel.
    • length: Dimensions of the vessel or objects (Base: m). Examples: design.length.overall, design.airHeight.
    • temperature: Temperature readings (Base: K). Examples: environment.outside.temperature, propulsion.*.temperature.
    • pressure: Pressure readings (Base: Pa). Examples: environment.outside.pressure, propulsion.*.oilPressure.
    • angle: Angles (Base: rad). Examples: environment.wind.angleApparent, navigation.headingMagnetic.
    • angularVelocity: Rate of turn (Base: rad/s). Examples: navigation.rateOfTurn.
    • volume: Liquid volumes (Base: m³). Examples: tanks.*.currentLevel.
    • volumeRate: Flow rates (Base: m³/s). Examples: propulsion.*.fuel.rate.
    • mass: Weight/Mass (Base: kg).
    • electrical:
      • voltage (Base: V). Examples: electrical.batteries.*.voltage.
      • current (Base: A). Examples: electrical.batteries.*.current.
      • charge (Base: C). Examples: electrical.batteries.*.capacity.stateOfCharge.
      • power (Base: W).
      • energy (Base: J).
    • frequency: (Base: Hz). Examples: propulsion.*.revolutions.
    • time: Durations (Base: s).
    • percentage: Ratios and levels (Base: ratio 0-1). Examples: tanks.*.currentLevel, electrical.batteries.*.capacity.stateOfCharge.

    Additional categories include dateTime, epoch for time representations, and unitless/boolean for data that doesn't require conversion.