Nyx Node
Loading...
Searching...
No Matches
Protocol

This page describes the Nyx protocol, a thin and backward-compatible overlay on the INDI protocol. INDI was originally designed to control astronomical hardware but is quite generic. Nyx preserves the INDI property/state model and message semantics while modernizing transport and serialization. By default, Nyx exchanges JSON messages over an MQTT broker, with a 1:1 mapping to INDI’s XML messages. It can also speak the original INDI XML directly over TCP for strict compatibility.

In addition, Nyx introduces an additional streaming system, to deliver data to multiple clients.

INDI protocol

This section summarizes version 1.7 of the INDI protocol. For the normative specification (message grammar, semantics, etc.), see the official INDI.pdf.

Purpose and model

INDI is a small, XML-based protocol to control devices through properties. A device exposes named properties (vectors of elements) and a client reads and changes them. Messages are asynchronous: there is no strict request/response pairing and participants must accept any valid message at any time. Malformed or unexpected input should be ignored rather than negotiated.

Discovery (introspection)

A client begins by asking device to describe itself. The client may request all devices, all properties of one device, or one specific property. Devices answer with definitions that fully describe each property and its elements.

<!-- Client → Device: ask for properties of all devices -->
<getProperties version="1.7"/>
<!-- Client → Device: ask for properties of the "Mount" device -->
<getProperties version="1.7" device="Mount"/>
<!-- Device → Client: define a number vector with two elements -->
<defNumberVector device="Mount" name="EQUATORIALJ2000_COORD" state="Idle" perm="rw" timeout="50" label="J2000 Equatorial">
<defNumber name="RA" label="RA H:M:S" format="%11.8m" min="0" max="24">0</defNumber>
<defNumber name="Dec" label="Dec D:M:S" format="%9.6m" min="-90" max="90">0</defNumber>
</defNumberVector>

Definitions exist for text, number, switch, light, and BLOB vectors (defTextVector, defNumberVector, defSwitchVector, defLightVector, defBLOBVector). Each element has a name and optional label. Numbers add display format, min, max, and step. Switches can announce a UI rule such as OneOfMany, AtMostOne or AnyOfMany.

State, permissions, and timeouts

Every property carries a state among Idle, Ok, Busy, and Alert. Devices should also send human-readable messages and timestamps alongside state changes. Permissions are hints for clients: text and number vectors can be ro (read-only), wo (write-only), or rw (read-write); switches can be ro or rw; lights are ro. The timeout value, in seconds, expresses the worst-case duration for the device to accomplish a change, allowing clients to reason about progress and failure.

<setLightVector device="Building" name="Security" state="Alert" timestamp="2002-03-13T16:06:20">
<oneLight name="Dock">Alert</oneLight>
</setLightVector>

Numeric value format

Numeric values are carried as strings and may be integer, real, or sexagesimal. A property may specify either a standard C printf format or the INDI sexagesimal spec %<w>.<f>m, where<w> is the total number of characters and <f> the fraction style:

<f>=9 → :mm:ss.ss
<f>=8 → :mm:ss.s
<f>=6 → :mm:ss
<f>=5 → :mm.m
<f>=3 → :mm

For example:

"%7.3m" → "-123:45"
"%9.6m" → " 0:01:02"

Changing values (Client → Device)

To change a property, the client sends a target message and immediately considers the property Busy until the device reports completion. For numbers and text, the client should send all elements; other types may carry only the changed members.

<!-- Set two numbers atomically -->
<newNumberVector device="Mount" name="EQUATORIALJ2000_COORD">
<oneNumber name="RA">10:20:30</oneNumber>
<oneNumber name="Dec">-04:05:06</oneNumber>
</newNumberVector>
<!-- Select one binning option; the device enforces OneOfMany -->
<newSwitchVector device="Camera" name="Binning">
<oneSwitch name="Two">On</oneSwitch>
</newSwitchVector>

Reporting values (Device → Client)

Devices report current values with setXXXVector messages and may include a new state, timeout, and a timestamped message. For rapidly changing values, devices should avoid flooding slower clients.

<setSwitchVector device="Camera" name="Binning" state="Ok" timestamp="2002-03-13T16:04:02" message="Binning 2:1 selected">
<oneSwitch name="One">Off</oneSwitch>
<oneSwitch name="Two">On</oneSwitch>
</setSwitchVector>

Transferring binary data (BLOBs)

BLOB elements carry base64-encoded payloads with a format hint (e.g., .fits or .fits.z) and a decoded size. Clients control BLOB flow per connection with enableBLOB: Never disables all setBLOB messages on that connection, Also permits setBLOB messages alongside normal INDI traffic, and Only restricts the connection to setBLOB messages exclusively.

<!-- Client opts in to receive BLOBs from this device -->
<enableBLOB device="Wonder Cam">Also</enableBLOB>
<!-- Device sends a BLOB update -->
<setBLOBVector device="Wonder Cam" name="Image" state="Ok" timestamp="2002-03-13T16:05:00">
<oneBLOB name="CCD1" size="16777216" format=".fits">BASE64…</oneBLOB>
</setBLOBVector>

Messages and deletions

Devices can send human-oriented message elements, optionally tied to a device, to narrate progress or issues. They can also announce that a property—or an entire device—is no longer available with delProperty.

<message device="Camera" timestamp="2002-03-13T16:06:20" message="TEC is approaching target temperature"/>
<delProperty device="FilterWheel" name="Filters" timestamp="2002-03-13T16:07:00" message="Wheel disconnected"/>

Snooping other devices

Any device—or client—may subscribe to messages about other devices and properties by issuing getProperties with device and optional name. From that point, matching defXXX and setXXX traffic is mirrored to the requester, enabling coordination and higher-level behaviors.

