UNPKG

signalk-server

Version:

An implementation of a [Signal K](http://signalk.org) server for boats.

195 lines (158 loc) 6.51 kB
# Unit Preferences System This directory contains all configuration files for the SignalK unit preferences system. ## Directory Structure ``` unitpreferences/ ├── config.json # Active preset configuration ├── categories.json # Category SI unit mapping ├── default-categories.json # Default category assignments for paths ├── standard-units-definitions.json # Unit conversion formulas ├── custom-units-definitions.json # Custom unit definitions (created on demand) └── presets/ ├── metric.json # Built-in: Metric (SI) ├── imperial-us.json # Built-in: Imperial (US) ├── imperial-uk.json # Built-in: Imperial (UK) └── custom/ # Custom presets directory └── *.json # User-created presets ``` ## File Descriptions ### config.json Stores the currently active preset name. ```json { "activePreset": "metric" } ``` ### categories.json Maps category names to their base SI units. Used to validate that a path's units match the category. ```json { "temperature": "K", "speed": "m/s", "distance": "m", ... } ``` ### default-categories.json Maps SignalK path patterns to default categories. Used for auto-suggesting categories for paths. ```json { "environment.*.temperature": "temperature", "navigation.speedOverGround": "speed", ... } ``` ### standard-units-definitions.json Defines all unit conversions. Each SI unit has conversion formulas to display units. ```json { "K": { "conversions": { "C": { "formula": "x - 273.15", "inverseFormula": "x + 273.15", "symbol": "°C" }, "F": { "formula": "(x - 273.15) * 9/5 + 32", "inverseFormula": "(x - 32) * 5/9 + 273.15", "symbol": "°F" } } }, ... } ``` ### custom-units-definitions.json User-defined unit conversions that extend or override standard definitions. Created when users add custom conversions via the API. ### Preset Files (presets/\*.json) Each preset defines target units for all categories: ```json { "name": "metric", "displayName": "Metric System", "description": "SI units", "categories": { "temperature": { "targetUnit": "C" }, "speed": { "targetUnit": "km/h" }, "distance": { "targetUnit": "kilometer" }, ... } } ``` ## REST API Endpoints | Endpoint | Method | Description | | ---------------------------------------------------- | ------ | ------------------------------------ | | `/signalk/v1/unitpreferences/config` | GET | Get active preset config | | `/signalk/v1/unitpreferences/config` | PUT | Set active preset | | `/signalk/v1/unitpreferences/categories` | GET | Get category SI unit mapping | | `/signalk/v1/unitpreferences/definitions` | GET | Get merged unit definitions | | `/signalk/v1/unitpreferences/custom-definitions` | GET | Get custom unit definitions | | `/signalk/v1/unitpreferences/custom-definitions` | PUT | Save custom unit definitions | | `/signalk/v1/unitpreferences/custom-categories` | GET | Get custom categories | | `/signalk/v1/unitpreferences/custom-categories` | PUT | Save custom categories | | `/signalk/v1/unitpreferences/presets` | GET | List all presets (built-in + custom) | | `/signalk/v1/unitpreferences/presets/:name` | GET | Get preset details | | `/signalk/v1/unitpreferences/presets/custom/:name` | PUT | Create/update custom preset | | `/signalk/v1/unitpreferences/presets/custom/:name` | DELETE | Delete custom preset | | `/signalk/v1/unitpreferences/presets/custom/upload` | POST | Upload custom preset file (admin) | | `/signalk/v1/unitpreferences/active` | GET | Get fully resolved active preset | | `/signalk/v1/unitpreferences/default-categories` | GET | Get default category mappings | | `/signalk/v1/unitpreferences/default-category/:path` | GET | Get default category for a path | ## WebSocket Stream When connecting to the WebSocket stream with `sendMeta=all`, metadata includes full `displayUnits` with conversion formulas: ``` ws://localhost:3000/signalk/v1/stream?subscribe=none&sendMeta=all ``` Subscribe to a path: ```json { "context": "vessels.self", "subscribe": [{ "path": "environment.wind.speedApparent" }] } ``` Metadata response includes enhanced `displayUnits`: ```json { "context": "vessels.urn:mrn:imo:mmsi:123456789", "updates": [ { "timestamp": "2024-01-15T12:00:00.000Z", "meta": [ { "path": "environment.wind.speedApparent", "value": { "units": "m/s", "description": "Apparent wind speed", "displayUnits": { "category": "speed", "targetUnit": "kn", "formula": "value * 1.94384", "inverseFormula": "value * 0.514444", "symbol": "kn", "displayFormat": "0.0" } } } ] } ] } ``` The `displayUnits` object provides everything needed to convert and display values: - **category** - The unit category (e.g., "speed", "temperature") - **targetUnit** - The display unit from the active preset - **formula** - Math.js expression to convert from SI to display unit (use `value` as variable) - **inverseFormula** - Convert from display unit back to SI - **symbol** - Display symbol (e.g., "kn", "°C") - **displayFormat** - Optional format string ## How It Works 1. **Path metadata** stores `displayUnits.category` (e.g., "temperature") 2. **Active preset** determines target unit for each category (e.g., temperature "C") 3. **Unit definitions** provide conversion formula from SI unit to target unit 4. **REST API / WebSocket** enhance metadata with full conversion info 5. **Data Browser / Apps** use the formula to convert and display values ## Path Override Priority 1. **Path-specific override** - `displayUnits.targetUnit` on path metadata 2. **Preset default** - Target unit from active preset for the category 3. **SI unit** - Raw value in base SI unit if no conversion defined