UNPKG

signalk-server

Version:

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

636 lines (606 loc) 266 kB
<!DOCTYPE HTML> <html lang="en" class="sidebar-visible no-js light"> <head> <!-- Book generated using mdBook --> <meta charset="UTF-8"> <title>Signal K Server Documentation</title> <meta name="robots" content="noindex" /> <!-- Custom HTML head --> <meta name="description" content="A Guide for users and developers."> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="theme-color" content="#ffffff" /> <link rel="shortcut icon" href="favicon.png"> <link rel="stylesheet" href="css/variables.css"> <link rel="stylesheet" href="css/general.css"> <link rel="stylesheet" href="css/chrome.css"> <link rel="stylesheet" href="css/print.css" media="print"> <!-- Fonts --> <link rel="stylesheet" href="FontAwesome/css/font-awesome.css"> <link rel="stylesheet" href="fonts/fonts.css"> <!-- Highlight.js Stylesheets --> <link rel="stylesheet" href="highlight.css"> <link rel="stylesheet" href="tomorrow-night.css"> <link rel="stylesheet" href="ayu-highlight.css"> <!-- Custom theme stylesheets --> </head> <body> <div id="body-container"> <!-- Provide site root to javascript --> <script> var path_to_root = ""; var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light"; </script> <!-- Work around some values being stored in localStorage wrapped in quotes --> <script> try { var theme = localStorage.getItem('mdbook-theme'); var sidebar = localStorage.getItem('mdbook-sidebar'); if (theme.startsWith('"') && theme.endsWith('"')) { localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1)); } if (sidebar.startsWith('"') && sidebar.endsWith('"')) { localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1)); } } catch (e) { } </script> <!-- Set the theme before any content is loaded, prevents flash --> <script> var theme; try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } if (theme === null || theme === undefined) { theme = default_theme; } var html = document.querySelector('html'); html.classList.remove('no-js') html.classList.remove('light') html.classList.add(theme); html.classList.add('js'); </script> <input type="checkbox" id="sidebar-toggle-anchor" class="hidden"> <!-- Hide / unhide sidebar before it is displayed --> <script> var html = document.querySelector('html'); var sidebar = null; var sidebar_toggle = document.getElementById("sidebar-toggle-anchor"); if (document.body.clientWidth >= 1080) { try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { } sidebar = sidebar || 'visible'; } else { sidebar = 'hidden'; } sidebar_toggle.checked = sidebar === 'visible'; html.classList.remove('sidebar-visible'); html.classList.add("sidebar-" + sidebar); </script> <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <div class="sidebar-scrollbox"> <a href="/" style="width:155px;height:30px;background-image:url(/signal-k-logo-image-text.svg);display:inline-block;background-repeat:no-repeat;background-position:center center;background-size:150px auto;"></a> <ol class="chapter"><li class="chapter-item expanded affix "><a href="index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Getting Started</li><li class="chapter-item expanded "><a href="installation/install.html"><strong aria-hidden="true">1.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="installation/raspberry_pi_installation.html"><strong aria-hidden="true">1.1.</strong> Installing on Raspberry Pi</a></li><li class="chapter-item expanded "><a href="installation/updating.html"><strong aria-hidden="true">1.2.</strong> Updating your installation</a></li><li class="chapter-item expanded "><a href="installation/command_line.html"><strong aria-hidden="true">1.3.</strong> Runtime environment & options</a></li></ol></li><li class="chapter-item expanded "><a href="security.html"><strong aria-hidden="true">2.</strong> Security</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="setup/generating_tokens.html"><strong aria-hidden="true">2.1.</strong> Generating tokens</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/configuration.html"><strong aria-hidden="true">3.</strong> Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="setup/seatalk/seatalk.html"><strong aria-hidden="true">3.1.</strong> Seatalk Connections</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Feature How Tos</li><li class="chapter-item expanded "><a href="features/anchoralarm/anchoralarm.html"><strong aria-hidden="true">4.</strong> Anchor Alarm</a></li><li class="chapter-item expanded "><a href="features/navdataserver/navdataserver.html"><strong aria-hidden="true">5.</strong> NMEA0183 Server</a></li><li class="chapter-item expanded "><a href="features/datalogging/datalogging.html"><strong aria-hidden="true">6.</strong> Data Logging</a></li><li class="chapter-item expanded affix "><li class="part-title">Support</li><li class="chapter-item expanded "><a href="support/help.html"><strong aria-hidden="true">7.</strong> Help & Support</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="support/faq.html"><strong aria-hidden="true">7.1.</strong> FAQs</a></li></ol></li><li class="chapter-item expanded "><a href="support/sponsor.html"><strong aria-hidden="true">8.</strong> Sponsor</a></li><li class="chapter-item expanded affix "><li class="part-title">Develop</li><li class="chapter-item expanded "><a href="develop/developer_notes.html"><strong aria-hidden="true">9.</strong> Notes for Developers</a></li><li class="chapter-item expanded "><a href="whats_new.html"><strong aria-hidden="true">10.</strong> What's New in V2</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="breaking_changes.html"><strong aria-hidden="true">10.1.</strong> Changes & Deprecations</a></li></ol></li><li class="chapter-item expanded "><a href="develop/webapps.html"><strong aria-hidden="true">11.</strong> WebApps</a></li><li class="chapter-item expanded "><a href="develop/plugins/server_plugin.html"><strong aria-hidden="true">12.</strong> Plugins</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="develop/plugins/deltas.html"><strong aria-hidden="true">12.1.</strong> Processing Data</a></li><li class="chapter-item expanded "><a href="develop/plugins/server_plugin_api.html"><strong aria-hidden="true">12.2.</strong> Server API</a></li><li class="chapter-item expanded "><a href="develop/plugins/resource_provider_plugins.html"><strong aria-hidden="true">12.3.</strong> Resource Providers</a></li><li class="chapter-item expanded "><a href="develop/rest-api/course_calculations.html"><strong aria-hidden="true">12.4.</strong> Course Providers</a></li><li class="chapter-item expanded "><a href="develop/plugins/autopilot_provider_plugins.html"><strong aria-hidden="true">12.5.</strong> Autopilot Providers</a></li></ol></li><li class="chapter-item expanded "><a href="develop/plugins/publishing.html"><strong aria-hidden="true">13.</strong> Publishing to the AppStore</a></li><li class="chapter-item expanded "><a href="develop/rest-api/open_api.html"><strong aria-hidden="true">14.</strong> REST APIs</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="develop/rest-api/course_api.html"><strong aria-hidden="true">14.1.</strong> Course API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="develop/rest-api/course_calculations.html"><strong aria-hidden="true">14.1.1.</strong> Course Calculations</a></li></ol></li><li class="chapter-item expanded "><a href="develop/rest-api/resources_api.html"><strong aria-hidden="true">14.2.</strong> Resources API</a></li><li class="chapter-item expanded "><a href="develop/rest-api/notifications_api.html"><strong aria-hidden="true">14.3.</strong> Notifications API</a></li><li class="chapter-item expanded "><a href="develop/rest-api/autopilot_api.html"><strong aria-hidden="true">14.4.</strong> Autopilot API</a></li><li class="chapter-item expanded "><a href="develop/rest-api/anchor_api.html"><strong aria-hidden="true">14.5.</strong> Anchor API</a></li></ol></li><li class="chapter-item expanded "><a href="develop/contributing.html"><strong aria-hidden="true">15.</strong> Contribute</a></li></ol> </div> <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div> </nav> <!-- Track and set sidebar scroll position --> <script> var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox'); sidebarScrollbox.addEventListener('click', function(e) { if (e.target.tagName === 'A') { sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop); } }, { passive: true }); var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll'); sessionStorage.removeItem('sidebar-scroll'); if (sidebarScrollTop) { // preserve sidebar scroll position when navigating via links within sidebar sidebarScrollbox.scrollTop = sidebarScrollTop; } else { // scroll sidebar to current active section when navigating via "next/previous chapter" buttons var activeSection = document.querySelector('#sidebar .active'); if (activeSection) { activeSection.scrollIntoView({ block: 'center' }); } } </script> <div id="page-wrapper" class="page-wrapper"> <div class="page"> <div id="menu-bar-hover-placeholder"></div> <div id="menu-bar" class="menu-bar sticky"> <div class="left-buttons"> <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar"> <i class="fa fa-bars"></i> </label> <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list"> <i class="fa fa-paint-brush"></i> </button> <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu"> <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li> <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li> <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li> <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li> <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li> </ul> <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar"> <i class="fa fa-search"></i> </button> </div> <h1 class="menu-title">Signal K Server Documentation</h1> <div class="right-buttons"> <a href="print.html" title="Print this book" aria-label="Print this book"> <i id="print-button" class="fa fa-print"></i> </a> </div> </div> <div id="search-wrapper" class="hidden"> <form id="searchbar-outer" class="searchbar-outer"> <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header"> </form> <div id="searchresults-outer" class="searchresults-outer hidden"> <div id="searchresults-header" class="searchresults-header"></div> <ul id="searchresults"> </ul> </div> </div> <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM --> <script> document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible'); document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible'); Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) { link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1); }); </script> <div id="content" class="content"> <main> <img src="./img/logo.png" width="75" > <h2 id="introduction"><a class="header" href="#introduction">Introduction</a></h2> <p>Signal K Server is software designed to be deployed on a vessel to act as a central hub which:</p> <ol> <li>Collects data from devices and sensors on board</li> <li>Aggregates and exposes it using the <em><a href="https://signalk.org/specification/latest/">Signal K Data Standard</a></em></li> <li>Exposes the collected data via REST APIs and websocket protocols over a standard WiFi, LAN or Internet connection.</li> </ol> <p>Through implementation of the <em><a href="https://signalk.org/specification/latest/">Signal K Data Standard</a></em>, it enables data exchange between NMEA0183, NMEA2000 and other marine protocols facilitating two way communication between the various onboard systems. In addition it can also act as data hub for additional sensors ensuring their data appears within the single data model. <em>(Visit the <a href="https://github.com/SignalK/SensESP">Signal K SensESP project</a> for <a href="https://en.wikipedia.org/wiki/ESP32">ESP32</a> for details.).</em></p> <p>Data is made available to client applications / connections in JSON format making it widely accessible to Apps on phone / tablet devices and web applications.</p> <p>Signal K Server is also extensible, providing a plugin framework which allows developers to create solutions that integrate and extend its capabilities. These solutions can be published to <strong>npmjs</strong> and installed via the <strong>App Store</strong> in the server's web-based user interface.</p> <p><img src="img/server_only.svg" alt="Server only setup" /></p> <div style="break-before: page; page-break-before: always;"></div><h1 id="getting-started"><a class="header" href="#getting-started">Getting Started</a></h1> <p>Signal K Server is a NodeJS application which can be installed on a variety of devices and operating systems.</p> <p>It is available for installation via:</p> <ol> <li>NPM package</li> <li>Docker image</li> <li>GitHub repository</li> </ol> <p>See the relevant section below for instructions based on your target system.</p> <h3 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites:</a></h3> <p><em>Signal K server requires NodeJs version &gt;= 18 be installed on the target system prior to commencing installation.</em></p> <hr /> <h2 id="raspberry-pi-installation"><a class="header" href="#raspberry-pi-installation">Raspberry Pi Installation</a></h2> <p><a href="installation/raspberry_pi_installation.html">Install Signal K Server on Raspberry Pi</a> outlines the process for getting Signal K Server up and running <em>(including supporting services)</em> on Raspberry Pi OS.</p> <hr /> <h2 id="using-docker"><a class="header" href="#using-docker">Using Docker</a></h2> <p>Signal K Server is available as a Docker image on <em>Docker Hub</em> and <em>cr.signalk.io/signalk/signalk-server</em>.</p> <p>To simply run a Signal K Server with some sample data on a device with docker installed, enter the following into a terminal:</p> <pre><code class="language-shell">docker run -it --rm --publish 3000:3000 signalk/signalk-server </code></pre> <p>This will start an instance of Signal K Server on port 3000 which you can then access via the web based Admin UI by pointing your web browser at <code>http://localhost:3000</code>.</p> <p>If you are wanting to use docker to deploy Signal K Server on your vessel you will need to:</p> <ol> <li>Specify a location to persist the server's configuration so it is not lost between restarts</li> <li>Run the instance as a background process</li> </ol> <p><em>Example: Run as background process and store server configuration in the current folder:</em></p> <pre><code class="language-shell">docker run -d --init --name signalk-server -p 3000:3000 -v $(pwd):/home/node/.signalk signalk/signalk-server </code></pre> <p>You are ready to now <strong><a href="installation/../setup/configuration.html">configure</a></strong> your installation and connect data from devices on your boat.</p> <hr /> <h2 id="installation-via-npm"><a class="header" href="#installation-via-npm">Installation via NPM</a></h2> <p>Signal K Server can be installed directly using NPM.</p> <p><em>Windows:</em></p> <ul> <li>See <a href="installation/install.html#installing-on-windows">Installing on Windows</a> below.</li> </ul> <p><em>Linux / macOS:</em></p> <pre><code class="language-shell">sudo npm install -g signalk-server </code></pre> <p>Once installation is complete, enter the following in a terminal window, to generate a settings file and configure the server to start automatically:</p> <pre><code class="language-shell">sudo signalk-server-setup </code></pre> <p>If you choose not to use <code>signalk-server-setup</code> you can start the server by entering the following in a terminal window:</p> <pre><code class="language-shell">signalk-server </code></pre> <hr /> <h2 id="installing-on-windows"><a class="header" href="#installing-on-windows">Installing on Windows</a></h2> <p>Please use the <a href="https://github.com/SignalK/signalk-server-windows">Signal K installer for Windows</a> to install Signal K Server on a Windows device.</p> <hr /> <h2 id="install-using-git"><a class="header" href="#install-using-git">Install using Git</a></h2> <p>Installation from the GitHub repository is useful when developing plugins and components.</p> <p>To do this enter the following commands in a terminal window:</p> <pre><code class="language-shell"># Copy the files to your device git clone https://github.com/SignalK/signalk-server.git # change to the folder containing the downloaded files cd signalk-server # install the dependencies npm install # build all packages in the repository npm run build:all </code></pre> <p>To start Signal K Server with a sample configuration file and some sample data, enter the following into a terminal: <em>To use NMEA0183 sample data:</em></p> <pre><code class="language-shell">bin/nmea-from-file </code></pre> <p><em>To use NMEA2000 sample data:</em></p> <pre><code class="language-shell">bin/n2k-from-file </code></pre> <p>The server will start playing back data from the specified sample file that can be viewed using the <em>Data Browser</em> in the Admin UI <em>(<code>http://localhost:3000</code>)</em> or via REST API / websocket connection.</p> <hr /> <div style="break-before: page; page-break-before: always;"></div><h1 id="installation-on-raspberry-pi"><a class="header" href="#installation-on-raspberry-pi">Installation on Raspberry Pi</a></h1> <p>Installation of Signal K server can consists of the following steps:</p> <ol> <li>Install the tools and libraries required to run the Signal K server (the dependencies)</li> <li>Install a Signal K Server to process the Signal K data</li> <li>Run the Setup script.</li> </ol> <p><em><strong>Important:</strong> If you are updating a Signal K server installation, especially if upgrading an installed version &lt;= 1.40.0, <a href="installation/./updating.html">please check here first</a>.</em></p> <h3 id="prerequisites-1"><a class="header" href="#prerequisites-1">Prerequisites:</a></h3> <p>Raspberry Pi OS is installed on the device.</p> <p>For instructions on how to install the operating system <a href="https://www.raspberrypi.org/documentation/computers/getting-started.html#setting-up-your-raspberry-pi">can be found here.</a>.</p> <p><em>Note: It is also possible to perform a "headless install" using <code>Raspberry Pi OS Lite</code> since the GUI for Signal K is browser based.</em></p> <p>Once the OS installation has been completed, you are ready to commence.</p> <hr /> <h2 id="install-the-dependencies"><a class="header" href="#install-the-dependencies">Install the Dependencies</a></h2> <ol> <li> <p>Log in to the RPi Desktop and open a terminal.</p> </li> <li> <p>Update the list of install packages.</p> <pre><code>sudo apt update </code></pre> </li> <li> <p>Install NodeJS 18 and npm.</p> <p>Follow <a href="https://github.com/nodesource/distributions#installation-instructions">instructions for Ubuntu and Debian based distributions like Raspberry Pi OS at NodeSource Distributions</a>.</p> </li> <li> <p>Ensure that we're using the latest version of npm.</p> <pre><code>sudo npm install -g npm@latest </code></pre> <p>Use the following command to check the versions of NodeJS and npm installed.</p> <pre><code>node -v &amp;&amp; npm -v </code></pre> <p>Ensure the reported versions are equal to or greater than <code>v18.15.0, 9.5.0</code> respectively.</p> </li> <li> <p>Install a Bonjour (mDNS) service for Linux called Avahi, which allows Apps and other network devices to Discover the Signal K server.</p> <pre><code>sudo apt install libnss-mdns avahi-utils libavahi-compat-libdnssd-dev </code></pre> </li> </ol> <h2 id="install-signal-k-server"><a class="header" href="#install-signal-k-server">Install Signal K Server</a></h2> <pre><code>sudo npm install -g signalk-server </code></pre> <p>You can test that installation was successful by starting the server using some sample data.</p> <pre><code>signalk-server --sample-nmea0183-data </code></pre> <p>You should see the terminal output "signalk-server running at 0.0.0.0:3000" as shown below...</p> <pre><code>signalk-server --sample-nmea0183-data Using sample data from /usr/lib/node_modules/signalk-server/samples/plaka.log signalk-server running at 0.0.0.0:3000 </code></pre> <p>The Signal K Node Server is now reading and publishing sample NMEA0183 data from the specified file.</p> <p>Using a Web browser enter the following URL: <code>http://127.0.0.1:3000/signalk</code> which should display the following information indicating the server is up and running.</p> <pre><code class="language-JSON">{ "endpoints":{ "v1":{ "version":"2.0.0", "signalk-http":"http://127.0.0.1:3000/signalk/v1/api/", "signalk-ws":"ws://127.0.0.1:3000/signalk/v1/stream", "signalk-tcp":"tcp://127.0.0.1:3858" } }, "server":{ "id":"signalk-server-node", "version":"2.0.0" } } </code></pre> <h2 id="run-the-setup-script"><a class="header" href="#run-the-setup-script">Run the Setup Script</a></h2> <p>Now that you have Signal K server installed, you will want to generate a settings file for your vessel and configure your RPi to start the server automatically. To do this run the setup script by entering the following command and follow the prompts.</p> <pre><code>sudo signalk-server-setup </code></pre> <p>You can re-run this command at any time in the future to change the settings.</p> <p><em>Note: The setup script will enable security which will require you to <code>Login`` from the Admin UI. Clicking </code>Login` for the first time will prompt you to create a user and password.</em></p> <p>Signal K server will now be started automatically when your RPi boots up.</p> <p>If you want to temporarily stop the Signal K server, you can do so by entering the following commands:</p> <pre><code>sudo systemctl stop signalk.service sudo systemctl stop signalk.socket </code></pre> <p>To start Signal K server again enter the following commands:</p> <pre><code>sudo systemctl start signalk.service sudo systemctl start signalk.socket </code></pre> <p>To stop Signal K server from starting automatically enter the following commands:</p> <pre><code>sudo systemctl disable signalk.service sudo systemctl disable signalk.socket </code></pre> <p>You are ready to now <strong><a href="installation/../setup/configuration.html">configure</a></strong> your installation and connect data from devices on your boat.</p> <div style="break-before: page; page-break-before: always;"></div><h1 id="updating-your-installation"><a class="header" href="#updating-your-installation">Updating your Installation</a></h1> <p>Signal K Server is frequently updated to introduce new features and fix issues that have been reported. Sometime these updates require that NodeJS or other supporting software on your device to be upgraded to support the new functionality.</p> <p>Additionally your device's operating system are constantly evolving to address security issues as well as providing new capabilities.</p> <p>Regularly updating your installation will reduce both the volume of data download and the time taken to complete the process. Connecting your device to a network with good broadband speed before performing an update is recommended.</p> <p>Updates fall into four categories:</p> <ol> <li>Device Operating system (e.g. RaspberryPi OS)</li> <li>NodeJS / NPM</li> <li>Signal K Server</li> <li>Signal K WebApps and Plugins</li> </ol> <h2 id="update-device-operating-system"><a class="header" href="#update-device-operating-system">Update Device Operating System</a></h2> <p>Instructions will vary depending on your device but for linux based systems such as the Raspberry Pi the following instrctions are used to update the OS.</p> <p>From a terminal window enter the following commands:</p> <pre><code class="language-shell">sudo apt update sudo apt dist-upgrade </code></pre> <p>If you have not performed an update for a while these commands may take a while to complete, just be patient and make sure everything completes correctly.</p> <p>After the process has completed <code>restart</code> your device.</p> <h2 id="update-nodejs-and-npm"><a class="header" href="#update-nodejs-and-npm">Update NodeJS and NPM</a></h2> <p>To ensure the version of NodeJS on your device is supported by Signal K Server <em><a href="installation/install.html#prerequisites">(see prerequisites)</a></em>, check the installed version by entering the following in a terminal window:</p> <pre><code class="language-bash">node -v # example response v18.17.0 </code></pre> <p>If the version of NodeJS displayed is lower than the version supported by Signal K Server then you can update it with the following command:</p> <pre><code class="language-shell">sudo apt upgrade nodejs </code></pre> <p>It is also recommended to update the version of the Node Package Manager (NPM).</p> <pre><code class="language-shell">sudo npm install -g npm@latest </code></pre> <h2 id="update-signal-k-server"><a class="header" href="#update-signal-k-server">Update Signal K Server</a></h2> <p>When an update is available for Signal K Server a visual indication is displayed in the Admin UI.</p> <p><strong>Important!</strong> Before updating please ensure the version of NodeJS on your device is <a href="installation/install.html#prerequisites">supported by Signal K Server</a>.</p> <p><em><strong>If you are updating from Signal K Server version v1.40.0 or earlier please <a href="https://github.com/SignalK/signalk-server/wiki/Updating-to-Node.js-18">read this first</a> before proceeding.</strong></em></p> <p>Click on <em>Server -&gt; Update</em> to display information about the new version.</p> <p><img src="installation/../img/server_update.png" alt="server_update" /></p> <p>Click <strong>Update</strong> to start the installation.</p> <p>After the installation is complete, click <strong>Restart</strong> to launch the updated Signal K Server.</p> <h3 id="webapps-and-plugins"><a class="header" href="#webapps-and-plugins">WebApps and Plugins</a></h3> <p>After updating Signal K Server some plugins and WebApps may also need to be updated.</p> <p>The AppStore is where WebApps and Plugins can be installed, removed or updated. Those with an update available will be listed in <em>Appstore -&gt; Updates</em> in the Admin UI.</p> <p>Clicking on the <em>download cloud</em> button next to the WebApp / Plugin you wish to update.</p> <p>After all installations have been completed, click <strong>Restart</strong> to activate the updated WebApps and Plugins.</p> <div style="break-before: page; page-break-before: always;"></div><h1 id="runtime-environment--options"><a class="header" href="#runtime-environment--options">Runtime Environment &amp; Options</a></h1> <p>Signal K Server provides the following command line options and environment variables to configure your implementation.</p> <h2 id="command-line-options"><a class="header" href="#command-line-options">Command line options</a></h2> <div class="table-wrapper"><table><thead><tr><th>Option</th><th>Description</th></tr></thead><tbody> <tr><td><code>-s</code></td><td>Override path to the settings file. <em>(same as <code>SIGNALK_NODE_SETTINGS</code> environment variable)</em></td></tr> <tr><td><code>-c</code></td><td>Override the path to find server configuration. <em>(same as <code>SIGNALK_NODE_CONFIG_DIR</code> environment variable)</em></td></tr> <tr><td><code>--sample-nmea0183-data</code></td><td>Starts signalk-server with sample NMEA0183 data.</td></tr> <tr><td><code>--sample-n2k-data</code></td><td>Starts signalk-server with sample NMEA2000 data.</td></tr> <tr><td><code>--override-timestamps</code></td><td>Override timestamps in the sample NMEA2000 data with current date and time. Doesn't apply nor makes a difference to NMEA0183 sample data.</td></tr> <tr><td><code>--securityenabled</code></td><td>Enable security. For a fresh install this makes the Admin UI force the user to create an admin account before he/she can continue further into the UI. See <a href="installation/../security.html#enabling-security">Security</a> for further details.</td></tr> </tbody></table> </div> <h2 id="environment-variables"><a class="header" href="#environment-variables">Environment variables</a></h2> <div class="table-wrapper"><table><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody> <tr><td><code>PORT</code></td><td>Override the port for http/ws service (default is 3000).</td></tr> <tr><td><code>SSLPORT</code></td><td>Override the port for https/wss service. If defined forces ssl as default protocol <em>(default port is 3443)</em>.</td></tr> <tr><td><code>PROTOCOL</code></td><td>Override http/https where the server is accessed via https but the server sees http <em>(e.g. when Heroku handles https termination)</em></td></tr> <tr><td><code>EXTERNALPORT</code></td><td>The port used in /signalk response and Bonjour advertisement. Has precedence over configuration file.</td></tr> <tr><td><code>EXTERNALHOST</code></td><td>The host used in /signalk response and Bonjour advertisement. Has precedence over configuration file.</td></tr> <tr><td><code>FILEUPLOADSIZELIMIT</code></td><td>Override the file upload size limit <em>(default is '10mb')</em>.</td></tr> <tr><td><code>NMEA0183PORT</code></td><td>Override the port for the NMEA 0183 over tcp service <em>(default is 10110)</em>.</td></tr> <tr><td><code>TCPSTREAMPORT</code></td><td>Override the port for the Signal K Streaming (deltas) over TCP.</td></tr> <tr><td><code>TCPSTREAMADDRESS</code></td><td>Override the address the Signal K Stream (deltas) over TCP is listening on.</td></tr> <tr><td><code>DISABLEPLUGINS</code></td><td>Disable all plugins so that they can not be enabled <em>(default is false)</em>.</td></tr> <tr><td><code>DEFAULTENABLEDPLUGINS</code></td><td>A comma separated list of plugin ids that are overridden to be enabled by default if no setttings exist. Lower preference than <code>DISABLEPLUGINS</code>.</td></tr> <tr><td><code>PLUGINS_WITH_UPDATE_DISABLED</code></td><td>A comma separated list of plugin that will not be updated.</td></tr> <tr><td><code>SECURITYSTRATEGY</code></td><td>Override the security strategy module name.</td></tr> <tr><td><code>WSCOMPRESSION</code></td><td>Compress websocket messages <em>(default is false)</em>.</td></tr> <tr><td><code>MAXSENDBUFFERSIZE</code></td><td>The maximum number of bytes allowed in the server's send buffer of a WebSocket connection. The connection will be terminated if this is exceeded for MAXSENDBUFFERCHECKTIME milliseconds. Guards against slow or dysfunctional clients that can not cope with the message volume <em>(default is 512 * 1024 bytes)</em>.</td></tr> <tr><td><code>MAXSENDBUFFERCHECKTIME</code></td><td>The maximum number of bytes allowed in the server's send buffer of a WebSocket connection. The connection will be terminated if this is exceeded. Guards against slow or dysfunctional clients that can not cope with the message volume <em>(default is 512 * 1024 bytes)</em>.</td></tr> <tr><td><code>SIGNALK_SERVER_IS_UPDATABLE</code></td><td>Allows the server to be updated through the GUI even if it is not installed in the standard paths <em>(default is false)</em>. If set to true, the server must have been installed with <code>npm install -g signalk-server</code>.</td></tr> <tr><td><code>SIGNALK_DISABLE_SERVER_UPDATES</code></td><td>Disables server updates in the GUI <em>(default is false)</em>.</td></tr> <tr><td><code>DEBUG</code></td><td>A comma-separated list of tags for debugging the specified module <em>(e.g signalk-server*,signalk-provider-tcp)</em>. Can now be defined directly in the graphical interface. More help on how to use the debug here: <code>https://www.npmjs.com/package/debug#wildcards</code></td></tr> <tr><td><code>IS_IN_DOCKER</code></td><td>Used to tell the server it is in Docker and not normally updateable <em>(default is false)</em>.</td></tr> <tr><td><code>NPMREGISTRYTIMEOUT</code></td><td>How long to wait for the registry when retrieving the App Store listing <em>(default is 20s)</em>.</td></tr> <tr><td><code>SECRETKEY</code></td><td>A secret string used to generate an authentication token <em>(the internal default autogenerated is a string of 512 hex chars like 'ef8307a4c7a4bd7...309d947bca3')</em></td></tr> <tr><td><code>ALLOW_DEVICE_ACCESS_REQUESTS</code></td><td>Used when a device needs to gain access to a secured Signal K server <em>(default is true)</em> (https://signalk.org/specification/1.4.0/doc/access_requests.html).</td></tr> <tr><td><code>ALLOW_NEW_USER_REGISTRATION</code></td><td><em>(default is true)</em>.</td></tr> <tr><td><code>ADMINUSER</code></td><td>Force an account for admin user <em>(username:password format)</em>.</td></tr> <tr><td><code>PRESERIALCOMMAND</code></td><td>Command to run before opening a serial port.</td></tr> <tr><td><code>SIGNALK_NODE_SETTINGS</code></td><td>Override the path to the settings file.</td></tr> <tr><td><code>SIGNALK_NODE_CONFIG_DIR</code></td><td>Override the path to find server configuration. Includes all run-time changing content: configuration files, plugins, plugin configuration files, webapps, and so forth.</td></tr> </tbody></table> </div><div style="break-before: page; page-break-before: always;"></div><h1 id="security"><a class="header" href="#security">Security</a></h1> <h2 id="introduction-1"><a class="header" href="#introduction-1">Introduction</a></h2> <p>The umbrella term <em>Security</em> in Signal K server refers to the difference between running a server, that any one connected to the network can access and alter at will <strong>(unsecured)</strong> , and one with restrictions in place <strong>(secured)</strong>.</p> <p>The available security options relate to:</p> <ul> <li><strong>authentication</strong>: Users and / or connecting devices having to provide a credential to gain access to the server <em>(e.g. username &amp; password, access token, etc.)</em>.</li> <li><strong>access control</strong>: Based on the authentication, access is granted to only specific Signal K data and server configuration.</li> <li><strong>communications</strong>: Network traffic is encrypted and the identity of the server verified to protect against eavesdropping.</li> <li><strong>network services</strong>: Control which of the server's services/interfaces are configured and active <em>(e.g. does it allow unsecured read/write over the network)</em>.</li> </ul> <h2 id="enabling-security"><a class="header" href="#enabling-security">Enabling Security</a></h2> <p>When Signal K Server does not have security enabled, the <code>Login</code> option at the top right corner of the Admin UI will not be available.</p> <p>Security can be enabled in several ways:</p> <ol> <li> <p>Using the Admin UI, select <em>Security -&gt; Users</em> and then:</p> <ul> <li>Click <strong>Add</strong></li> <li>Enter a <strong>user id</strong></li> <li>Enter a <strong>password</strong> and confirm it</li> <li>In <strong>Permissions</strong> select <strong>Admin</strong></li> <li>Click <strong>Apply</strong>.</li> <li>Restart the Signal K Server.</li> </ul> </li> <li> <p>Starting the server with the <code>--securityenabled</code> command line option</p> </li> <li> <p>Adding the following section in the settings file</p> </li> </ol> <pre><code class="language-JSON">"security": { "strategy": "./tokensecurity", } </code></pre> <p>When security is enabled, the next time you access the Admin UI it will prompt you to create an administrator account.</p> <p>Security configuration is stored in file called <code>security.json</code> which will be located in the server configuration directory.</p> <h2 id="disabling-security--lost-admin-credentials"><a class="header" href="#disabling-security--lost-admin-credentials">Disabling Security / Lost Admin Credentials</a></h2> <p>In case the administrator user credentials are lost, removing the <code>security.json</code> file and restarting the server will restore access to the Admin UI.</p> <h2 id="access-control"><a class="header" href="#access-control">Access Control</a></h2> <p>Access control lists <em>(acls)</em> allow for fine grained access to specific data in Signal K. They specify the permissions assigned to users for resources within specifc contexts and are defined within the <code>security.json</code> file.</p> <p>The following example defines acls for the self context allowing:</p> <ol> <li> <p>Anyone to read the paths <code>"steering.*"</code>, <code>"navigation.*"</code>, <code>"name"</code>, <code>"design.aisShipType"</code> and grants the admin user permission to write (update) those paths.</p> </li> <li> <p>The user <em>john</em> to read any data coming from the <code>actisense.35</code> $source.</p> </li> <li> <p>For all other paths, only the admin user to read and no one can write.</p> </li> </ol> <pre><code class="language-JSON"> "acls": [ { "context": "vessels.self", "resources": [ { "paths": ["steering.*", "navigation.*", "name", "design.aisShipType"], "permissions": [ { "subject": "any", "permission": "read" }, { "subject": "admin", "permission": "write" } ] }, { "sources": [ "actisense.35" ], "permissions": [ { "subject": "john", "permission": "read" } ] }, { "paths": ["*"], "permissions": [ { "subject": "admin", "permission": "read" } ] } ] } ] </code></pre> <p><em>Note: If there is no match is found for a specific path in the acl list, then permission will be denied to that path!</em></p> <h2 id="active-network-services"><a class="header" href="#active-network-services">Active network services</a></h2> <p>Signal K Server's main network services are:</p> <ul> <li>The <em>primary Signal K http / WebSocket interface</em>, with options to use TLS encryption and authentication <em>(read/write)</em></li> <li><em>NMEA0183 data over TCP</em> on port 10110 <em>(read only)</em></li> <li><em>Signal K over TCP</em> on port 8375 <em>(read/write)</em></li> </ul> <p>In addition the user may configure any number of TCP, UDP and Websocket connections, some of which allow write access to the server.</p> <p>The security implication of these connections is that with no security options turned on <em>devices connected to the network will have both read and write access to practically all of its data and settings</em>.</p> <p>People often dismiss local network access by saying that their boat's local network is secure enough. But one very common scenario is connecting your Signal K server <em>(e.g. a Raspberry Pi)</em> to a marina wifi. Many wifi networks allow communication between all connected computers, so your Signal K server will be advertising its services over MDNS to all other connected devices.</p> <p>So in the case that your server has a manually configured connection for <em>NMEA0183 over UDP</em>, NMEA0183 data broadcast by other devices will be received and written into your SIgnal K data.</p> <p>NMEA0183 connections over TCP and UDP are inherently unsafe. There are no options for authentication and / or secure communication. In comparison Signal K over TLS and HTTP / WebSockets can provide secure, authenticated read and write access to your data.</p> <div style="break-before: page; page-break-before: always;"></div><h1 id="generating-tokens"><a class="header" href="#generating-tokens">Generating Tokens</a></h1> <h2 id="overview"><a class="header" href="#overview">Overview</a></h2> <p>For a device to be able to interact with a Signal K server with security enabled, it is require to pass an access token with each request.</p> <p><em>Examples include display / gauge, temperature sensor or client with no user interface.</em></p> <p>To get an access token the following methods can be used:</p> <ol> <li>The device can submit an <a href="https://signalk.org/specification/1.5.0/doc/access_requests.html">Access Request</a> which needs to be actioned via the Signal K Server UI.</li> <li>Generate a token against a user account that has been configured on the Signal K Server.</li> </ol> <h3 id="generate-token"><a class="header" href="#generate-token">Generate Token</a></h3> <p>To generate a token against a user account that has been configured on the Signal K Server use the <code>signalk-generate-token</code> utility.</p> <p>The <code>signalk-generate-token</code> utility is run from a terminal session on the Signal K Server and accepts the following parameters:</p> <ul> <li><code>-u &lt;username&gt;</code>: The user account against which the token is created.</li> <li><code>-e &lt;time to live&gt;</code>: The duration of time for which the token is valid. <ul> <li>1y = 1 year</li> <li>2h = 2 hours</li> <li>10m = 10 minutes</li> <li>5s = 5 seconds</li> </ul> </li> <li><code>-s &lt;path to security.json&gt;</code>: The path to the Siganl K Server's security.json file <em>(e.g. ~/.signalk/security.json)</em></li> </ul> <p><em>Example: Generate a token against the user "TempSensorDevice" that is valid for 1 year.</em></p> <pre><code class="language-sh">signalk-generate-token -u TempSensorDevice -e 1y -s ~/.signalk/security.json </code></pre> <p><em>Note: The device using the token will have the same permissions as the user account the token was generated against. It is recommended that you create a specific user with the appropriate permissions for use with the device.</em></p> <h3 id="access-requests"><a class="header" href="#access-requests">Access Requests</a></h3> <p>For information regarding Access Requests, <a href="https://signalk.org/specification/1.5.0/doc/access_requests.html"> see the Signal K specification</a>.</p> <div style="break-before: page; page-break-before: always;"></div><h2 id="configuring-signal-k-server"><a class="header" href="#configuring-signal-k-server">Configuring Signal K Server</a></h2> <p>Signal K Server provides an Admin UI to allow you to easily configure your installation.</p> <p>Open the Admin UI using a web browser on the device where Signal K server is installed (if the defaults have not been changed) by navigating to <code>http://localhost:3000</code>.</p> <h3 id="create-an-admin-account"><a class="header" href="#create-an-admin-account">Create an Admin account</a></h3> <p>It is considered good practise to enable security and create an administrator account to controll access to your server and protect your data.</p> <p>If you ran the <code>signalk-server-setup</code> script, security will be enabled and you will be presented with a login screen when accessing the Admin UI.</p> <p>If the login screen is not displayed, click <code>Login</code> <em>(top right of screen)</em> to display the prompt to create a user and password.</p> <p>Alternatively, from the menu select <em>Security -&gt; Users</em> and then:</p> <ol> <li>Click <strong>Add</strong></li> <li>Enter a <strong>user id</strong></li> <li>Enter a <strong>password</strong> and confirm it</li> <li>In <strong>Permissions</strong> select <strong>Admin</strong></li> <li>Click <strong>Apply</strong>.</li> </ol> <p>After creating the account, the server needs to be restarted.</p> <p>How you restart the server will depend on the installation type <em>(i.e. installed from NPM, embedded on a commercial device, etc)</em>. Power cycling the device that Signal K Server is always an option.</p> <h3 id="set-up-data-connections"><a class="header" href="#set-up-data-connections">Set up data connections</a></h3> <p>To get data into Signal K server you will need to configure one or more data connections via the <em>Server -&gt; Data Connections</em> menu option.</p> <p>From this screen you can add connections for various data types including:</p> <ul> <li>NMEA2000</li> <li>NMEA0183</li> <li>Signal K</li> <li>SeaTalk</li> <li>File Stream</li> </ul> <p>The options presented will vary based on the data type chosen.</p> <p><strong><em>NMEA2000</em></strong>: The processing of NMEA2000 PGNs is done by <a href="https://github.com/SignalK/n2k-signalk">n2k-signalk</a> via <a href="https://github.com/canboat/canboatjs">canboatjs</a>.</p> <p>Please refer to the <a href="https://canboat.github.io/canboat/canboat.html">Canboat PGN database</a> to see what PGNs are supported.</p> <p><strong><em>NMEA0183</em></strong>: The processing of NMEA0183 sentences is done by <a href="https://github.com/SignalK/signalk-parser-nmea0183">nmea0183-signalk</a></p> <h4 id="nmea-0183-options"><a class="header" href="#nmea-0183-options">NMEA 0183 Options</a></h4> <ul> <li> <p><em>Suppress nmea0183 event</em> - All incoming NMEA0183 data is made available over TCP on port 10110 by default. This happens by incoming data being emitted as <em>nmea0183</em> events. Selecting this option will prevent data from this connection appearing on the NEMA0183 TCP service.</p> </li> <li> <p><em>Input Event</em> - By default, data received on this connection will cause the nmea0183 event to be emitted. In order to distinguish input from this connection from other NMEA 0183 connections, enter an input event name which will be emitted (in addition to the nmea0183 event) when data is received on this connection.</p> </li> <li> <p><em>Validate checksum</em> - Usually <a href="https://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183 sentences</a> contain a checksum that can be used to check that the data is not garbled so that erroneous data is discarded. However some data sources do not include the checksum or it is simply wrong. Unchecking this option will disable validating the checksum.</p> </li> <li> <p><em>Append Checksum</em> - See previous point. Some data sources do not include a checksum, but for example a mobile app you are using may require them. Activating this option will add checksums to the data.</p> </li> <li> <p><em>Remove NULL characters</em> - Some data sources include superfluous NULL characters in the input data stream, making the data invalid for consumption. This option will remove the NULL characters. It causes additional processing, so not on by default.</p> </li> <li> <p><em>Ignored Sentences</em> - NMEA0183 sentences to throw away from the input data. Sometimes you may want to ignore certain sentences from a connection, because the data is invalid or missing or just not needed.</p> </li> <li> <p><em>Override timestamps</em> - NMEA0183 data may include timestamps in tag blocks. These may be off or when playing back captured data you may want to ignore the data and override them with current time when con