<!-- Start snooping the Environment.Now property -->
<getProperties device="Environment" name="Now"/>

Nyx protocol

XML → JSON mapping

Nyx mirrors INDI’s XML as JSON with a minimal, lossless mapping: the element name is stored under "<>", attributes use an "@" prefix, text content goes under "$", and child elements appear in a "children" array (order preserved). Values are strings by design; clients parse numbers where needed.

Example — Client → Device (ask for properties):

{
"<>": "getProperties",
"@version": "1.7",
"@device": "Mount"
}

Example — Device → Client (define a number vector):

{
"<>": "defNumberVector",
"@device": "Mount",
"@name": "EQUATORIALJ2000_COORD",
"@state": "Idle",
"@perm": "rw",
"@timeout": "50",
"@label": "J2000 Equatorial",
"children": [
{
"<>": "defNumber",
"@name": "RA",
"@label": "RA H:M:S",
"@format": "%11.8m",
"@min": "0",
"@max": "24",
"$": "0"
},
{
"<>": "defNumber",
"@name": "Dec",
"@label": "Dec D:M:S",
"@format": "%9.6m",
"@min": "-90",
"@max": "90",
"$": "0"
}
]
}

In any defXXXVector message, Nyx supports an optional @hints attribute carrying Markdown to describe the vector in the UI.

Stream vectors

Nyx adds a feature for describing stream vectors metadata. Stream payloads are not transported in JSON, a dedicated API delivers them to clients. This capability is specific to Nyx and not part of INDI.

Nyx message grammar

The schema below describes the message structures for both the INDI protocol and its Nyx overlay. Nyx-specific extensions are explicitly noted.

<?xml version="1.0" encoding="UTF-8"?>
<!--
NyxNode
Author: Jérôme ODIER <jerome.odier@lpsc.in2p3.fr>
SPDX-License-Identifier: GPL-2.0-only (Mongoose backend) or GPL-3.0+
-->
<!--suppress XmlDefaultAttributeValue -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!-- ************************************************************************************************************* -->
<xs:simpleType name="propertyState">
<xs:restriction base="xs:token">
<xs:enumeration value="Idle"/>
<xs:enumeration value="Ok"/>
<xs:enumeration value="Busy"/>
<xs:enumeration value="Alert"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="propertyPerm">
<xs:restriction base="xs:token">
<xs:enumeration value="ro"/>
<xs:enumeration value="wo"/>
<xs:enumeration value="rw"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="switchRule">
<xs:restriction base="xs:token">
<xs:enumeration value="OneOfMany"/>
<xs:enumeration value="AtMostOne"/>
<xs:enumeration value="AnyOfMany"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="blobEnable">
<xs:restriction base="xs:token">
<xs:enumeration value="Never"/>
<xs:enumeration value="Also"/>
<xs:enumeration value="Only"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="streamEnable">
<xs:restriction base="xs:token">
<xs:enumeration value="Never"/>
<xs:enumeration value="Also"/>
<xs:enumeration value="Only"/>
</xs:restriction>
</xs:simpleType>
<!-- ************************************************************************************************************* -->
<!-- Messages -->
<!-- ************************************************************************************************************* -->
<xs:element name="message">
<xs:complexType>
<xs:attribute name="device" type="xs:string" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- Properties -->
<!-- ************************************************************************************************************* -->
<xs:element name="getProperties">
<xs:complexType>
<xs:attribute name="version" type="xs:string" use="required"/>
<xs:attribute name="device" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="delProperty">
<xs:complexType>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="enableBLOB">
<xs:complexType mixed="true">
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="enableStream">
<xs:complexType mixed="true">
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- Number Vectors -->
<!-- ************************************************************************************************************* -->
<xs:element name="defNumberVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defNumber"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/> <!-- Nyx only -->
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defNumber">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="format" type="xs:string" use="required"/>
<xs:attribute name="min" type="xs:decimal" use="required"/>
<xs:attribute name="max" type="xs:decimal" use="required"/>
<xs:attribute name="step" type="xs:decimal" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="setNumberVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneNumber"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newNumberVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneNumber"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneNumber">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- Text Vectors -->
<!-- ************************************************************************************************************* -->
<xs:element name="defTextVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defText"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/> <!-- Nyx only -->
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defText">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setTextVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneText"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newTextVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneText"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneText">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- Light Vectors -->
<!-- ************************************************************************************************************* -->
<xs:element name="defLightVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defLight"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/> <!-- Nyx only -->
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defLight">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setLightVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneLight"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneLight">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- Switch Vectors -->
<!-- ************************************************************************************************************* -->
<xs:element name="defSwitchVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defSwitch"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/> <!-- Nyx only -->
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="rule" type="switchRule" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defSwitch">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setSwitchVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneSwitch"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newSwitchVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneSwitch"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneSwitch">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- BLOB Vectors -->
<!-- ************************************************************************************************************* -->
<xs:element name="defBLOBVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defBLOB"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/> <!-- Nyx only -->
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defBLOB">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="format" type="xs:string" use="optional"/> <!-- Nyx only -->
</xs:complexType>
</xs:element>
<xs:element name="setBLOBVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneBLOB"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newBLOBVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneBLOB"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneBLOB">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="size" type="xs:decimal" use="required"/>
<xs:attribute name="format" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
<!-- Stream Vectors (Nyx only) -->
<!-- ************************************************************************************************************* -->
<xs:element name="defStreamVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defStream"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defStream">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setStreamVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneStream"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newStreamVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneStream"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneStream">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<!-- ************************************************************************************************************* -->
</xs:schema>