Skip to content

Sonardyne API Overview

The Sonardyne API allows supported devices to be programmatically controlled.

The underlying technologies are gRPC and Protocol Buffers (Protobuf), which support a number of programming languages. The examples in this documentation are written in Python and make use of the wrappers which are packaged up with the Sonardyne API Python library.

The API supports gRPC as a transport mechanism, as well as supporting two non-gRPC alternatives detailed below.

  • The API supports sending and receiving messages using the Framed protocol, which encodes serialised Protobuf messages using Consistent Overhead Byte Stuffing (COBS). One reason to use the Framed protocol is that it removes gRPC as a dependency, which may be preferable in some use cases. For more information on the Framed protocol, see Using Non-gRPC Modes.
  • The API also supports sending and receiving messages as JSON. This is not only useful for debugging (as JSON messages are human-readable), but it also removes both gRPC and Protobuf as dependencies. Each example has a "Raw JSON" version which demonstrates how these messages could be sent and received without Protobuf or gRPC.

Services

The API provides services which all follow a regular pattern.

Service Sends and receives Envelope contains What is this for?
ConfigurationService ConfigurationEnvelope [name]Configuration Set/Get e.g. set lever arms
CommandService CommandEnvelope [name]Command Run Task e.g. reset INS
ObservationService ObservationEnvelope [name]Observation In/Out stream of data e.g. GNSS received
CommsService CommsEnvelope [name]Comms In/Out stream of comms data e.g. write to serial

Configuration Service

The configuration service is used for setting and getting configurations. For each configuration sent in an envelope, we can expect the same configuration types returned in the same order. Configurations contain a result to signify the success of the configuration application.

The configuration service provides a ConfigurationStream, which outputs any configurations which change. Listening on the ConfigurationStream is an efficient way to track the entire state of the product you are connected to.

Typically, all fields in a configuration are optional. This allows the application of partial configurations.

Command Service

The command service is for command and control. Whereas the configuration service is used to configure the state of a product (typically at startup), the command service is used to perform actions (typically throughout runtime) such as algorithm resets, triggering acoustics or commanding the system to shut down.

Observation Service

The observation service provides a bidirectional stream, allowing us to send and listen to observations. An observation is a piece of structured data e.g. a GNSS observation containing latitude and longitude fields, unlike comms which is unstructured data, containing a variable number of raw bytes.

Example use cases for the observation services are streaming data from a pressure sensor, streaming GNSS readings from a GNSS source, and streaming navigation solutions from a navigation module.

For information on subscribing to observation streams, see Subscribing to Streams.

Comms Service

The comms service allows bidirectional communication with data ports e.g. ethernet ports and serial ports. This allows monitoring of incoming and outgoing data over a port, or the sending of data out over a port.

An example comms message as JSON:

{
 "@type": "type.googleapis.com/sonardyne.api.services.comms_service.CommsEnvelope",
 "comms_messages": [
  {
   "@type": "type.googleapis.com/sonardyne.api.common.ports.DataPortComms",
   "uid": {
    "value": "1518954244",
    "name": "TCP-8110"
   },
   "timestamp": {
    "common_time_seconds": 1765206239.1132329,
    "instrument_time_seconds": 251542.067792193
   },
   "data_direction": "DATA_DIRECTION_OUTPUT",
   "data": "SGVsbG8gV29ybGQhIDUw"
  }
 ]
}
A CommsEnvelope containing a DataPortComms message with bytes to output over a TCP port named TCP-8110. Note that although these bytes are not human-readable in the serialised JSON, they do deserialise to a human-readable string.

Message Types

The API makes use of message suffixes which give information on how a message may be used.

  • There are messages which represent a component of the device.
  • There are messages which represent a reference to a component.
  • There are common messages which represent commonly used concepts (e.g. ethernet ports) and have no required suffix.

Component Messages

A product can be considered as a collection of components. These components are modules, algorithms, sources, and port lists.

Component Message name must be Can be combined with service names e.g.
Module [name]Module [name]ModuleConfiguration
Algorithm [name]Algorithm [name]AlgorithmCommand
Source [name]Source [name]SourceObservation
Sensor [name]Sensor [name]SensorObservation
Port List [name]PortList [name]PortListComms

Modules

