signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
724 lines • 126 kB
HTML
<!DOCTYPE html><html class="default" lang="en" data-base="../../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Radar API | Signal K</title><meta name="description" content="Documentation for Signal K"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../../assets/style.css?cache=1783009712609"/><link rel="stylesheet" href="../../assets/highlight.css?cache=1783009712609"/><script defer src="../../assets/main.js?cache=1783009712609"></script><script async src="../../assets/icons.js?cache=1783009712609" id="tsd-icons-script"></script><script async src="../../assets/search.js?cache=1783009712609" id="tsd-search-script"></script><script async src="../../assets/navigation.js?cache=1783009712609" id="tsd-nav-script"></script><script async src="../../assets/hierarchy.js?cache=1783009712609" id="tsd-hierarchy-script"></script><link rel="stylesheet" href="../../assets/theme.css"/><script>if(window.self!==window.top){document.documentElement.classList.add('embedded')}</script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../../index.html" class="title"><img class="title-logo" src="../../assets/logo.svg" alt="Signal K"/><svg class="title-home-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-label="Documentation home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg></a><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../../assets/icons.svg#icon-search"></use></svg><span class="visible@s">Search</span></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><div id="tsd-toolbar-links"><a href="https://discord.gg/uuZrwz4dCS" target="_blank" rel="noopener" class="toolbar-icon visible@s" aria-label="Discord"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"></path></svg></a><a href="https://github.com/SignalK/signalk-server" target="_blank" rel="noopener" class="toolbar-icon visible@s" aria-label="Discord"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path></svg></a><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="../../Developing.html">Developing</a></li><li><a href="../REST_APIs.html">REST APIs</a></li><li><a href="" aria-current="page">Radar API</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="radar-api" class="tsd-anchor-link">Radar API<a href="#radar-api" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h1>
<p>The Signal K server Radar API provides a unified interface for viewing and controlling marine radar equipment from any manufacturer. The API is <strong>(web)app-friendly</strong>: clients can build dynamic UIs that automatically adapt to any radar's capabilities without hardcoding support for specific brands or models.</p>
<p>This is version v3.1.0 of the API. The version will use semver for version updates.</p>
<p>Radar functionality is provided by "provider plugins" that handle the interaction with radar hardware and stream spoke data to connected clients.</p>
<p>Requests to the Radar API are made to HTTP REST endpoints rooted at <code>/signalk/v2/api/vessels/self/radars</code> or the Signal K websocket stream at <code>/signalk/v1/stream</code>.</p>
<p>Like <code>signalk-server</code> vis-a-vis the Signal K specification there is a reference implementation
for this API, which may very well remain the only implementation of the server side of the API,
at <a href="https://github.com/MarineYachtRadar/mayara-server">https://github.com/MarineYachtRadar/mayara-server</a>. However, like Signal K itself, there is no
reason it needs to remain the only implementation. In particular it would be ultra cool if some
manufacturer of marine hardware would implement this API -- even though this is very unlikely.</p>
<h2 id="design-philosophy-capabilities-driven-api" class="tsd-anchor-link">Design Philosophy: Capabilities-Driven API<a href="#design-philosophy-capabilities-driven-api" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>This API uses a <strong>self-describing schema</strong> pattern that benefits both radar provider developers and client/chartplotter developers.</p>
<h3 id="for-clientchartplotter-developers" class="tsd-anchor-link">For Client/Chartplotter Developers<a href="#for-clientchartplotter-developers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Build a <strong>single, adaptive UI</strong> that works with any radar—now and in the future—without hardcoding brand-specific logic.</p>
<p><strong>How it works:</strong></p>
<ol>
<li><strong>Fetch capabilities once</strong> when a radar connects — this tells you what the radar can do</li>
<li><strong>Generate UI widgets from the schema:</strong>
<ul>
<li><code>dataType: "number"</code> → Slider with min/max/step</li>
<li><code>dataType: "enum"</code> with <code>descriptions</code> → Dropdown or button group</li>
<li><code>dataType: "string"</code> → Text input field</li>
<li><code>dataType: "button"</code> → Action button</li>
<li><code>dataType: "sector"</code> → Angle range selector (start/end angles)</li>
<li><code>dataType: "zone"</code> → Guard zone editor (angles + distances)</li>
<li><code>dataType: "rect"</code> → Rectangular exclusion zone (two corners + width)</li>
<li><code>isReadOnly: true</code> → Display-only label</li>
</ul>
</li>
<li><strong>Subscribe to updates for current values</strong> — the schema tells you what to expect</li>
<li><strong>Connect to websocket for spoke data</strong> - receive the binary spoke data stream</li>
</ol>
<p><strong>Example: Rendering a Gain Control</strong></p>
<pre><code class="shell"><span class="hl-5">$</span><span class="hl-0"> </span><span class="hl-4">curl</span><span class="hl-0"> </span><span class="hl-2">-s</span><span class="hl-0"> </span><span class="hl-4">http://10.56.0.1:6502/signalk/v2/api/vessels/self/radars/nav1034A/capabilities</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-5">jq</span><span class="hl-0"> </span><span class="hl-4">'.controls.gain'</span><br/><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-5">"category"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">"base",</span><br/><span class="hl-0"> </span><span class="hl-5">"dataType"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">"number",</span><br/><span class="hl-0"> </span><span class="hl-5">"description"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">"How sensitive the radar is to returning echoes",</span><br/><span class="hl-0"> </span><span class="hl-5">"hasAuto"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-2">true</span><span class="hl-4">,</span><br/><span class="hl-0"> </span><span class="hl-5">"hasAutoAdjustable"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-2">false</span><span class="hl-4">,</span><br/><span class="hl-0"> </span><span class="hl-5">"id"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">4,</span><br/><span class="hl-0"> </span><span class="hl-5">"maxValue"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">100.0,</span><br/><span class="hl-0"> </span><span class="hl-5">"minValue"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">0.0,</span><br/><span class="hl-0"> </span><span class="hl-5">"name"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-4">"Gain",</span><br/><span class="hl-0"> </span><span class="hl-5">"stepValue"</span><span class="hl-2">:</span><span class="hl-0"> </span><span class="hl-2">1.0</span><br/><span class="hl-0">}</span><br/><span class="hl-5">$</span><span class="hl-0"> </span><span class="hl-4">curl</span><span class="hl-0"> </span><span class="hl-2">-s</span><span class="hl-0"> </span><span class="hl-4">http://10.56.0.1:6502/signalk/v2/api/vessels/self/radars/nav1034A/controls/gain</span><br/><span class="hl-0">{</span><span class="hl-5">"auto"</span><span class="hl-5">:false,</span><span class="hl-5">"value"</span><span class="hl-5">:58}</span>
</code><button type="button">Copy</button></pre>
<p>Your UI renders:</p>
<ul>
<li>Mode toggle: <code>[Auto] [Manual]</code></li>
<li>Value slider: <code>0 ----[58]---- 100</code> (disabled or hidden when mode=auto)</li>
</ul>
<p>Whether it's a Furuno DRS4D-NXT with 20, a Navico HALO with 40 controls or a basic radar with 5 controls, the same client code handles both.</p>
<h3 id="for-radar-provider-developers-plugin-authors" class="tsd-anchor-link">For Radar Provider Developers (Plugin Authors)<a href="#for-radar-provider-developers-plugin-authors" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Different manufacturers have vastly different hardware capabilities, control sets, value ranges, and operating modes. Instead of clients hardcoding knowledge about each model, your provider plugin <strong>declares</strong> what the radar can do:</p>
<ol>
<li><strong>Capabilities</strong> — hardware capabilities (Doppler, dual-range, no-transmit zones, supported ranges)</li>
<li><strong>Controls</strong> — schema for each control (type, valid values, modes, read-only status)</li>
</ol>
<h2 id="control-categories" class="tsd-anchor-link">Control Categories<a href="#control-categories" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<table>
<thead>
<tr>
<th>Category</th>
<th>Description</th>
<th>Examples</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>base</code></td>
<td>Available on all radars</td>
<td>power, range, gain, sea, rain</td>
</tr>
<tr>
<td><code>targets</code></td>
<td>Target tracking settings</td>
<td>targetExpansion, targetTrails</td>
</tr>
<tr>
<td><code>guardZones</code></td>
<td>Guard zone configuration</td>
<td>guardZone1, guardZone2</td>
</tr>
<tr>
<td><code>trails</code></td>
<td>Trail display settings</td>
<td>trailsTime, clearTrails</td>
</tr>
<tr>
<td><code>advanced</code></td>
<td>Model-specific features</td>
<td>dopplerMode, beamSharpening, interferenceRejection</td>
</tr>
<tr>
<td><code>installation</code></td>
<td>Setup/configuration settings</td>
<td>antennaHeight, bearingAlignment, noTransmitSector1</td>
</tr>
<tr>
<td><code>info</code></td>
<td>Read-only information</td>
<td>serialNumber, firmwareVersion, transmitTime</td>
</tr>
</tbody>
</table>
<p>Read-only information (serialNumber, firmwareVersion, operatingHours) is exposed as controls with <code>isReadOnly: true</code>. Some controls are <strong>dynamically</strong> read-only when a particular mode is set. This is handled with an optional <code>allowed: <bool></code> field in the control value.</p>
<p>Some further considerations as how to show controls:</p>
<ul>
<li>Within each category, all controls have a numeric <code>id</code> field which may be used for ordering.</li>
<li>The <code>advanced</code> and especially the <code>installation</code> categories could be shown in a different panel.</li>
<li>In particular the <code>installation</code> controls are typically configured once.</li>
<li>The <code>power</code> and <code>range</code> controls are used often and should be easy to be controlled.</li>
<li>The <code>gain</code>, <code>sea</code> and <code>rain</code> controls are usually represented graphically on a PPI window.</li>
</ul>
<h2 id="api-overview" class="tsd-anchor-link">API Overview<a href="#api-overview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<pre><code class="text">/signalk/v2/api/vessels/self/radars
├── GET → List all active radars
├── /interfaces
│ └── GET → List network interfaces and listener status
└── /{radar_id}
├── /capabilities GET → Get radar capabilities and control definitions
├── /controls
│ ├── GET → Get all control values
│ └── /{control_id}
│ ├── GET → Get single control value
│ └── PUT → Set single control value
├── /spokes → WebSocket (spoke data in binary format)
└── /targets
├── GET → List tracked targets
├── POST → Acquire target manually
└── /{target_id}
└── DELETE → Cancel target tracking
/signalk/v1/stream → WebSocket (control values and targets for all radars)
</code><button type="button">Copy</button></pre>
<h2 id="rest-api" class="tsd-anchor-link">REST API<a href="#rest-api" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<h3 id="listing-all-radars" class="tsd-anchor-link">Listing All Radars<a href="#listing-all-radars" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Retrieve all available radars with their current info:</p>
<pre><code class="text">HTTP GET "/signalk/v2/api/vessels/self/radars"
</code><button type="button">Copy</button></pre>
<p><em>Response:</em></p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"nav1034A"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"brand"</span><span class="hl-0">: </span><span class="hl-4">"Navico"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"model"</span><span class="hl-0">: </span><span class="hl-4">"HALO"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"HALO 034A"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"radarIpAddress"</span><span class="hl-0">: </span><span class="hl-4">"192.168.1.50"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"spokeDataUrl"</span><span class="hl-0">: </span><span class="hl-4">"ws://192.168.1.100:8080/signalk/v2/api/vessels/self/radars/nav1034A/spokes"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"streamUrl"</span><span class="hl-0">: </span><span class="hl-4">"ws://192.168.1.100:8080/signalk/v1/stream"</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"nav1034B"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"brand"</span><span class="hl-0">: </span><span class="hl-4">"Navico"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"model"</span><span class="hl-0">: </span><span class="hl-4">"HALO"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"HALO 034B"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"radarIpAddress"</span><span class="hl-0">: </span><span class="hl-4">"192.168.1.50"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"spokeDataUrl"</span><span class="hl-0">: </span><span class="hl-4">"ws://192.168.1.100:8080/signalk/v2/api/vessels/self/radars/nav1034B/spokes"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"streamUrl"</span><span class="hl-0">: </span><span class="hl-4">"ws://192.168.1.100:8080/signalk/v1/stream"</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="network-interfaces" class="tsd-anchor-link">Network Interfaces<a href="#network-interfaces" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Check which network interfaces are available and which radar brands are listening:</p>
<pre><code class="text">HTTP GET "/signalk/v2/api/vessels/self/radars/interfaces"
</code><button type="button">Copy</button></pre>
<p><em>Response:</em></p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"brands"</span><span class="hl-0">: [</span><span class="hl-4">"Navico"</span><span class="hl-0">, </span><span class="hl-4">"Furuno"</span><span class="hl-0">, </span><span class="hl-4">"Raymarine"</span><span class="hl-0">],</span><br/><span class="hl-0"> </span><span class="hl-3">"interfaces"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"en0"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"status"</span><span class="hl-0">: </span><span class="hl-4">"Ok"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"ip"</span><span class="hl-0">: </span><span class="hl-4">"192.168.1.100"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"netmask"</span><span class="hl-0">: </span><span class="hl-4">"255.255.255.0"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"listeners"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"Navico"</span><span class="hl-0">: </span><span class="hl-4">"Active"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"Furuno"</span><span class="hl-0">: </span><span class="hl-4">"No match for 172.31.255.255"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"Raymarine"</span><span class="hl-0">: </span><span class="hl-4">"Listening"</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"en1"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"status"</span><span class="hl-0">: </span><span class="hl-4">"WirelessIgnored"</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>This endpoint is useful for diagnosing network configuration issues when radars are not being detected.</p>
<h3 id="getting-radar-capabilities" class="tsd-anchor-link">Getting Radar Capabilities<a href="#getting-radar-capabilities" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>The capability manifest describes everything a radar can do. Clients should fetch this at the beginning of a session. The contents do not change during radar operation.</p>
<pre><code class="text">HTTP GET "/signalk/v2/api/vessels/self/radars/{radar_id}/capabilities"
</code><button type="button">Copy</button></pre>
<p><em>Response:</em></p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"maxRange"</span><span class="hl-0">: </span><span class="hl-2">74080</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minRange"</span><span class="hl-0">: </span><span class="hl-2">50</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"supportedRanges"</span><span class="hl-0">: [</span><br/><span class="hl-0"> </span><span class="hl-2">50</span><span class="hl-0">, </span><span class="hl-2">75</span><span class="hl-0">, </span><span class="hl-2">100</span><span class="hl-0">, </span><span class="hl-2">250</span><span class="hl-0">, </span><span class="hl-2">500</span><span class="hl-0">, </span><span class="hl-2">750</span><span class="hl-0">, </span><span class="hl-2">1000</span><span class="hl-0">, </span><span class="hl-2">1500</span><span class="hl-0">, </span><span class="hl-2">2000</span><span class="hl-0">, </span><span class="hl-2">3000</span><span class="hl-0">, </span><span class="hl-2">4000</span><span class="hl-0">, </span><span class="hl-2">6000</span><span class="hl-0">, </span><span class="hl-2">8000</span><span class="hl-0">, </span><span class="hl-2">12000</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-2">16000</span><span class="hl-0">, </span><span class="hl-2">24000</span><span class="hl-0">, </span><span class="hl-2">36000</span><span class="hl-0">, </span><span class="hl-2">48000</span><span class="hl-0">, </span><span class="hl-2">64000</span><span class="hl-0">, </span><span class="hl-2">74080</span><br/><span class="hl-0"> ],</span><br/><span class="hl-0"> </span><span class="hl-3">"spokesPerRevolution"</span><span class="hl-0">: </span><span class="hl-2">2048</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxSpokeLength"</span><span class="hl-0">: </span><span class="hl-2">1024</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"pixelValues"</span><span class="hl-0">: </span><span class="hl-2">16</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasDoppler"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasDualRadar"</span><span class="hl-0">: </span><span class="hl-2">false</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasDualRange"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasSparseSpokes"</span><span class="hl-0">: </span><span class="hl-2">false</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"noTransmitSectors"</span><span class="hl-0">: </span><span class="hl-2">2</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"controls"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"gain"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">4</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Gain"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"How sensitive the radar is to returning echoes"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"base"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"number"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minValue"</span><span class="hl-0">: </span><span class="hl-2">0.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">100.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"stepValue"</span><span class="hl-0">: </span><span class="hl-2">1.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasAuto"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasAutoAdjustable"</span><span class="hl-0">: </span><span class="hl-2">false</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"legend"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"lowReturn"</span><span class="hl-0">: </span><span class="hl-2">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"mediumReturn"</span><span class="hl-0">: </span><span class="hl-2">8</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"strongReturn"</span><span class="hl-0">: </span><span class="hl-2">13</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"targetBorder"</span><span class="hl-0">: </span><span class="hl-2">17</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dopplerApproaching"</span><span class="hl-0">: </span><span class="hl-2">18</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dopplerReceding"</span><span class="hl-0">: </span><span class="hl-2">19</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"historyStart"</span><span class="hl-0">: </span><span class="hl-2">20</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"pixelColors"</span><span class="hl-0">: </span><span class="hl-2">16</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"pixels"</span><span class="hl-0">: [</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"normal"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: { </span><span class="hl-3">"r"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">, </span><span class="hl-3">"g"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">, </span><span class="hl-3">"b"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">, </span><span class="hl-3">"a"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0"> } },</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"normal"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: { </span><span class="hl-3">"r"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">, </span><span class="hl-3">"g"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">, </span><span class="hl-3">"b"</span><span class="hl-0">: </span><span class="hl-2">51</span><span class="hl-0">, </span><span class="hl-3">"a"</span><span class="hl-0">: </span><span class="hl-2">255</span><span class="hl-0"> } }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>Capability fields:</p>
<ol>
<li><code>hasDoppler</code> - if true, the radar can detect boats or objects approaching or receding and emits separate pixel colors for these.</li>
<li><code>hasDualRadar</code> - if true, the physical radome reports itself as two independent radars that can be set to different ranges and modes. Currently only Navico 4G and HALO support this.</li>
<li><code>hasDualRange</code> - mutually exclusive with <code>hasDualRadar</code>, indicates a more limited form of supporting two ranges with one device.</li>
<li><code>minRange</code> and <code>maxRange</code> - define what ranges the radar supports (in meters).</li>
<li><code>supportedRanges</code> - list of all discrete range values the radar supports (in meters).</li>
<li><code>maxSpokeLength</code> and <code>spokesPerRevolution</code> - define how many pixels the radar produces each revolution.</li>
<li><code>noTransmitSectors</code> - how many sectors the radar can stop transmitting to avoid obstacles like masts.</li>
<li><code>pixelValues</code> - number of distinct pixel intensity values.</li>
<li><code>hasSparseSpokes</code> - if true, the radar produces fewer spokes per revolution than <code>spokesPerRevolution</code> indicates (see <a href="#spoke-skipping">Spoke skipping</a>).</li>
</ol>
<h3 id="legend" class="tsd-anchor-link">Legend<a href="#legend" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>All spokes are sent with one byte per pixel. The legend explains what each byte value represents.</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"lowReturn"</span><span class="hl-0">: </span><span class="hl-2">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"mediumReturn"</span><span class="hl-0">: </span><span class="hl-2">8</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"strongReturn"</span><span class="hl-0">: </span><span class="hl-2">13</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dopplerApproaching"</span><span class="hl-0">: </span><span class="hl-2">18</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dopplerReceding"</span><span class="hl-0">: </span><span class="hl-2">19</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"historyStart"</span><span class="hl-0">: </span><span class="hl-2">20</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"pixelColors"</span><span class="hl-0">: </span><span class="hl-2">16</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"pixels"</span><span class="hl-0">: [</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"normal"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: </span><span class="hl-4">"#00000000"</span><span class="hl-0"> },</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"normal"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: </span><span class="hl-4">"#0000ffff"</span><span class="hl-0"> },</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"dopplerApproaching"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: </span><span class="hl-4">"#ff00ffff"</span><span class="hl-0"> },</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"dopplerReceding"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: </span><span class="hl-4">"#00ff00ff"</span><span class="hl-0"> },</span><br/><span class="hl-0"> { </span><span class="hl-3">"type"</span><span class="hl-0">: </span><span class="hl-4">"history"</span><span class="hl-0">, </span><span class="hl-3">"color"</span><span class="hl-0">: </span><span class="hl-4">"#454545ff"</span><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>The <code>lowReturn</code>, <code>mediumReturn</code>, and <code>strongReturn</code> indicate offsets in the array, typically used for smoothing algorithms.</p>
<p>If the radar doesn't implement Doppler, the <code>dopplerApproaching</code> and <code>dopplerReceding</code> fields will be null. If the provider doesn't implement target trails, <code>historyStart</code> will be null.</p>
<h3 id="dual-rangeradar" class="tsd-anchor-link">Dual range/radar<a href="#dual-rangeradar" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>There are two different ways that radars handle "dual" ranges.</p>
<p>Navico radars implement this by acting
as if both radars are full independent, to the point where both radars use different ports and IP addresses.
They can be seen to be dependent in that if you change some controls they also change on the other radar.
The NoTransmitZones are examples of such controls.
These radars therefore also show up as two radars in the API.
As long as clients listen to updates to controls, which they should do anyway to be able to function in a setting where there is for instance a MFD device, they can assume that all controls can be set.</p>
<p>Furuno radars do this in a way where the second range shares as many control settings as possible.
Currently there is no support for Furuno dual range yet and its impact on the API is unknown.</p>
<h3 id="controls" class="tsd-anchor-link">Controls<a href="#controls" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>The <code>controls</code> object in capabilities lists all controls the radar supports. Control data types:</p>
<table>
<thead>
<tr>
<th>dataType</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>number</td>
<td>Numeric value with min/max/step</td>
</tr>
<tr>
<td>enum</td>
<td>Discrete set of values with descriptions</td>
</tr>
<tr>
<td>string</td>
<td>Text value</td>
</tr>
<tr>
<td>button</td>
<td>Action trigger (no value)</td>
</tr>
<tr>
<td>sector</td>
<td>Angle range (start/end)</td>
</tr>
<tr>
<td>zone</td>
<td>Guard zone (angles + distances)</td>
</tr>
<tr>
<td>rect</td>
<td>Rectangular exclusion zone</td>
</tr>
</tbody>
</table>
<ol>
<li><strong>number</strong></li>
</ol>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">47</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Transmit time"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"How long the radar has been transmitting over its lifetime"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"info"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"number"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"isReadOnly"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minValue"</span><span class="hl-0">: </span><span class="hl-2">0.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">3599996400.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"stepValue"</span><span class="hl-0">: </span><span class="hl-2">3600.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"units"</span><span class="hl-0">: </span><span class="hl-4">"s"</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>The <code>units</code> field indicates the unit of measurement for the control value. A conforming server implementation sends only SI units to clients:</p>
<table>
<thead>
<tr>
<th>Category</th>
<th>SI Unit</th>
<th>Abbreviation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Distance</td>
<td>Meters</td>
<td><code>m</code></td>
</tr>
<tr>
<td>Speed</td>
<td>Meters per second</td>
<td><code>m/s</code></td>
</tr>
<tr>
<td>Angle</td>
<td>Radians</td>
<td><code>rad</code></td>
</tr>
<tr>
<td>Rotational speed</td>
<td>Radians per second</td>
<td><code>rad/s</code></td>
</tr>
<tr>
<td>Duration</td>
<td>Seconds</td>
<td><code>s</code></td>
</tr>
</tbody>
</table>
<p>Note how in the above example the server has converted a value in hours (3600 seconds) to seconds to conform to the above, but the client can convert the value back to hours for representation to
a human.</p>
<p>A conforming API server will allow the following units to be specified when receiving values from
a client:</p>
<table>
<thead>
<tr>
<th>Category</th>
<th>Unit</th>
<th>Abbreviation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Distance</td>
<td>Meters</td>
<td><code>m</code></td>
</tr>
<tr>
<td>Distance</td>
<td>Kilometers</td>
<td><code>km</code></td>
</tr>
<tr>
<td>Distance</td>
<td>Nautical miles</td>
<td><code>nm</code></td>
</tr>
<tr>
<td>Speed</td>
<td>Meters per second</td>
<td><code>m/s</code></td>
</tr>
<tr>
<td>Speed</td>
<td>Knots</td>
<td><code>kn</code></td>
</tr>
<tr>
<td>Angle</td>
<td>Radians</td>
<td><code>rad</code></td>
</tr>
<tr>
<td>Angle</td>
<td>Degrees</td>
<td><code>deg</code></td>
</tr>
<tr>
<td>Rotational speed</td>
<td>Radians per second</td>
<td><code>rad/s</code></td>
</tr>
<tr>
<td>Rotational speed</td>
<td>Rotations/minute</td>
<td><code>rpm</code></td>
</tr>
<tr>
<td>Duration</td>
<td>Seconds</td>
<td><code>s</code></td>
</tr>
<tr>
<td>Duration</td>
<td>Minutes</td>
<td><code>min</code></td>
</tr>
<tr>
<td>Duration</td>
<td>Hours</td>
<td><code>h</code></td>
</tr>
</tbody>
</table>
<ol start="2">
<li><strong>enum</strong></li>
</ol>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Power"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"Radar operational state"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"base"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"enum"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minValue"</span><span class="hl-0">: </span><span class="hl-2">0.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">3.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"stepValue"</span><span class="hl-0">: </span><span class="hl-2">1.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"descriptions"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"0"</span><span class="hl-0">: </span><span class="hl-4">"Off"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"1"</span><span class="hl-0">: </span><span class="hl-4">"Standby"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"2"</span><span class="hl-0">: </span><span class="hl-4">"Transmit"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"3"</span><span class="hl-0">: </span><span class="hl-4">"Preparing"</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"validValues"</span><span class="hl-0">: [</span><span class="hl-2">1</span><span class="hl-0">, </span><span class="hl-2">2</span><span class="hl-0">]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>The <code>validValues</code> array indicates which values can be set by clients. The <code>power</code> control guarantees that at least these values can be set across all radars: 1 (Standby) and 2 (Transmit).</p>
<ol start="3">
<li><strong>string</strong></li>
</ol>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">53</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Custom name"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"User defined name for the radar"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"advanced"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"string"</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<ol start="4">
<li><strong>button</strong></li>
</ol>
<p>A button triggers an action without needing a value:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">15</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Clear trails"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"Clear target trails"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"trails"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"button"</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<ol start="5">
<li><strong>sector</strong></li>
</ol>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">35</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"No Transmit sector"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"First no-transmit sector"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"installation"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"sector"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasEnabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minValue"</span><span class="hl-0">: </span><span class="hl-2">-3.141592653589793</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">3.141592653589793</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"stepValue"</span><span class="hl-0">: </span><span class="hl-2">0.0017453292519943296</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"units"</span><span class="hl-0">: </span><span class="hl-4">"rad"</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>A sector defines a start and end angle from -π to +π radians, plus an enabled flag. The value for start is transmitted in <code>value</code> and the end in <code>endValue</code>.</p>
<pre><code class="shell"><span class="hl-5">$</span><span class="hl-0"> </span><span class="hl-4">curl</span><span class="hl-0"> </span><span class="hl-2">-s</span><span class="hl-0"> </span><span class="hl-4">http://localhost:6502/signalk/v2/api/vessels/self/radars/nav1034A/controls/noTransmitSector1</span><br/><span class="hl-0">{</span><span class="hl-5">"enabled"</span><span class="hl-5">:true,</span><span class="hl-5">"value"</span><span class="hl-5">:-1.5533,</span><span class="hl-5">"endValue"</span><span class="hl-5">:-1.2217}</span>
</code><button type="button">Copy</button></pre>
<ol start="6">
<li><strong>zone</strong></li>
</ol>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">16</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Guard zone"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"First guard zone for target detection"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"guardZones"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"zone"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasEnabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minValue"</span><span class="hl-0">: </span><span class="hl-2">-3.141592653589793</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">3.141592653589793</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxDistance"</span><span class="hl-0">: </span><span class="hl-2">100000.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"units"</span><span class="hl-0">: </span><span class="hl-4">"rad"</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>A zone defines five attributes: start angle, end angle, start distance, end distance, and enabled.</p>
<pre><code class="shell"><span class="hl-5">$</span><span class="hl-0"> </span><span class="hl-4">curl</span><span class="hl-0"> </span><span class="hl-2">-s</span><span class="hl-0"> </span><span class="hl-4">http://localhost:6502/signalk/v2/api/vessels/self/radars/nav1034A/controls/guardZone1</span><br/><span class="hl-0">{</span><span class="hl-5">"enabled"</span><span class="hl-5">:true,</span><span class="hl-5">"value"</span><span class="hl-5">:-0.5585,</span><span class="hl-5">"endValue"</span><span class="hl-5">:1.7104,</span><span class="hl-5">"startDistance"</span><span class="hl-5">:100.0,</span><span class="hl-5">"endDistance"</span><span class="hl-5">:232.0}</span>
</code><button type="button">Copy</button></pre>
<ol start="7">
<li><strong>rect</strong></li>
</ol>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">60</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Exclusion zone"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"Rectangular exclusion zone"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"guardZones"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"rect"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasEnabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">100000.0</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>A rect defines a rectangular zone using two corners and a perpendicular width. The corners (x1, y1) and (x2, y2) define one edge of the rectangle in meters relative to the radar position (positive X is starboard, positive Y is ahead). The width extends perpendicular to this edge.</p>
<pre><code class="shell"><span class="hl-5">$</span><span class="hl-0"> </span><span class="hl-4">curl</span><span class="hl-0"> </span><span class="hl-2">-s</span><span class="hl-0"> </span><span class="hl-4">http://localhost:6502/signalk/v2/api/vessels/self/radars/nav1034A/controls/exclusionZone1</span><br/><span class="hl-0">{</span><span class="hl-5">"enabled"</span><span class="hl-5">:true,</span><span class="hl-5">"x1"</span><span class="hl-5">:-50.0,</span><span class="hl-5">"y1"</span><span class="hl-5">:100.0,</span><span class="hl-5">"x2"</span><span class="hl-5">:50.0,</span><span class="hl-5">"y2"</span><span class="hl-5">:100.0,</span><span class="hl-5">"width"</span><span class="hl-5">:200.0}</span>
</code><button type="button">Copy</button></pre>
<h2 id="radar-control" class="tsd-anchor-link">Radar Control<a href="#radar-control" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>Controlling the radar can be done via HTTP REST requests or via the stream websocket.</p>
<h3 id="getting-all-control-values" class="tsd-anchor-link">Getting All Control Values<a href="#getting-all-control-values" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="text">HTTP GET "/signalk/v2/api/vessels/self/radars/{radar_id}/controls"
</code><button type="button">Copy</button></pre>
<p><em>Response:</em></p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"gain"</span><span class="hl-0">: { </span><span class="hl-3">"auto"</span><span class="hl-0">: </span><span class="hl-2">false</span><span class="hl-0">, </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">50</span><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"sea"</span><span class="hl-0">: { </span><span class="hl-3">"auto"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">, </span><span class="hl-3">"autoValue"</span><span class="hl-0">: </span><span class="hl-2">25</span><span class="hl-0">, </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">30</span><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"range"</span><span class="hl-0">: { </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">3000</span><span class="hl-0"> }</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="getting-a-single-control-value" class="tsd-anchor-link">Getting a Single Control Value<a href="#getting-a-single-control-value" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="text">HTTP GET "/signalk/v2/api/vessels/self/radars/{radar_id}/controls/{control_id}"
</code><button type="button">Copy</button></pre>
<p><em>Response:</em></p>
<pre><code class="json"><span class="hl-0">{ </span><span class="hl-3">"auto"</span><span class="hl-0">: </span><span class="hl-2">false</span><span class="hl-0">, </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">50</span><span class="hl-0"> }</span>
</code><button type="button">Copy</button></pre>
<h3 id="setting-a-control-value" class="tsd-anchor-link">Setting a Control Value<a href="#setting-a-control-value" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="text">HTTP PUT "/signalk/v2/api/vessels/self/radars/{radar_id}/controls/{control_id}"
</code><button type="button">Copy</button></pre>
<p><strong>Simple numeric control:</strong></p>
<pre><code class="json"><span class="hl-0">{ </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">75</span><span class="hl-0"> }</span>
</code><button type="button">Copy</button></pre>
<p><strong>Control with auto mode:</strong></p>
<pre><code class="json"><span class="hl-0">{ </span><span class="hl-3">"auto"</span><span class="hl-0">: </span><span class="hl-2">false</span><span class="hl-0">, </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">75</span><span class="hl-0"> }</span>
</code><button type="button">Copy</button></pre>
<p>or just change auto mode:</p>
<pre><code class="json"><span class="hl-0">{ </span><span class="hl-3">"auto"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0"> }</span>
</code><button type="button">Copy</button></pre>
<p><strong>Control with auto adjustment (e.g., Sea on HALO):</strong></p>
<p>When in auto mode, some controls accept an adjustment value:</p>
<pre><code class="json"><span class="hl-0">{ </span><span class="hl-3">"auto"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">, </span><span class="hl-3">"autoValue"</span><span class="hl-0">: </span><span class="hl-2">-20</span><span class="hl-0"> }</span>
</code><button type="button">Copy</button></pre>
<p><strong>Sector control:</strong></p>
<pre><code class="json"><span class="hl-0">{ </span><span class="hl-3">"enabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">, </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">-1.5533</span><span class="hl-0">, </span><span class="hl-3">"endValue"</span><span class="hl-0">: </span><span class="hl-2">-1.2217</span><span class="hl-0"> }</span>
</code><button type="button">Copy</button></pre>
<p><strong>Zone control:</strong></p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"enabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">-0.5585</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"endValue"</span><span class="hl-0">: </span><span class="hl-2">1.7104</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"startDistance"</span><span class="hl-0">: </span><span class="hl-2">100.0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"endDistance"</span><span class="hl-0">: </span><span class="hl-2">500.0</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p><strong>Button control:</strong></p>
<p>For buttons, send an empty body or <code>{}</code> - the PUT request itself triggers the action.</p>
<h3 id="control-value-fields" class="tsd-anchor-link">Control Value Fields<a href="#control-value-fields" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Control values contain different fields depending on the control's <code>dataType</code> (defined in the capability schema).</p>
<p><strong>Common fields</strong>:</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>value</code></td>
<td>The control value (numeric or string) (if dataType is not <code>rect</code>)</td>
</tr>
<tr>
<td><code>auto</code></td>
<td>Whether automatic mode is enabled (if <code>hasAuto</code> is true)</td>
</tr>
<tr>
<td><code>autoValue</code></td>
<td>Adjustment when auto=true (if <code>hasAutoAdjustable</code> is true)</td>
</tr>
<tr>
<td><code>timestamp</code></td>
<td>ISO 8601 timestamp when value was last changed</td>
</tr>
</tbody>
</table>
<p><strong>dataType-specific fields</strong>:</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>dataType</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>enabled</code></td>
<td>sector, zone, rect</td>
<td>Whether the control is enabled</td>
</tr>
<tr>
<td><code>endValue</code></td>
<td>sector, zone</td>
<td>End angle (radians)</td>
</tr>
<tr>
<td><code>startDistance</code></td>
<td>zone</td>
<td>Inner radius (meters)</td>
</tr>
<tr>
<td><code>endDistance</code></td>
<td>zone</td>
<td>Outer radius (meters)</td>
</tr>
<tr>
<td><code>x1</code></td>
<td>rect</td>
<td>First corner X (meters, starboard +)</td>
</tr>
<tr>
<td><code>y1</code></td>
<td>rect</td>
<td>First corner Y (meters, ahead +)</td>
</tr>
<tr>
<td><code>x2</code></td>
<td>rect</td>
<td>Second corner X (meters, starboard +)</td>
</tr>
<tr>
<td><code>y2</code></td>
<td>rect</td>
<td>Second corner Y (meters, ahead +)</td>
</tr>
<tr>
<td><code>width</code></td>
<td>rect</td>
<td>Perpendicular width (meters)</td>
</tr>
</tbody>
</table>
<h2 id="arpa-target-tracking" class="tsd-anchor-link">ARPA Target Tracking<a href="#arpa-target-tracking" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>The Radar API defines ARPA (Automatic Radar Plotting Aid) target tracking with CPA/TCPA calculations and SignalK notification integration.</p>
<p><code>mayara-server</code> fully supports both ARPA and MARPA, but this is an optional part of the API. When a server does not support it it shall
return HTTP status 501.</p>
<p>If the radar is a dual-radar device then <code>mayara-server</code> has a CLI option <code>--merge-targets</code>, when this
is used targets will be shared between both ranges and move from one radar to another.</p>
<h3 id="listing-tracked-targets" class="tsd-anchor-link">Listing Tracked Targets<a href="#listing-tracked-targets" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="text">HTTP GET "/signalk/v2/api/vessels/self/radars/{id}/targets"
</code><button type="button">Copy</button></pre>
<p><em>Response:</em></p>
<pre><code class="json"><span class="hl-0">[</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"status"</span><span class="hl-0">: </span><span class="hl-4">"tracking"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"position"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"bearing"</span><span class="hl-0">: </span><span class="hl-2">0.789</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"distance"</span><span class="hl-0">: </span><span class="hl-2">1852</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"latitude"</span><span class="hl-0">: </span><span class="hl-2">52.3702</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"longitude"</span><span class="hl-0">: </span><span class="hl-2">4.8952</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"motion"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"course"</span><span class="hl-0">: </span><span class="hl-2">3.14159</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"speed"</span><span class="hl-0">: </span><span class="hl-2">3.34</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"danger"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"cpa"</span><span class="hl-0">: </span><span class="hl-2">150</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"tcpa"</span><span class="hl-0">: </span><span class="hl-2">324</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"acquisition"</span><span class="hl-0">: </span><span class="hl-4">"auto"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"sourceZone"</span><span class="hl-0">: </span><span class="hl-2">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"firstSeen"</span><span class="hl-0">: </span><span class="hl-4">"2025-01-15T10:25:00Z"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"lastSeen"</span><span class="hl-0">: </span><span class="hl-4">"2025-01-15T10:30:00Z"</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">]</span>
</code><button type="button">Copy</button></pre>
<p><strong>Units:</strong> All distances are in meters. All angles (bearing, course) are in radians [0, 2π). Speed is in m/s. Time values (tcpa) are in seconds.</p>
<p><strong>Optional fields:</strong> Sub-structures are omitted when data is not yet known or not applicable:</p>
<ul>
<li><code>motion</code>: Omitted when motion is not yet computed (target still acquiring). Present with <code>speed: 0</code> and <code>course: 0</code> for confirmed stationary targets (buoys, anchored vessels).</li>
<li><code>danger</code>: Omitted when vessels are diverging (no CPA exists) or own-ship motion unavailable</li>
<li><code>position.latitude</code>/<code>longitude</code>: Omitted when radar position is unavailable</li>
<li><code>sourceZone</code>: Omitted for manually acquired targets or Doppler-detected targets</li>
</ul>
<h3 id="manual-target-acquisition" class="tsd-anchor-link">Manual Target Acquisition<a href="#manual-target-acquisition" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="text">HTTP POST "/signalk/v2/api/vessels/self/radars/{id}/targets"
</code><button type="button">Copy</button></pre>
<p><em>Request body:</em></p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"bearing"</span><span class="hl-0">: </span><span class="hl-2">0.785</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"distance"</span><span class="hl-0">: </span><span class="hl-2">2000</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="cancel-target-tracking" class="tsd-anchor-link">Cancel Target Tracking<a href="#cancel-target-tracking" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="text">HTTP DELETE "/signalk/v2/api/vessels/self/radars/{id}/targets/{targetId}"
</code><button type="button">Copy</button></pre>
<h2 id="streaming-api-websocket" class="tsd-anchor-link">Streaming API (WebSocket)<a href="#streaming-api-websocket" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>There are two types of websocket:</p>
<ol>
<li>Control Stream: Signal-K-formatted JSON messages containing control information to and from radars, as well as targets.</li>
<li>Spoke Data Stream: High-volume radar spoke data in binary format (up to 1 MB/s).</li>
</ol>
<h2 id="control-stream" class="tsd-anchor-link">Control Stream<a href="#control-stream" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>The JSON data websocket provides real-time control value updates for all radars via the standard Signal K stream.</p>
<p>The URI is found in the radar response as <code>streamUrl</code> or can be constructed as:</p>
<pre><code class="text">ws://{host}:{port}/signalk/v1/stream
</code><button type="button">Copy</button></pre>
<p>This websocket endpoint works identical to a Signal K stream, as documented in
<a href="https://signalk.org/specification/1.5.0/doc/streaming_api.html">https://signalk.org/specification/1.5.0/doc/streaming_api.html</a></p>
<p>In short:</p>
<ul>
<li>By default you are described to all paths</li>
<li>Query parameters <code>subscribe=none</code> can be used to start without any subscriptions and <code>sendCachedValues=false</code> to disable sending all currently cached values. <code>sourcePolicy=all</code> opts the connection into deltas from every source rather than the priority-resolved preferred-only default — see <a href="../Plugins/Processing_Data.html#source-policy">Source Policy</a>.</li>
<li>Subscriptions and desubscriptions can be made for paths. You can use '*' for all radars
including radars still to be discovered.</li>
<li>When first connected all radar meta data will be sent.</li>
<li>When a new radar is discovered all existing streams will also be sent the meta
data for the new radar.</li>
</ul>
<p>The recommended way of connecting is to either send <code>subscribe=none</code> and then a subscribe to all controls, as in the example below, with a policy of <code>instant</code>. The number of updates after the
initial cache dump is low, about 2 messages per second.</p>
<pre><code class="json"><span class="hl-4">"subscribe"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.*.controls.*"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"period"</span><span class="hl-0">: </span><span class="hl-2">1000</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> ]</span>
</code><button type="button">Copy</button></pre>
<p>To receive real-time ARPA target updates, subscribe to the targets path:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"subscribe"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.*.targets.*"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"policy"</span><span class="hl-0">: </span><span class="hl-4">"instant"</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>You can subscribe to both controls and targets simultaneously:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"subscribe"</span><span class="hl-0">: [</span><br/><span class="hl-0"> { </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.*.controls.*"</span><span class="hl-0">, </span><span class="hl-3">"period"</span><span class="hl-0">: </span><span class="hl-2">1000</span><span class="hl-0"> },</span><br/><span class="hl-0"> { </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.*.targets.*"</span><span class="hl-0">, </span><span class="hl-3">"policy"</span><span class="hl-0">: </span><span class="hl-4">"instant"</span><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="controls-1" class="tsd-anchor-link">Controls<a href="#controls-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Example of received meta-data:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"updates"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"$source"</span><span class="hl-0">: </span><span class="hl-4">"mayara"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"timestamp"</span><span class="hl-0">: </span><span class="hl-4">"2026-02-23T18:15:26.409454084Z"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"meta"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.nav1034A.controls.guardZone1"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">13</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Guard zone"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"First guard zone for target detection"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"guardZones"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"zone"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"hasEnabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"minValue"</span><span class="hl-0">: </span><span class="hl-2">-3.141592653589793</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxValue"</span><span class="hl-0">: </span><span class="hl-2">3.141592653589793</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"units"</span><span class="hl-0">: </span><span class="hl-4">"rad"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"maxDistance"</span><span class="hl-0">: </span><span class="hl-2">100000.0</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.nav1034A.controls.firmwareVersion"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">48</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"name"</span><span class="hl-0">: </span><span class="hl-4">"Firmware version"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"description"</span><span class="hl-0">: </span><span class="hl-4">"Version of the radar firmware"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"category"</span><span class="hl-0">: </span><span class="hl-4">"info"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"dataType"</span><span class="hl-0">: </span><span class="hl-4">"string"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"isReadOnly"</span><span class="hl-0">: </span><span class="hl-2">true</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>Example of received data:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"updates"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"$source"</span><span class="hl-0">: </span><span class="hl-4">"mayara"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"values"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.nav1034A.controls.spokes"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: { </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">2048</span><span class="hl-0"> }</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>Example of setting a control:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.nav1034A.controls.guardZone1"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">0.735</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"endValue"</span><span class="hl-0">: </span><span class="hl-2">3.1415</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"startDistance"</span><span class="hl-0">: </span><span class="hl-2">0</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"endDistance"</span><span class="hl-0">: </span><span class="hl-2">500</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"enabled"</span><span class="hl-0">: </span><span class="hl-2">true</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>Target updates are sent whenever a target's position, motion, or status changes:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"updates"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"$source"</span><span class="hl-0">: </span><span class="hl-4">"mayara"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"timestamp"</span><span class="hl-0">: </span><span class="hl-4">"2025-01-15T10:30:00Z"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"values"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.nav1034A.targets.1"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"id"</span><span class="hl-0">: </span><span class="hl-2">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"status"</span><span class="hl-0">: </span><span class="hl-4">"tracking"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"position"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"bearing"</span><span class="hl-0">: </span><span class="hl-2">0.789</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"distance"</span><span class="hl-0">: </span><span class="hl-2">1852</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"latitude"</span><span class="hl-0">: </span><span class="hl-2">52.3702</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"longitude"</span><span class="hl-0">: </span><span class="hl-2">4.8952</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"motion"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"course"</span><span class="hl-0">: </span><span class="hl-2">3.14159</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"speed"</span><span class="hl-0">: </span><span class="hl-2">3.34</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"danger"</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">"cpa"</span><span class="hl-0">: </span><span class="hl-2">150</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"tcpa"</span><span class="hl-0">: </span><span class="hl-2">324</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> </span><span class="hl-3">"acquisition"</span><span class="hl-0">: </span><span class="hl-4">"auto"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"sourceZone"</span><span class="hl-0">: </span><span class="hl-2">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"firstSeen"</span><span class="hl-0">: </span><span class="hl-4">"2025-01-15T10:25:00Z"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"lastSeen"</span><span class="hl-0">: </span><span class="hl-4">"2025-01-15T10:30:00Z"</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<p>Targets are created either automatically (ARPA) or manually (MARPA, via a REST or stream message.)
In all cases the targets go through the following states: <code>acquiring</code> -> <code>tracking</code> -> <code>lost</code>.</p>
<p>When a target is deleted (either because it has been in status <code>lost</code> for a while or a client explicitly deletes it), a final <code>null</code> value is sent:</p>
<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">"updates"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"$source"</span><span class="hl-0">: </span><span class="hl-4">"mayara"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"timestamp"</span><span class="hl-0">: </span><span class="hl-4">"2025-01-15T10:32:00Z"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"values"</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">"path"</span><span class="hl-0">: </span><span class="hl-4">"radars.nav1034A.targets.1"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">"value"</span><span class="hl-0">: </span><span class="hl-2">null</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h2 id="spoke-data-stream" class="tsd-anchor-link">Spoke Data Stream<a href="#spoke-data-stream" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<p>Because radars can produce up to 4 megabytes of data per rotation, this data is transmitted
on a separate websocket <em>per radar</em> and is in a binary format. The data is encoded using <a href="https://protobuf.dev/">Protocol Buffers</a> (protobuf), Google's language-neutral binary serialization format. Protobuf provides compact encoding and fast parsing, with official implementations available for most programming languages including JavaScript, Python, Java, C++, Go, and Rust.</p>
<p>The message schema is stable and will not change within a major version (per <a href="https://semver.org/">semver</a>):</p>
<pre><code class="text">syntax = "proto3";
/*
* The data stream coming from a radar is a series of spokes.
* The number of spokes per revolution is different for each type of
* radar and can be found in the capabilities at
* .../v2/api/vessels/self/radars/{id}/capabilities as 'spokesPerRevolution'.
* The maximum length of each spoke is also defined there, as well as the legend that provides
* a lookup table for each byte of data in the spoke.
*
* The angle and bearing fields below are in terms of spokes, so
* range from [0..spokesPerRevolution>.
*
* Angle is a mandatory field and tells you the rotation of the spoke
* relative to the front of the boat, going clockwise. 0 means directly
* ahead, spokesPerRevolution / 4 is to starboard, spokesPerRevolution / 2 is directly astern, etc.
*
* Bearing, if set, means that either the radar or the radar server has
* enriched the data with a true bearing, e.g. 0 is directly North,
* spokesPerRevolution / 4 is directly West, spokesPerRevolution / 2 is South, etc.
*
* Likewise, time and lat/lon indicate the best effort when the spoke
* was generated, and the lat/lon of the radar at the time of generation.
*
*/
message RadarMessage {
message Spoke {
uint32 angle = 1; // [0..spokesPerRevolution>, angle from bow
optional uint32 bearing = 2; // [0..spokesPerRevolution>, offset from True North
uint32 range = 3; // [meters], range in meters of the last pixel in data
optional uint64 time = 4; // [millis since UNIX epoch] Time when spoke was generated or received
optional double lat = 6; // Location of radar at time of generation
optional double lon = 7; // Location of radar at time of generation
bytes data = 5;
}
repeated Spoke spokes = 2;
}
</code><button type="button">Copy</button></pre>
<p>The URL is found in the <code>radars</code> REST response as <code>spokeDataUrl</code> or can be constructed as:</p>
<pre><code class="text">/signalk/v2/api/vessels/self/radars/{radar_id}/spokes
</code><button type="button">Copy</button></pre>
<h3 id="connection-logic" class="tsd-anchor-link">Connection Logic<a href="#connection-logic" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>This a Javascript example how to set up the connection to receive spokes:</p>
<pre><code class="javascript"><span class="hl-6">// Fetch radars</span><br/><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">response</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> </span><span class="hl-1">await</span><span class="hl-0"> </span><span class="hl-7">fetch</span><span class="hl-0">(</span><span class="hl-4">'/signalk/v2/api/vessels/self/radars/'</span><span class="hl-0">)</span><br/><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">data</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> </span><span class="hl-1">await</span><span class="hl-0"> response.</span><span class="hl-7">json</span><span class="hl-0">()</span><br/><br/><span class="hl-6">// Choose a radar_id from the returned radars</span><br/><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">radarId</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> Object.</span><span class="hl-7">keys</span><span class="hl-0">(data)[</span><span class="hl-2">0</span><span class="hl-0">]</span><br/><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">radar</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> data[radarId]</span><br/><br/><span class="hl-6">// Connect to spoke data stream</span><br/><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">wsUrl</span><span class="hl-0"> </span><span class="hl-1">=</span><br/><span class="hl-0"> radar.spokeDataUrl </span><span class="hl-1">??</span><br/><span class="hl-0"> </span><span class="hl-4">`ws://${</span><span class="hl-0">location</span><span class="hl-4">.</span><span class="hl-0">host</span><span class="hl-4">}/signalk/v2/api/vessels/self/radars/${</span><span class="hl-0">radarId</span><span class="hl-4">}/spokes`</span><br/><br/><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">socket</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> </span><span class="hl-1">new</span><span class="hl-0"> </span><span class="hl-7">WebSocket</span><span class="hl-0">(wsUrl)</span><br/><span class="hl-0">socket.binaryType </span><span class="hl-1">=</span><span class="hl-0"> </span><span class="hl-4">'arraybuffer'</span><br/><br/><span class="hl-0">socket.</span><span class="hl-7">onmessage</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> (</span><span class="hl-5">event</span><span class="hl-0">) </span><span class="hl-1">=></span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-1">const</span><span class="hl-0"> </span><span class="hl-2">spokeData</span><span class="hl-0"> </span><span class="hl-1">=</span><span class="hl-0"> </span><span class="hl-1">new</span><span class="hl-0"> </span><span class="hl-7">Uint8Array</span><span class="hl-0">(event.data)</span><br/><span class="hl-0"> </span><span class="hl-6">// Process binary spoke data...</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="spoke-content-and-the-legend" class="tsd-anchor-link">Spoke content and the legend<a href="#spoke-content-and-the-legend" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Every spoke contains <code>spoke_len</code> bytes. The radar API always uses one byte per pixel, with every byte representing a value explained by the <code>legend</code> contained in the capabilities.</p>
<p>The legend provides a lookup table mapping each byte value to its meaning and suggested display color:</p>
<ul>
<li><strong>Byte values 0 to <code>pixelColors - 1</code></strong>: Normal radar returns, ranging from no echo (0) to strongest echo. The <code>lowReturn</code>, <code>mediumReturn</code>, and <code>strongReturn</code> fields indicate thresholds within this range, useful for smoothing or color gradient algorithms.</li>
<li><strong>Byte value at <code>targetBorder</code></strong>: Indicates the edge of a tracked ARPA target.</li>
<li><strong>Byte value at <code>dopplerApproaching</code></strong>: Object moving toward the radar (requires Doppler-capable radar).</li>
<li><strong>Byte value at <code>dopplerReceding</code></strong>: Object moving away from the radar (requires Doppler-capable radar).</li>
<li><strong>Byte values from <code>historyStart</code> onward</strong>: Historical trail data showing where targets were in previous rotations.</li>
</ul>
<p>The <code>pixels</code> array provides the complete mapping from byte value to RGBA color. Clients can use this directly for rendering, or implement their own color scheme based on the semantic pixel types (<code>normal</code>, <code>targetBorder</code>, <code>dopplerApproaching</code>, <code>dopplerReceding</code>, <code>history</code>).</p>
<p>If the radar doesn't support a feature, the corresponding legend field will be absent or null (e.g., <code>dopplerApproaching</code> and <code>dopplerReceding</code> are absent for non-Doppler radars).</p>
<p>In a later API release it is likely that the legend will be expanded to contain color mappings for different palettes.</p>
<h3 id="spoke-skipping" class="tsd-anchor-link">Spoke skipping<a href="#spoke-skipping" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>Some radars have a high value for <code>spokesPerRevolution</code> but actually only produce fewer spokes
per each revolution. This is true for Furuno radars but not the other
supported radars from Garmin, Navico and Raymarine. The Furuno radars set <code>hasSparseSpokes</code> in
the capabilities struct to <code>true</code>.</p>
<p>A conforming GUI must allow for this and either implement some way to expand missing spokes or
to reconsider the width of spokes to be from the angle/bearing from the received spoke to the
previously received spoke.</p>
<p>A typical value for Furuno is to have <code>spokesPerRevolution = 8192</code> but the actual # of spokes
will be ~ 900. Weirdly enough it is not a "round" figure like 1440, 2048, 512 or 250 like the
other radars.</p>
<h2 id="typescript-interfaces" class="tsd-anchor-link">TypeScript Interfaces<a href="#typescript-interfaces" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<h3 id="radarsresponse" class="tsd-anchor-link">RadarsResponse<a href="#radarsresponse" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">RadarsResponse</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">version</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">radars</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-5">Record</span><span class="hl-0"><</span><span class="hl-2">string</span><span class="hl-0">, </span><span class="hl-5">RadarInfo</span><span class="hl-0">></span><br/><span class="hl-0">}</span><br/><br/><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">RadarInfo</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">name</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">brand</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">model</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">radarIpAddress</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">spokeDataUrl</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">streamUrl</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="capabilities" class="tsd-anchor-link">Capabilities<a href="#capabilities" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">Capabilities</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">maxRange</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">minRange</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">supportedRanges</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0">[]</span><br/><span class="hl-0"> </span><span class="hl-5">spokesPerRevolution</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">maxSpokeLength</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">pixelValues</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">hasDoppler</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">hasDualRadar</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">hasDualRange</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">hasSparseSpokes</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">noTransmitSectors</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">controls</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-5">Record</span><span class="hl-0"><</span><span class="hl-2">string</span><span class="hl-0">, </span><span class="hl-5">ControlDefinition</span><span class="hl-0">></span><br/><span class="hl-0"> </span><span class="hl-5">legend</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-5">Legend</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="controldefinition" class="tsd-anchor-link">ControlDefinition<a href="#controldefinition" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">ControlDefinition</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">id</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">name</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">description</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">category</span><span class="hl-1">:</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'base'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'targets'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'guardZones'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'trails'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'advanced'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'installation'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'info'</span><br/><span class="hl-0"> </span><span class="hl-5">dataType</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-4">'number'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'enum'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'string'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'button'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'sector'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'zone'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'rect'</span><br/><span class="hl-0"> </span><span class="hl-5">isReadOnly</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">hasEnabled</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">minValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">maxValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">stepValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">maxDistance</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">units</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-4">'m'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'m/s'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'rad'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'rad/s'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'s'</span><br/><span class="hl-0"> </span><span class="hl-5">descriptions</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-5">Record</span><span class="hl-0"><</span><span class="hl-2">string</span><span class="hl-0">, </span><span class="hl-2">string</span><span class="hl-0">> </span><span class="hl-6">// For enum types</span><br/><span class="hl-0"> </span><span class="hl-5">validValues</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0">[] </span><span class="hl-6">// For enum types</span><br/><span class="hl-0"> </span><span class="hl-5">hasAuto</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">hasAutoAdjustable</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">autoAdjustMinValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">autoAdjustMaxValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="controlvalue" class="tsd-anchor-link">ControlValue<a href="#controlvalue" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">ControlValue</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">value</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0"> </span><span class="hl-5">units</span><span class="hl-1">?:</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'m'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'km'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'nm'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'m/s'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'kn'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'rad'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'deg'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'rad/s'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'rpm'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'s'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'min'</span><br/><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'h'</span><br/><span class="hl-0"> </span><span class="hl-5">auto</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">autoValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">enabled</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">boolean</span><br/><span class="hl-0"> </span><span class="hl-5">endValue</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// End angle for sectors/zones (radians)</span><br/><span class="hl-0"> </span><span class="hl-5">startDistance</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Inner radius for zones (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">endDistance</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Outer radius for zones (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">x1</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Rect: first corner X (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">y1</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Rect: first corner Y (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">x2</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Rect: second corner X (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">y2</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Rect: second corner Y (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">width</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// Rect: perpendicular width (meters)</span><br/><span class="hl-0"> </span><span class="hl-5">timestamp</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">string</span><span class="hl-0"> </span><span class="hl-6">// ISO 8601 timestamp when value was last changed</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="legend-1" class="tsd-anchor-link">Legend<a href="#legend-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">Legend</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">lowReturn</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">mediumReturn</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">strongReturn</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">targetBorder</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">dopplerApproaching</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">dopplerReceding</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">historyStart</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">pixelColors</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">pixels</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-5">LegendPixel</span><span class="hl-0">[]</span><br/><span class="hl-0">}</span><br/><br/><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">LegendPixel</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">type</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-4">'normal'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'dopplerApproaching'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'dopplerReceding'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'history'</span><br/><span class="hl-0"> </span><span class="hl-5">color</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h3 id="target" class="tsd-anchor-link">Target<a href="#target" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<pre><code class="typescript"><span class="hl-1">interface</span><span class="hl-0"> </span><span class="hl-5">Target</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">id</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><br/><span class="hl-0"> </span><span class="hl-5">status</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-4">'tracking'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'lost'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'acquiring'</span><br/><span class="hl-0"> </span><span class="hl-5">position</span><span class="hl-1">:</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-5">bearing</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// radians [0, 2π)</span><br/><span class="hl-0"> </span><span class="hl-5">distance</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// meters</span><br/><span class="hl-0"> </span><span class="hl-5">latitude</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// omitted if radar position unavailable</span><br/><span class="hl-0"> </span><span class="hl-5">longitude</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// omitted if radar position unavailable</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> </span><span class="hl-5">motion</span><span class="hl-1">?:</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-6">// omitted if motion not yet computed; present with zeros for stationary targets</span><br/><span class="hl-0"> </span><span class="hl-5">course</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// radians [0, 2π)</span><br/><span class="hl-0"> </span><span class="hl-5">speed</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// m/s</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> </span><span class="hl-5">danger</span><span class="hl-1">?:</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-6">// omitted if vessels diverging or own-ship motion unavailable</span><br/><span class="hl-0"> </span><span class="hl-5">cpa</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// meters</span><br/><span class="hl-0"> </span><span class="hl-5">tcpa</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// seconds</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> </span><span class="hl-5">acquisition</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-4">'manual'</span><span class="hl-0"> </span><span class="hl-1">|</span><span class="hl-0"> </span><span class="hl-4">'auto'</span><br/><span class="hl-0"> </span><span class="hl-5">sourceZone</span><span class="hl-1">?:</span><span class="hl-0"> </span><span class="hl-2">number</span><span class="hl-0"> </span><span class="hl-6">// guard zone (1 or 2) that acquired this target; omitted for manual/Doppler</span><br/><span class="hl-0"> </span><span class="hl-5">firstSeen</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><span class="hl-0"> </span><span class="hl-6">// ISO 8601 timestamp</span><br/><span class="hl-0"> </span><span class="hl-5">lastSeen</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-2">string</span><span class="hl-0"> </span><span class="hl-6">// ISO 8601 timestamp</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
</div></div><div class="col-sidebar"><div class="page-menu"><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#design-philosophy-capabilities-driven-api"><span>Design <wbr/>Philosophy: <wbr/>Capabilities-<wbr/>Driven <wbr/>API</span></a><ul><li><a href="#for-clientchartplotter-developers"><span>For <wbr/>Client/<wbr/>Chartplotter <wbr/>Developers</span></a></li><li><a href="#for-radar-provider-developers-plugin-authors"><span>For <wbr/>Radar <wbr/>Provider <wbr/>Developers (<wbr/>Plugin <wbr/>Authors)</span></a></li></ul><a href="#control-categories"><span>Control <wbr/>Categories</span></a><a href="#api-overview"><span>API <wbr/>Overview</span></a><a href="#rest-api"><span>REST <wbr/>API</span></a><ul><li><a href="#listing-all-radars"><span>Listing <wbr/>All <wbr/>Radars</span></a></li><li><a href="#network-interfaces"><span>Network <wbr/>Interfaces</span></a></li><li><a href="#getting-radar-capabilities"><span>Getting <wbr/>Radar <wbr/>Capabilities</span></a></li><li><a href="#legend"><span>Legend</span></a></li><li><a href="#dual-rangeradar"><span>Dual range/radar</span></a></li><li><a href="#controls"><span>Controls</span></a></li></ul><a href="#radar-control"><span>Radar <wbr/>Control</span></a><ul><li><a href="#getting-all-control-values"><span>Getting <wbr/>All <wbr/>Control <wbr/>Values</span></a></li><li><a href="#getting-a-single-control-value"><span>Getting a <wbr/>Single <wbr/>Control <wbr/>Value</span></a></li><li><a href="#setting-a-control-value"><span>Setting a <wbr/>Control <wbr/>Value</span></a></li><li><a href="#control-value-fields"><span>Control <wbr/>Value <wbr/>Fields</span></a></li></ul><a href="#arpa-target-tracking"><span>ARPA <wbr/>Target <wbr/>Tracking</span></a><ul><li><a href="#listing-tracked-targets"><span>Listing <wbr/>Tracked <wbr/>Targets</span></a></li><li><a href="#manual-target-acquisition"><span>Manual <wbr/>Target <wbr/>Acquisition</span></a></li><li><a href="#cancel-target-tracking"><span>Cancel <wbr/>Target <wbr/>Tracking</span></a></li></ul><a href="#streaming-api-websocket"><span>Streaming <wbr/>API (<wbr/>Web<wbr/>Socket)</span></a><a href="#control-stream"><span>Control <wbr/>Stream</span></a><ul><li><a href="#controls-1"><span>Controls</span></a></li></ul><a href="#spoke-data-stream"><span>Spoke <wbr/>Data <wbr/>Stream</span></a><ul><li><a href="#connection-logic"><span>Connection <wbr/>Logic</span></a></li><li><a href="#spoke-content-and-the-legend"><span>Spoke content and the legend</span></a></li><li><a href="#spoke-skipping"><span>Spoke skipping</span></a></li></ul><a href="#typescript-interfaces"><span>Type<wbr/>Script <wbr/>Interfaces</span></a><ul><li><a href="#radarsresponse"><span>Radars<wbr/>Response</span></a></li><li><a href="#capabilities"><span>Capabilities</span></a></li><li><a href="#controldefinition"><span>Control<wbr/>Definition</span></a></li><li><a href="#controlvalue"><span>Control<wbr/>Value</span></a></li><li><a href="#legend-1"><span>Legend</span></a></li><li><a href="#target"><span>Target</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../../modules.html">Signal K</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>