UNPKG

signalk-server

Version:

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

326 lines (285 loc) 24.1 kB
<!DOCTYPE HTML> <html lang="en" class="sidebar-visible no-js light"> <head> <!-- Book generated using mdBook --> <meta charset="UTF-8"> <title>Seatalk Connections - Signal K Server Documentation</title> <!-- 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" class="active"><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> <a href="https://github.com/SignalK/signalk-server/tree/master/docs/src" title="Suggest an edit" aria-label="Suggest an edit"> <i id="git-edit-button" class="fa fa-edit"></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> <h2 id="seatalk-connections"><a class="header" href="#seatalk-connections">Seatalk Connections</a></h2> <h3 id="introduction"><a class="header" href="#introduction">Introduction</a></h3> <p>The Signal K Server supports a variety of data connection types including <em>Seatalk (GPIO)</em> which provides the ability to receive Raymarine Seatalk 1 (ST1) data, via simple DIY hardware connected to a Raspberry Pi GPIO, and convert it to Signal K deltas. This information can then be forwarded by the Signal K Server to a NMEA 0183 or NMEA 2000 network using appropriate hardware and plugins.</p> <p>A guide to SeaTalk can be found <a href="http://boatprojects.blogspot.com/2012/12/beginners-guide-to-raymarines-seatalk.html">here</a>.</p> <h3 id="hardware"><a class="header" href="#hardware">Hardware</a></h3> <p>Using an optocoupler as the hardware interface is recommended as it creates electrical isolation from hazardous voltages and avoids ground loops.</p> <p>The circuit below uses the <a href="https://www.amazon.com/ARCELI-Optocoupler-Isolation-Converter-Photoelectric/dp/B07M78S8LB/ref=sr_1_2?dchild=1&amp;keywords=pc817+optocoupler&amp;qid=1593516071&amp;sr=8-2">PC817 optocoupler board</a> but any equivlent product can be used. The LED in the circuit will flicker when there is ST1 traffic.</p> <p><img src="./seatalk_circuit_3.jpg" alt="ST1_opto_SK" /></p> <p>If you are building the interface yourself use the below circuit instead. If you don't want any flickering just drop the LED at the input.</p> <p><img src="./seatalk_circuit_4.jpg" alt="ST1_opto_SK" /></p> <p>A simpler, non-electrically isolated, solution is detailed below, using a low signal NPN transistor which inverts and shifts the voltage from 12V DC to 3.3V DC.</p> <p><img src="./seatalk_circuit_2.jpg" alt="ST1_Tr" /></p> <p>If you do not want to build your own circuit, you can get a <strong>MacArthur HAT</strong> and simply connect it to your Seatalk 1 network <a href="https://macarthur-hat-documentation.readthedocs.io/en/latest/seatalk.html">following the manual</a>. If you also use OpenPlotter with this HAT, all the software will be installed and ready to go.</p> <p><img src="./seatalk-dcdc.png" alt="MacArthur HAT" /></p> <h3 id="software"><a class="header" href="#software">Software</a></h3> <p>Before setting up the data connection on Signal K Server, you may need to install some associated Python libraries on your system. Here you have two options: gpiod library (<strong>Raspberry Pi 3, 4 and 5 models</strong>) or pigpio library (<strong>Raspberry Pi 3 and 4 models</strong>).</p> <h4 id="gpiod-recommended"><a class="header" href="#gpiod-recommended">gpiod (recommended)</a></h4> <p>Both versions of this library 1.x.x (Debian package) and 2.x.x (Pip package) are supported. It is possible that your system already has one of the two versions of this library installed and some program is already using it, so before installing it we will check if we already have one.</p> <p>Type this in a terminal:</p> <pre><code>python -m pydoc gpiod | tail </code></pre> <p>If gpiod appears as installed, simply do nothing and go directly to the <em>Data Connection</em> section.</p> <p>If it is not installed, type this in a terminal to install the latest version from pip:</p> <pre><code>sudo pip3 install gpiod </code></pre> <p>Since Debian 12 (Bookworm) and Ubuntu 24 (Noble), pip packages need to be installed in virtual environments, but we need this library to be installed at the system level, so on these systems we need to type this instead:</p> <pre><code>sudo pip3 install gpiod --break-system-packages </code></pre> <p>Pip will complain that the package is being installed in a non-virtual environment, but you can ignore the warning because it has not been detected to break any system packages.</p> <h4 id="pigpio"><a class="header" href="#pigpio">pigpio</a></h4> <p><em>Inspired by <a href="https://github.com/Thomas-GeDaD/Seatalk1-Raspi-reader">Read SeaTalk1 from the Raspberry Pi GPIO using pigpio</a>.</em></p> <p>Open a terminal and enter the following:</p> <ol> <li>Update the package manifest</li> </ol> <pre><code> sudo apt-get update </code></pre> <ol start="2"> <li>Install the software</li> </ol> <pre><code> sudo apt-get install pigpio python-pigpio python3-pigpio </code></pre> <ol start="3"> <li>Enable and start the <em>pigpio</em> <a href="http://abyz.me.uk/rpi/pigpio/">daemon</a> which handles the data connection.</li> </ol> <pre><code> sudo systemctl enable pigpiod &amp;&amp; sudo systemctl restart pigpiod </code></pre> <ol start="4"> <li>Check the _pigpio_service is running</li> </ol> <pre><code> sudo systemctl status pigpiod </code></pre> <p><em>Note: The <em>pigpio</em> deamon by default provides a socket interface on port 8888, which may conflict with other software running on your Raspberry Pi. To have the socket interface use another port you will need to change the <a href="http://abyz.me.uk/rpi/pigpio/pigpiod.html">pigpiod.service file</a> using the <a href="http://abyz.me.uk/rpi/pigpio/python.html#pigpio.pi">Python program</a> with the -p option.</em></p> <h3 id="data-connection"><a class="header" href="#data-connection">Data Connection</a></h3> <p>With the required software installed, you can now add a new data connection using the Signal K Server Admin UI.</p> <p><em>Example Data Connection:</em></p> <p><img src="./config.png" alt="ST1_connection_SK" /></p> <ul> <li> <p>Select <em>Server -&gt; Data Connections</em> from the main menu.</p> </li> <li> <p>Click the <strong>Add</strong> button to create a new connection.</p> </li> <li> <p>Select <strong>Seatalk (GPIO)</strong> in the <em>Data Type</em> dropdown list.</p> </li> <li> <p>Set the <em>Enabled</em> to <strong>Yes</strong>.</p> </li> <li> <p>Enter an <em>ID</em> <em>(e.g. Seatalk1)</em>.</p> </li> <li> <p>In <em>GPIO Library</em>, select the software that is installed on your system as we have seen in the previous section.</p> </li> <li> <p>In <em>GPIO Pin</em>, select one of the green GPIO pins from those pictured below <em>(this will be the pin to which you connect your hardware e.g. GPIO04).</em></p> </li> </ul> <p><img src="./gpio.png" alt="GPIO" /></p> <ul> <li> <p>Set <em>Invert Signal</em> based on the hardware interface you have used <em>(e.g. Select <strong>No</strong> if using the optocoupler hardware setup above. Select <strong>Yes</strong> if using a hardware interface that inverts the ST1 signal)</em>.</p> </li> <li> <p>Click <strong>Apply</strong> to save your data connection settings.</p> </li> <li> <p>Restart the Signal K Server.</p> </li> </ul> <h3 id="viewing-received-data"><a class="header" href="#viewing-received-data">Viewing Received Data</a></h3> <p>Once the server has restarted, confirm that data is being received from the ST1 connection by using the <em>Data Browser</em> in the Admin UI .</p> <p>The data received via the Seatalk connection will be displayed in the Data Browser with a source value that contains the <em>ID</em> you provided when setting up the connection.</p> <p>If there is no data displayed in the Data Browser from the Seatalk connection, you can check if there is data available at the selected GPIO using these utilities:</p> <p>gpiod: https://gist.github.com/astuder/c319cf955f6d651350222d36065981b3</p> <p>pigpio: https://raw.githubusercontent.com/MatsA/seatalk1-to-NMEA0183/master/STALK_read.py</p> <p>If the display shows ST1 sentences being received at the GPIO pin then review your data connection settings.</p> </main> <nav class="nav-wrapper" aria-label="Page navigation"> <!-- Mobile navigation buttons --> <a rel="prev" href="../../setup/configuration.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a rel="next" href="../../features/anchoralarm/anchoralarm.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> <div style="clear: both"></div> </nav> </div> </div> <nav class="nav-wide-wrapper" aria-label="Page navigation"> <a rel="prev" href="../../setup/configuration.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a rel="next" href="../../features/anchoralarm/anchoralarm.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> </nav> </div> <script> window.playground_copyable = true; </script> <script src="../../elasticlunr.min.js"></script> <script src="../../mark.min.js"></script> <script src="../../searcher.js"></script> <script src="../../clipboard.min.js"></script> <script src="../../highlight.js"></script> <script src="../../book.js"></script> <!-- Custom JS scripts --> </div> </body> </html>