The Module component represents non-algorithm, non-sensor, non-data source components e.g. a BatteryModule is responsible for managing a battery and enabling/disabling charging. Another example module is the NetworkModule.

  • BatteryModule Allows battery management e.g. enabling charging.
  • DeviceInstallationModule Allows configuration of the device's lever arms & mounting angles relative to the vessel.
  • DeviceModule Allows reading of product name and serial number as well as sending of shutdown & factory reset commands.
  • ExternalLoggingModule Allows configuration of logging to an external client via a TCP server.
  • NavigationModule Allows streaming of navigation solutions, in SPRINT this is the combined result of the AHRS & INS algorithm.
  • NetworkModule Allows configuration of the device's network interface e.g. changing the device IP address.
  • OutputMessageModule Allows configuration of output messages over data ports e.g. outputting GGA messages on a serial port.
  • PortLinkModule Allows bidirectional routing between a serial and ethernet port.
  • RemotePointsModule Allows configuration of remote points on the vessel, the navigation module can output data valid at these remote points.
  • SprintModule Allows reading of SPRINT-specific device information.
  • TimeModule Allows selection of time input sources in order to set UTC and instrument time.

An example request and response sent as JSON:

{
  "@type": "type.googleapis.com/sonardyne.api.common.envelope.RequestEnvelope",
  "uid": 1,
  "requests": [
    {
      "@type": "type.googleapis.com/sonardyne.api.services.configuration_service.SetConfigurationRequest",
      "configuration": {
        "@type": "type.googleapis.com/sonardyne.api.modules.battery_module.BatteryModuleConfiguration",
        "isBatteryChargingEnabled": false
      }
    }
  ]
}
A request to disable battery charging.
{
 "@type": "type.googleapis.com/sonardyne.api.common.envelope.ResponseEnvelope",
 "uid": 1,
 "responses": [
  {
   "@type": "type.googleapis.com/sonardyne.api.services.configuration_service.SetConfigurationResponse",
   "timestamp": {
    "common_time_seconds": 1765193736.1050346,
    "instrument_time_seconds": 239039.059659313
   },
   "configuration": {
    "@type": "type.googleapis.com/sonardyne.api.modules.battery_module.BatteryModuleConfiguration",
    "uid": {
     "value": "2388163018",
     "name": "Output Message Module"
    },
    "is_battery_charging_enabled": false
   },
   "result": {
    "success": "OUTCOME_SUCCESS"
   }
  }
 ]
}
The response to the battery module configuration request.

Algorithms

The Algorithm component represents internal algorithms e.g. an INS algorithm.

  • AhrsAlgorithm Allows sending of reset commands and configuring AHRS coarse latitude and longitude.
  • InsAlgorithm Allows sending of reset commands and configuring INS aiding.
  • DvlAlgorithm Allows configuration of DVL algorithm settings e.g. max ping rate & trigger inputs.

An example request and response sent as JSON:

{
  "@type": "type.googleapis.com/sonardyne.api.common.envelope.RequestEnvelope",
  "uid": 2,
  "requests": [
    {
      "@type": "type.googleapis.com/sonardyne.api.services.configuration_service.SetConfigurationRequest",
      "configuration": {
        "@type": "type.googleapis.com/sonardyne.api.algorithms.ins_algorithm.InsAlgorithmConfiguration",
        "isGnssEnabled": true,
        "isXposEnabled": false
      }
    }
  ]
}
A request to enable GNSS aiding to the INS, and to disable XPOS aiding.
{
 "@type": "type.googleapis.com/sonardyne.api.common.envelope.ResponseEnvelope",
 "uid": 2,
 "responses": [
  {
   "@type": "type.googleapis.com/sonardyne.api.services.configuration_service.SetConfigurationResponse",
   "timestamp": {
    "common_time_seconds": 1765193984.8364909,
    "instrument_time_seconds": 239287.79105141
   },
   "configuration": {
    "@type": "type.googleapis.com/sonardyne.api.algorithms.ins_algorithm.InsAlgorithmConfiguration",
    "uid": {
     "value": "3646079212",
     "name": "INS Algorithm"
    },
    "is_gnss_enabled": true,
    "is_susbl_enabled": true,
    "is_xpos_enabled": false
   },
   "result": {
    "success": "OUTCOME_SUCCESS"
   }
  }
 ]
}
The response to the INS algorithm configuration request. Note that other aiding sources (SUSBL, in this case) are left unchanged.

Sources

