Nixie-Net Protocol Specification

From Wiki
Jump to: navigation, search

This needs to be re-formatted.

NIXIE-NET Proposal

# Rename to NIXIE-NET (RFC #1)
# Simple text based protocol, minimum number of fields, comma separated.
# Multiple record types to support various features
# Low baud rate (2400/4800/9600) to allow for lower cost data radios

Data is NRZI encoded into the transmitter to equalize the bitstream.  If
a long sequence of 1's or 0's occurs, many radios will get confused.  
(Some more text about syncing at the start of transmission goes here)

Other than the basic time record, support of all record types is optional.
Device should handle errors logically and gracefully, ignoring records
device is not capable of supporting.

In the example below, the group and code is set to 255 to indicate all
devices within reception range.

Checksum will ALWAYS be transmitted, but the device MAY choose to ignore
them.  The example below supposes that a checksum is expected and will be
checked.  If not using checksums, you may wish to parse slightly differently.

Unlike NMEA, fields may not be left blank.  Inapplicable fields should be 
set to a reasonable value, such as 0.  While useless, double quoted text
fields may be zero length.

To embed non-ASCII characters (such as control characters) in a message, the
'C' language method will be used.  A '\' character will be used as an escape 
character.  The character can either be followed by a 3 digit OCTAL number,
OR a standard C language construct, such as '\n' for linefeed, and '\r' for
carriage return.  There are others, but I'll skip those for now.  These
embedded characters may ONLY occur in double quoted text fields.  If seen
outside of double quotes, the state machine should reset itself.

   State 1 : If character is a '$'
                state = 2
             else
                state = 1

   State 2 : Initialize timeout timer
             state = 3

   State 3 : If timeout timer expired
               state = 1
             else if character not in [0123456789.-*ABCDEF"]
               state = 1
             else if input buffer full
               state = 1
             else is character a 
               state = 3
             else
               store character
               state = 3

   State 4 : If character at length of buffer - 3 NOT '*'
               state = 1
             else if calculated checksum does NOT match end of buffer
               state = 1
             else
               state = 5

   State 5 : Parse and display data as appropriate
             state = 1

The statement machine should check for balanced double quotes if they occur,
since this mostly likely would be a result of a transmission error, the 
checksum (which all good programmers would implement) would detect that.

Time set - generic

Start of record ($)
Record type (1=time record)
Group code (0 to 255) *1
Clock code (0 to 255) *2
TimeType (0=UTC, 1=Local)
Time (HHMMSS)
Date (YYYYMMDD)
Timezone_1 (+- offset from UTC, applied to hours)
Timezone_2 (+- offset from UTC, applied to minutes)
Checksum (like NMEA, '*xx' if present, or ignore)

Example: $1,255,255,0,230722,20030225,-5,0*23

*1 devices are assigned to a group code.  255 is reserved to indicate
all groups.  A device may only belong to one group code, and may not
be assigned 255 as a group code number.

*2 devices are assigned a unit number.  255 is reserved to indicate all
units within a specific group.  A device may only be assigned one
unit code, and may not be assigned 255 as a unit number.


Time set - epoch seconds

Start of record ($)
Record type (2=epoch seconds record)
Group code (0 to 255)
Clock code (0 to 255)
TimeType (0=UTC, 1=Local)
EpochSeconds (1014167121)
Timezone (+- offset from UTC, in seconds)
Checksum (like NMEA, '*xx' if present, or ignore)

Example: $1,255,255,0,1014167121,-3000*88

Request for simple immediate display

Start of record ($)
Record type (3=Simple immediate display)
Group code (0 to 255)
Clock code (0 to 255)
Number (numeric value, up to 16(?) digits, right justified)
Duration (number of seconds to display, up to 65535)
Tone (if tone capable, play tone number) *3
ToneDuration (if tone capable, tone duration in milliseconds) *4
Checksum (like NMEA, '*xx' if present, or ignore)

Example: $3,255,255,8005551212,30,2,0*4b

*3 if device only supports a single tone, a non-zero value
will play it. If device is multi-tone or tune capable, play
tone number or tune number.

*4 if device supports tones, duration in milliseconds, up to
65535. If tune capable, this field is ignored.

Request for complex immediate display

Start of record ($)
Record type (4=Complex immediate display)
Group code (0 to 255)
Clock code (0 to 255)
Text (text string, double quote delimited, up to 128 characters)
Duration (total number of seconds to display, up to 65535)
ScrollDirection (if scroll capable, 0=right to left, 1=left to right)
ScrollIncrement (if scroll capable, number of characters per scroll, up to 255)
ScrollDuration (if scroll capable, duration in milliseconds between increments up to 65535)
ScrollRepeat (if scroll capable, number of times to repeat, 0=up to Duration, up to 255)
Tone (if tone capable, play tone number) *3
ToneDuration (if tone capable, tone duration in milliseconds) *4
ToneEvery (if tone capable, 0=tone once, 1=tone on each re-scroll)
Checksum (like NMEA, '*xx' if present, or ignore)

Example: $4,255,255,"Ray's 4 letter word clock demo scroll",30,0,1,100,0,1,100,1*bc

Request for tone

Start of record ($)
Record type (5=Request for tone)
Group code (0 to 255)
Clock code (0 to 255)
Tone (if tone capable, play tone number) *3
ToneDuration (if tone capable, tone duration in milliseconds) *4
Checksum (like NMEA, '*xx' if present, or ignore)

Example: $5,255,255,2,250*7e

Clock configuration

Start of record ($)
Record type (6=clock configuration)
Group code (0 to 255)
Clock code (0 to 255)
Display (0=off, 1..100=On/Intensity)
TimeDisplay (0=off, 1=12Hr, 2=24Hr)
TimeBase (0=primary, 1=secondary, 2=teriary) *5
UpdateDownstream (0=No, 1=Yes) *6
ManualSetOverride (0=Off, 1=On, 2=Use current) *7
Checksum (like NMEA, '*xx' if present, or ignore)

Example: $6,255,255,100,2,0,1,2*f5

*5 The devices primary timebase is determined at construction time.
If a clock contains a GPS receiver, the GPS receiver may be considered
the primary time base. If a clock contains a clock chip in addition
to the GPS receiver, the GPS receiver would be primary, and the clock
chip would be the time base if the GPS receiver loses signal. The
processor of the device may be considered a timebase. Optionally,
the NIXIE-NET master may be considered a timebase.

*6 Device timebases priority should be based on accuracy. A higher
accuracy timebase may update a lower accuracy timebase if TimeBase=1.
Thus, if a GPS has a valid signal, and is the primary timebase, it
may update the clock chip, which is the secondary timebase.

*7 If a device contains a manual method for setting time (i.e.
"pushbuttons", and the manual method is activated ("pressed"), and
ManualSetOverride=1, then all automatic updating via NIXIE-NET is
disabled. To return to using NIXIE-NET data to update the device,
this should be configured to on, or if the device is currently in
'Use current' mode (mode determined at device, via jumper, switch, etc),
the 'Use current' mode should be set to NIXIE-NET. This permits
manual overrides without the manual override being reset by the next
NIXIE-NET time set transmission.