The Source component represents "aiding" or "input" sources e.g. GNSS or Time. These sources typically have configurable lever arms. The SPRINT Nav has a pressure sensor and a depth source. The depth source selects either a data port (receiving depth messages e.g. PSONPD) or a built-in pressure sensor for use as the source of depth.

  • DepthSource Allows configuration of a data port or pressure sensor for deriving depth.
  • GnssSource Allows configuration of a data port for a GNSS input (receiving GGA & GST messages).
  • SoundVelocitySource Allows configuration of a manual value, data port, or derived sound velocity.
  • SusblSource Allows configuration of a data port for an SUSBL input (receiving PSIMSSB messages).
  • NtpTimeSource Allows configuration of a connection to an NTP server.
  • ZdaTimeSource Allows configuration of a data port for a ZDA input (receiving ZDA messages).
  • PpsTimeSource Allows configuration of a trigger port for a 1-pulse-per-second time input.
  • XposSource Allows configuration of a data port for an XPOS input (receiving XPOS messages).

Many of the sources support observation streaming, which allows the monitoring of data received by these sources e.g. a GnssSourceObservation.

Sources typically have lever arms, and may have mounting angles, which relate their position to the Vessel's common reference point.

Sensors

The Sensor component represents physical devices which observe data. The observation stream can be used to monitor these observations. Example sensors are depth, temperature - these can be configured using the Configuration Service.

  • DvlSensor Represents a doppler velocity log (DVL) on the device.
  • PressureSensor Represents a pressure sensor on the device.
  • TemperatureSensor Represents a temperature sensor on the device.

Port Lists

The Port List component represents collections of data inputs/outputs. Some port lists, e.g. ethernet port lists, can have entries added and removed. Other port lists, e.g. serial port lists, represent physical ports on the device and are fixed length. On a data port such as a SerialPort or an EthernetPort, it is possible to send and receive bytes using the CommsService.

  • EthernetPortList Allows adding, removing & configuring of TCP & UDP ports, these may be used as inputs to supported sources, and can be set as outputs in the output message module.
  • ExternalControlPortList Represents external control ports on the device, these may be used as inputs to supported sources.
  • PowerPassPortList Allows management of power pass ports (e.g. enabling/disabling).
  • SerialPortList Allows management of serial ports (e.g. setting baud rate), these may be used as inputs to supported sources, and can be set as outputs in the output message module.
  • TriggerPortList Allows management of trigger ports.

Common Messages

Unlike the component messages, the common messages have no required suffixes. Common messages may only contain other common messages, whereas component messages may contain other component messages and common messages.

Common messages include LeverArms, MountingAngles, EthernetPort, SerialPort, and more. Common messages also include the RequestEnvelope and ResponseEnvelope - to see how these are used, see Using Non-gRPC Modes.

Additional Message Types

Reference Messages

Messages ending in the word "Reference" allow one message to point to another. Note that these references are read-only.

import sonardyne_api as son
with son.WrapperGrpc('0.0.0.0', 8103) as wrapper:  # Device IP address & gRPC port:
    result = wrapper.set_configuration(son.GnssSourceConfiguration(input_data_port=son.DataPortReference(set_uid=son.UniqueID(name="TCP-5000"))))
    print(result)
In this example, the input_data_port of a GNSS source is set using a DataPortReference. the DataPortReference references a data port - an ethernet, serial, or external control port. The DataPortReference can be set using set_uid, which allows us to refer to other configuration by unique ID value or by name.

son.DataPortReference(set_uid=son.UniqueID(name="TCP-5000"))
son.DataPortReference(set_uid=son.UniqueID(value=3245395109))
The data port reference has "set" fields which are used to reference to a particular data port.
son.DataPortReference(set_none=True)
The set_none field may be used to clear the reference.
son.DataPortReference(set_any_ethernet_port=True)
son.DataPortReference(set_any_external_control_port=True)
son.DataPortReference(set_any_serial_port=True)
The data port reference also has set_any fields, these allow data port references to be set when no unique ID values are known.

Below is an example of a DataPortReference being set:

import sonardyne_api as son
with son.WrapperJsonTcp('0.0.0.0', 8111) as wrapper:  # Device IP address & gRPC port:
    print(wrapper.set_configuration(son.GnssSourceConfiguration(input_data_port=son.DataPortReference(set_uid=son.UniqueID(name="TCP-5000")))))
When using the JSON interface over a TCP server (in this example on port 8111) the following message contents can be observed; these can be seen by using the 'Comms Viewer' functionality in the SPRINT-Nav UI.
{
  "@type": "type.googleapis.com/sonardyne.api.common.envelope.RequestEnvelope",
  "uid": 1,
  "requests": [
    {
      "@type": "type.googleapis.com/sonardyne.api.services.configuration_service.SetConfigurationRequest",
      "configuration": {
        "@type": "type.googleapis.com/sonardyne.api.sources.gnss_source.GnssSourceConfiguration",
        "inputDataPort": {
          "setUid": {
            "name": "TCP-5000"
          }
        }
      }
    }
  ]
}
This is the JSON message sent by the running the example, with the partially populated inputDataPort field.
{
 "@type": "type.googleapis.com/sonardyne.api.common.envelope.ResponseEnvelope",
 "uid": 10,
 "responses": [
  {
   "@type": "type.googleapis.com/sonardyne.api.services.configuration_service.SetConfigurationResponse",
   "timestamp": {
    "common_time_seconds": 1764954922.1296844,
    "instrument_time_seconds": 225.084287999
   },
   "configuration": {
    "@type": "type.googleapis.com/sonardyne.api.sources.gnss_source.GnssSourceConfiguration",
    "uid": {
     "value": "887217899",
     "name": "GNSS Source"
    },
    "input_data_port": {
     "readonly_uid": {
      "value": "3245395109",
      "name": "TCP-5000"
     },
     "readonly_ethernet_port_reference": {
      "uid": {
       "value": "3245395109",
       "name": "TCP-5000"
      },
      "source_port": 5000,
      "data_encoding": "DATA_ENCODING_NONE",
      "tcp_server": {
       "maximum_connections": 20
      }
     }
    },
    "lever_arms": {},
    "fallback_horizontal_uncertainty_metres": 5,
    "scale_uncertainty": 1,
    "gnss_depth_mode": "GNSS_DEPTH_MODE_ELLIPSOIDAL"
   },
   "result": {
    "success": "OUTCOME_SUCCESS"
   }
  }
 ]
}
This is the received message, with the fully populated inputDataPort (with input_data_port and readonly_ethernet_port_reference fields).

The data port reference has "set" fields, and "readonly" fields. The readonly fields are populated when a data port reference is returned from the device.

Using Non-gRPC Modes

The API may be used without gRPC by sending proto messages as either JSON or Framed binary messages. Framed messages are serialised Protobuf messages wrapped in a Sonardyne Simple Binary Message and COBS encoded.

In non-gRPC modes, only message types ending in "Envelope" can be sent over the API. For example, a RequestEnvelope can be sent as JSON and a corresponding ResponseEnvelope will be returned. These envelopes can be matched by setting the UID on the RequestEnvelope.

A RequestEnvelope can contain any number of messages ending in "Request" e.g. SetConfigurationRequest or SendCommandRequest, and the returned ResponseEnvelope will match one to one with responses e.g. (SetConfigurationResponse or SendCommandResponse).

When streaming data in or out over non-gRPC modes, the ObservationEnvelope is used. When subscribing to changing configurations, the ConfigurationEnvelopes is used. For more information on subscribing to streams, see Subscribing to Streams.

Subscribing to Streams

Several services allow data streaming, these are:

  • ObservationStream (on the ObservationService). Allows the monitoring of outputs from components e.g. streaming out readings from a PressureSensor or GnssSource. Data can also be streamed into these components e.g. streaming GnssSourceObservations into a GnssSource.
  • CommsStream (on the CommsService). Allows the monitoring of data being sent and received over serial and ethernet, also allows data to be sent out over these ports.
  • ConfigurationStream (on the ConfigurationService). Allows the monitoring changing configurations.

Messages ending in "SubscriptionRequest" (e.g. CommsSubscriptionRequest) allow the setting of matching and rejection criteria based on message typenames and UniqueIDs.

For example, possible subscriptions include:

  • All messages with a specified suffix e.g. "SensorObservation".
  • All messages excluding a specified suffix e.g. "Observation" messages excluding "SourceObservation".
  • All messages matching a specified unique ID name e.g. "GNSS Source.
  • All messages matching a specified unique ID value e.g. 19572865462 (supposing this is the UID of a particular component).

Streams can be subscribed to by sending a "SubscriptionRequest" message. For example, an ObservationSubscriptionRequest can be sent to the ObservationStream on the observation service to listen to pressure sensor readings.

The ConfigurationSubscriptionRequest may be used to monitor changing configurations.

The CommsSubscriptionRequest may be used to monitor incoming and outgoing data over a port (serial or ethernet). The CommsEnvelope allows the sending of data out over a port, and must contain messages ending in "Comms" e.g. DataPortComms.