NovaStar Reference / Data Formats / NovaStar Custom Specification
- Overview
- Specification File Details
- Standard NovaStar Properties
- Examples
- Limitations
- Importing Data into NovaStar
- Exporting Data from NovaStar
Overview
The initial focus of this specification is binary-encoded transmissions (Encoding=Binary
).
ASCII encoding has been prototyped but requires additional testing.
The NovaStar Custom Specification format is used with the
nsrecdata
program to define custom data report formats.
It is intended to support "flat" messages encoded in a line of text or a sequence of binary values,
which is typical for data collection.
Multiple messages can be included in a "transmission" and
one or more data reports can be included in a message, as illustrated below:
Transmission (`nsrecdata` is typically configured to listen for pushed transmissions)
Header (optional header, for example for Iridium)
Message
Mesage type
Data values
End of message (optional, for example \n for ASCII encoding)
Message
Mesage type
Data values
End of message
Using this data format and specification file is more complex than the simple
nsrecdata -G#,#,#
approach,
which is limited to timestamp, point identifier, and value in each message.
The specification focuses on data payload and does not include specific handling of communication layers. In contrast, the ALERT2 specification is complex and includes data elements that represent communication and data packaging layers. Consequently, the specification is suitable for common applications that do not require the communication properties of ALERT2 messages.
Data transmissions over IP (or data loaded from a file) consist of one or more data messages, each of which contain encoded data. The specification file indicates the encoding format for data in messages and allows for custom message formats for different hardware. The goal of the design is to allow the specification file to define data formats without requiring additional software enhancements.
A message specification is typically defined to optimize communication bandwidth and minimize latency. For example, messages for single sensor (a "sensor" message type) contain the timestamp, point identifier, and value and are appropriate for periodic transmissions and cases where bandwidth throughput and cost is not an issue.
If multiple sensor values are available at a station, using a "multi sensor" message will transmit the timestamp with multiple values and therefore save bandwidth. However, sending "multi sensor" messages too frequently, such as when some sensor values do not change, can waste bandwidth and single sensor messages may be better. These design issues should be evaluated based on the requirements for each implementation and the frequency that each message type is used. The specification allows multiple message types to be defined, which allows mixing of messages from a transmitter to optimize performance.
The message type at the start of each message indicates to the decoding software
such as nsrecdata
how to decode the message,
using specification file properties for each message type.
Multiple message types can be transmitted in sequence,
typically corresponding to different station configurations
and transmissions for different conditions,
including weather events and station status or summary check-in reports.
Use the nsrecdata -Gcustomspec --customspec=file
command parameters to indicate that a custom specification file is used.
The specification file typically exists in the /usr/ns/cus
folder on the NovaStar server in production systems.
The specification file format is described in the remainder of this document.
Version control can also be used to track changes in the specification file.
It is typical to name the file with .cfg
extension
indicating that it is a configuration file.
Specification File Details
The specification file (used with nsrecdata --customspec
command parameter)
is a text file that follows the
conventions of an INI file, using #
for comments.
The format uses [Section]
to group properties into a section,
and Property = Value
syntax to define properties.
Property values can be surrounded by double quotes if necessary to ensure that
whitespace and other characters are included.
This format is easily parsed by programming languages,
which can search for sections and properties in a section.
An equivalent format, such as JSON, may be implemented in the future.
Currently, the specification file must be edited with a text editor
and copied to the /usr/ns/cus
folder.
Restart the nsrecdata
process to read the file if the specification file changes.
The different file sections are used to specify related blocks of specification properties, as described in the following documentation.
General constraints for the specification include:
- A data transmission's encoding must be consistent throughout the transmission.
The following encodings are typical:
- Binary (
Encoding=Binary
) - initial focus of this specification - ASCII delimited (for example:
Encoding=ASCII
,Delimiter=,
) - prototyped but not fully tested - ASCII hex - protototyped but not fully tested
- Binary (
- All times are reported in UTC (not local time). Support for time zone can be added; however, this requires coordination of configuration on stations and NovaStar database. Using UTC ensures a common clock.
- Global general properties that apply throughout the specification,
such as global default property values, are specified in the
[General]
section. - Properties for each message type are specified using a section name that starts with the
message type and a period:
- This allows the specification for multiple message types to be described in one specification file.
- General properties for a message type are specified in a section similar to
[MessageType.General]
, for example[Sensor.General]
. - Column properties for a message type are specified in a section for each
numbered column similar to
[MessageType.Column1]
, for example[Sensor.Column1]
. - Default column properties for a message type are specified
in a section with wildcard similar to
[MessageType.Column*]
, for example[Sensor.Column*]
. For example, a multi-sensor message type may have a variable number of data values and each data column may have similar message format.
Message Types
Message types allow defining multiple data encodings based on requirements.
When properly configured, software such as
nsrecdata
requires minimal knowledge about the messages because the specification file defines the software behavior.
Although standard specifications are recommended for consistency,
the design allows for highly-customized formats to meet specific requirements.
It is recommended that messages types are consitent within a system,
for example use the same message types for all stations, if possible.
The message type is assumed to be transmitted as a one byte unsigned integer at the start of the message.
This value is cross-referenced with the MessageTypeNumber
property in the specification,
which then allows all other specification properties to be determined.
Consequently, new message types with different data configurations and encodings can generally
be enabled without changing the software.
The following table summarizes standard message types that are recommended for use
and are described in this documentation.
The text MessageType
is used for documentation and readability (e.g., MessageType=Sensor
)
whereas the numeric MessageTypeNumber
is used internally by software to cross-reference
specification properties (e.g., MessageTypeNumber = 1
(e.g., MessageTypeNumber = 1
)).
The initial implementation of the specification focuses on optimizing sensor and multi-sensor data reports,
which requires consideration of how timestamp, point identifier, and other data are handled.
See the message general properties for an explanation of how MessageType
is used.
The following message types are recommended based on common use in a system, which is to define single sensor and multi-sensor message types consistent with system requirements, communication bandwidth optimization, and station logger programming.
It is recommended that message types and their specification are defined as simply as possible. For example, use a 4-byte integer for data values for all columns rather than mixing types. A simple specification helps to minimize configuration errors.
MessageType
Property Values
MessageType |
MessageTypeNumber |
Description |
---|---|---|
Sensor |
1 | Single sensor data report, typically with NovaStar point identifier included. |
MultiSensor |
2 | Multi-sensor data report, which may or may not include the NovaStar point identifier. If not included, it must be determined from the NovaStar database based on data number. |
Other message types can be added as necessary, for example to receive and log station metadata. |
The specification is flexible to allow including point identifier and other properties in the messages, or looking up point properties from the database. If multiple message variants are needed for a system, specific message types can be defined, for example:
- Variants on
Sensor
:Sensor
- simple message with point identifier included in the message (this is the focus of the initial specification)SensorNoPointId
- look up the point identifier from the database rather than including in the message (smaller message size, but more configuration in the database)
- Variants on
MultiSensor
:MultiSensor
- may or may not include point identifier in the message data (message without point identifier is the focus of the initial specification)MultiSensorWithPointId
- define message types that include point identifier in the message data (larger message size, but less configuration in the database)MultiSensorNoPointId
- look up the point identifier from the database rather than including in the message (smaller message size, but more configuration in the database)
[General]
Properties
General properties provide general information and defaults for message column properties. Recognized properties are listed in the following table. Property names are case-specific to ensure exact match lookup; however, property values are case independent unless otherwise indicated.
[General]
Section Properties
Property | Description | Default |
---|---|---|
Delimiter |
The delimiter used to separate columns when used with Encoding=ASCII . This property is the default for all message types. Supported values are:
|
|
Encoding |
The overall encoding of the transmission and messages within the transmission:
|
ASCII (in anticipation of ASCII delimited format being the default due to ease of use) |
Endianness |
The order of bytes when Encoding=Binary and the order of Hex bytes in message data for multi-byte values for Encoding=ASCII . This property is the default for all message types. Supported values are:
|
Big - results in more readable left to right messages |
Header |
If specified, each transmission is assumed to start with a header that is read before messages are decoded. Possible values are:
|
None |
MessageSeparator |
The character(s) that indicate the end of one message and start of another message. Encoding=ASCII data messages that are separated by Linux line feed (newline) that can be read with software "read line" functions. Any empty messages due to duplicate newline characters are ignored.
|
|
[MessageType.General]
Properties
These properties describe general properties for a message type, for example in a [Sensor.General]
section.
The properties can be used as defaults so that fewer properties need to be specified for columns.
Property names are case-specific to ensure exact match lookup;
however, property values are case independent unless otherwise indicated.
[MessageType.General]
Section Properties
Property | Description | Default |
---|---|---|
Delimiter |
The delimiter used to separate columns for the message, will override the [General] section Delimiter property. Supported values are:
|
Most specific of:
|
Endianness |
The order of bytes when Encoding=Binary and the order of Hex bytes in message data for multi-byte values for Encoding=ASCII . This property is the default for encoding columns for the message and will override the [General] section Endianness property. Supported values are:
|
Most specific of:
|
Format |
The use of this property is being evaluated. The format of the data value, as the default for all columns for a message type:
|
|
MessageType required |
The message type as indicated in the Message Types documentation. The message type must agree with the first part of the section, for example MessageType = Sensor for section [Sensor.General] . The property facilitates processing by software and improves readability of the specification file. |
None - must be specified. |
MessageTypeNumber required |
The message type number as indicated in the Message Types documentation. The number used in the specification must be consistent with the software that encodes the messages. The MessageTypeNumber is transmitted in messages as an integer and is critical for interpreting the specification. |
None - must be specified. |
[MessageType.ColumnN]
Properties
These properties describe each column for a message type. Property names are case-specific to ensure exact match lookup; however, property values are case independent unless otherwise indicated. The following are typical:
[Sensor.Column1]
,[Sensor.Column2]
, etc.:- Define single sensor fixed columns at the start of messages, for example for the message type, date/time, point identifier, and data value columns.
[MultiSensor.Column1]
,[MultiSensor.Column2]
, etc.:- Define multi-sensor fixed columns at the start of messages, for example for the message type, date/time, and station identifier columns.
[MultiSensor.Column*]
:- Define multi-sensor data columns after fixed columns, which will be processed in sequence until the end of the message is detected, for example for the point identifier or order and data value columns.
Message columns are separated by a delimiter if the general message property Delimiter
is specified.
If Delimiter=None
, the columns must be formatted using an encoding that does not require a delimiter:
- For
Encoding=Binary
and no delimiter:- The columns must contain values of the correct type and endianness.
- For
Encoding=ASCII
and no delimiter:- A data column with type of
Integer4
must be represented by 4 bytes as 4 hex values, each of which is a 2-character string. - A hex value of
00
corresponds to a decimal value of0
and a hex value offf
corresponds to an unsigned one byte integer decimal value of255
. - The
Endianness
of the data message indicates the order of the hex values so that they can be properly decoded into the software's in-memory variables.
- A data column with type of
Decoding software should determine column properties as follows:
- Use the number section (e.g.,
[MultiSensor.Column1]
). - Use the wildcard default for the message type (e.g.,
[MultiSensor.Column*
]). - Use the appropriate
[General]
property.
The following are recognized column properties, which must be handled by NovaStar decoding software in order to file data reports. Property names are case-specific to ensure exact match lookup; however, property values are case independent unless otherwise indicated.
[ColumnN]
and [Column*]
Section Properties
Property | Description | Default |
---|---|---|
DateFormat |
A string that allows decoding text or integer date into its parts, for example using format YYYYMMDD , case-sensitive. This format is applied after initial decoding occurs. For example, a column identified with Name=ReportDate may contain a binary or ASCII integer that must be decoded into a date using DateFormat . See also DateTimeFormat and TimeFormat . |
YYYYMMDD |
DateTimeFormat |
A string that allows decoding text or integer date into its parts, for example using format YYYYMMDDhhmmss , case-sensitive. This format is applied after the initial decoding occurs. For example, a column identified with Name=ReportDateTime may contain a binary or ASCII integer that must be decoded into date and time using DateTimeFormat . See also DateFormat and TimeFormat . |
YYYYMMDDhhmmss |
Description |
A description of the column, for information purposes to avoid confusion. | |
Divisor |
Can use if point calibration multiplier is not used. An integer divisor (must be positive) to be applied to the value after decoding, for example to convert a transmitted integer value into floating point value for the NovaStar database. A divisor is necessary if a measured floating point value is encoded as an integer in the message. The divisor provides a way to indicate how many digits after the decimal point are encoded. For example, air temperature data with a range -NNN.NN to NNN.NN would require the station to multiply all values by 100 to create an integer and then use Divisor=100 to recreate the floating point number. For example, a measured floating point value of 25.12 would become an integer 2512 for transmission and then would be converted to 25.12 to load into the database.Note that the divisor is different than the NovaStar "calibration" adder and multiplier factors, which are used to convert raw measurement into scaled (engineering unit) values. The NovaStar point table does not include a specific column for this value and therefore the divisor must be specified as one of:
|
1 (no change in the transmitted value)See the PointOrder Property documentation for more information. |
Endianness |
The order of Hex bytes as transmitted, which will be decoded appropriately for the decoding software. |
Most specific of:
|
Format |
The use of this property is being evaluated. The format of the data value:
|
Most specific of:
|
Name required |
The column name, which corresponds to known values when decoding and allows the software to load data into the NovaStar database. See the Column Name Property Values table below for more information. |
None - must be specified. |
PointOrder |
Point order for MultiStation message type, used to look up PointNumId using NovaStar data because the message does not contain the PointNumId . Specify as:
See the PointOrder Property documentation for more information. |
None - must be specified. |
TimeFormat |
A string that allows decoding text or integer time into its parts, for example using format hhmmss , case-sensitive. This format is applied after initial decoding. For example, a column identified with Name=ReportTime may contain a binary or ASCII integer that must be decoded into a time using TimeFormat . See also DateFormat and DateTimeFormat . |
hhmmss |
Type required |
The column type, which indicates the primitive data type for the data value in the column. Initial decoding will occur using Format and Endianness and additional formats may be specified to allow further decoding, such as DateFormat , TimeFormat , and DateTimeFormat to decode the date/time. See the Column Type Property Values table below for available options. |
None - must be specified. |
ValueCount required for Binary format |
Count of data value columns, necessary for binary format messages to know how many values are part of a message. ASCII delimited messages use the MessageSeparator property to specified the message separator character (typically a newline) and the ValueCount is not needed. |
Must be specified for Binary format. |
Endianness
Property Values
The following table lists possible values for the Endianness
property,
which indicate how encoded multi-byte hex values should be decoded.
Property names are case-specific to ensure exact match lookup;
however, property values are case independent unless otherwise indicated.
The Endianness
property can be defined in the [General]
section to apply for all message types
or can be defined in message type sections for granular control of encoding.
It is recommended that transmitting software use the same endianness for all encoding in order to avoid complex specifications that may be prone to errors.
Endianness
Property Values
Endianness |
Description |
---|---|
Big |
Multi-byte hex values in the message are shown in left to right order with the byte on the left being the most significant. This is similar to the order of decimal numbers. The left-most byte contains the sign, if used. This endianness is used for the default in this specification because it is often used for network data transmissions and reads left to right when viewed in text form. |
Little |
Multi-byte hex values in the message are shown in left to right order with the byte on the left being the least significant. The right-most byte contains the sign, if used. |
Endianness is important when formatting integers in byte representations. Endianness indicates the order of bytes for multi-byte values. See Endianness on Wikipedia. Encoding is also impacted by whether an integer is signed. Most computers use two's complement (see Wikipedia article) to indicate sign. Two's complement signed values do not result in only the signed bit being set and all bytes that form a value must be shifted appropriately when decoding the value.
- Big endian format numbers are shown with the most significant byte at the lowest (leftmost) address when written as text.
- Little endian format numbers are shown with the least significant byte at the lowest (leftmost) address when written as text.
- The 8 bits within a byte are always represented with the most significant bit on the left, regardless of whether big or little endian
- Normal numbers are written with most significant digits on the left, similar to big-endian format.
- The leftmost bit in the most significant byte is used for the sign for data types that support sign, such as signed integers.
An unsigned one byte integer is able to store a maximum value of 255, as shown below.
1 1 1 1 1 1 1 1
| | | | | | | |
| | | | | | | +- = 1
| | | | | | +--- = 2
| | | | | +----- = 4
| | | | +------- = 8
| | | +--------- = 16
| | +----------- = 32
| +------------- = 64
+--------------- = 128
Total = 255
The next significant byte for multi-byte values will continue a similar pattern with larger numbers 256, 512, etc.
Rather than representing a byte in binary representation, a two-character hexadecimal value can be used.
For example ff
in an unsigned one-byte integer is equivalent to 8-bits set to 1
or decimal 255
.
A four byte unsigned integer has a value range of 0
to 4,294,967,295
,
whereas a signed integer has a value range of -2,147,483,648
to 2,147,483,647
.
A decimal value of 25000
has a big-endian hexadecimal value of 000061a8
,
meaning that the byte values from left to right are (00
, 00
, 61
, a8
).
The same number in little-endian format is the reverse order (a8
, 61
, 00
, 00
).
The decoding computer system must ensure that data value formatting is decoded consistent with the endianness of the in-memory integer.
Column Name
Property Values
The following table lists possible values for column Name
property.
Property names are case-specific to ensure exact match lookup;
however, property values are case independent unless otherwise indicated.
The property value is interpreted by software to know how to file data in the NovaStar database.
Name
Property Values
Name |
Description |
---|---|
PointNumId |
The NovaStar point numeric identifier, which corresponds to the NovaStar point table point_numid column. Once matched, the point table id is used for NovaStar data table column point_id . |
ReportDateTime |
The date and time corresponding to the data measurement, used for the NovaStar database data* table report_time . The report time can alternatively be provided using ReportDate and ReportTime . See the Date/time Format section. |
ReportDate |
The date corresponding to the data measurement, used with ReportTime to create the report time when ReportDateTime is not specified. See the Date/time Format section. |
ReportTime |
The time (for a date) corresponding to the data measurement, used with ReportDate to create the report time when ReportDateTime is not specified. See the Date/Time Format section. |
StationNumId |
The station numerical identifier, for MultiSensor message type, used to match the NovaStar station table numid in order to determine associated point table records. |
ValueRaw |
Raw sensor value, which will be loaded into the NovaStar data table raw_val value. The scaled_val value is calculated using the point's calibration data. |
ValueScaled |
Scaled sensor value, which will be loaded into NovaStar data table scaled_val value. The raw_val value is calculated using the point's calibration data. |
Column Type
Property Values
The following table lists possible values for column Type
property,
which defines the encoded column value.
For example, the type may indicate that a 4-byte integer
is used for the data value, represented as 4 hex codes.
Integer types are generally signed by default unless indicated as unsigned,
wheres characters are typically unsigned by default.
The primitive type is shown for comparison (see
C data types).
Property names are case-specific to ensure exact match lookup;
however, property values are case independent unless otherwise indicated.
Integers are often the primary types for transmitting data. Transmitted floating point values can be multiplied by a factor on the station, transmitted, and then divided by the factor during decoding, using one of the following approaches:
- Use the point's calibration multiplication factor to convert transmitted
integer to floating point value (e.g., scale by
100
on station and by.01
in calibration). - Specify the
Divisor
in the custom specification to convert the integer to a floating point number with digits after the decimal point (e.g.,100
if the value was scaled by100
on the station).
Decoding software may store all decoded values in memory as long
, double
,
or other suitable data type that is ensured to not lose precision,
given that consuming software generally is not constrained to small types.
Type
Property Values
Type |
Description | Primitive Type | Range |
---|---|---|---|
Char |
Single 1-byte character. Not currently supported. | char |
See ASCII character set. |
Char[N] |
Array of 1-byte characters. Use Char[] for ASCII format where strings are of variable length. The string should contain a trailing NULL character if less than the array size. Not currently supported. |
char[] |
See ASCII character set, any length is supported. |
Char2 |
Unicode 2-byte character - Not currently supported. | Depends on software language. | |
Float4 |
IEEE 754 4-byte signed floating point number. Not currently supported. | float |
Approximately +- 10^38 |
Float8 |
IEEE 754 8-byte signed floating point number. Not currently supported. | double |
Approximately +- 10^308 |
Integer1 |
1-byte signed integer. | byte , signed char |
-128 to 127 |
UInteger1 |
1-byte unsigned integer. | unsigned char |
0 to 255 |
Integer2 |
2-byte signed integer. | short |
-32,768 to 32,767 |
UInteger2 |
2-byte unsigned integer. | unsigned short |
0 to 65,535 |
Integer4 |
4-byte signed integer. | integer |
-2,147,483,648 to 2,147,483,647 |
UInteger4 |
4-byte unsigned integer. | unsigned integer |
0 to 4,294,967,295 |
Integer8 |
8-byte signed integer. | long |
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
UInteger8 |
8-byte unsigned integer. | unsigned long |
0 to 18,446,744,073,709,551,615 |
Other types can be added as necessary. |
PointOrder
Property
The specification for multi-sensor messages typically includes
the station identifier (Name=StationNumId
column property)
and column properties necessary to decode multiple data columns for the station.
A point identifier is necessary to file the data from the message column for the appropriate point in the database.
The Divisor
must also be specified if the data value is scaled in the message.
Including a point identifier and divisor for each data value in the message
would increase the size of the message and therefore
an alternative strategy is typically used, as described below.
- The order of data transmitted for the station must be known, for example 1) rain sensor bucket tip count, 2) water level, 3) air temperature, 4) battery. This configuration occurs at the station.
- These values correspond to the data columns in a message,
which are counted after the fixed columns (e.g., after
MessageTypeNumber
,ReportDate
,ReortTime
,StationNumId
). The data position is counted as1
,2
,3
,4
, ... , which is different than the column number in a message (due to other columns at the start of a message). - The NovaStar database record for each point should be configured accordingly:
- Use a consistent combination of the
point
tabledata_position
and optionallydata_parameter
to hold the message data position and divisor. Thesensor_id
is also an option but is not currently recommended for use and may be prohibited in the future. - For example, decide that
data_position
will be used for the data position (1
,2
,3
, ...). - There is no database column for "divisor", which is why one of the above columns must be used instead.
For example, use
data_parameter
for the divisor value and set accordingly for the data value for the point. For example, set to100
if the data value was multiplied by100
before transmitting. Alternatively, use the point's calibration multiplication factor, which will result in the factor representing the transmission scaling as well as any other scaling that is required.
- Use a consistent combination of the
- Define the specification to describe the above. For example, if data column configurations are the same for all data columns, the specification file might look like the following:
[MultiSensor.General]
MessageType = MultiSensor
MessageTypeNumber = 2
[MultiSensor.Column1]
Description= "Message type number"
Name = MessageTypeNumber
Type = Integer1
[MultiSensor.Column2]
Description = "Report date"
Name = ReportDate
Type = Integer4
DateFormat = MMDDYYYY
[MultiSensor.Column3]
Description = "Report time"
Name = ReportTime
Type = Integer4
TimeFormat = hhmmss
[MultiSensor.Column4]
Description = "NovaStar station numeric identifier"
Name = StationNumId
Type = Integer4
[MultiSensor.Column*]
Description = "Point data raw value(s)"
Name = ValueRaw
Type = Integer4
# A value of data_parameter=1 in the database corresponds to the first data value column in the message.
PointOrder = ${ns.point:data_position}
# After the point is found using 'PointOrder', use the 'data_parameter' for the divisor value, if `Divisor` is used.
Divisor = ${ns.point:data_parameter}
Decoding software such as nsrecdata
should handle the above configuration as follows,
for each data column that is processed:
- Select all points that match the given
StationNumId
. - For the data column of interest (for example
1
for the first data position), match thePointOrder
value. For example, for the above example, find a station's point that hasdata_position=1
. This point will be used to file the first data value. - If
Divisor
is used, once the point has been found, determine the divisor from thedata_parameter
column, which is applied to compute the data value to insert into the database. - File the data report.
If no matching point is found, the data report will not be filed.
A warning should be logged and the data should be written to the log file in case it needs to be reloadd later.
If a sensor is removed from the transmitting station,
the data position will shift to the left and NovaStar database data_position
values will
need to be adjusted accordingly.
Date/time Format
Data reports typically have a report time in UTC that is the time of measurement or the inteval-ending time of a computed interval statistic value (e.g., mean over an interval). The NovaStar system expects data messages to include a time and therefore if only date is used for a report, the time parts will default to zero. The following examples illustrate options for encoding date and time for common cases.
Encode Date and Time as Two Integers
Separate integers can be used to encode date and time.
For example the date/time 2022-02-08T01:02:03
can be represented with integers 20220208
and 10203
.
If Format = Hex
(specified in the global or message General
properties),
the following specification properties should be used (for example).
The integers as hex codes are first decoded to integers.
The parts of the integer are then parsed into the report date and time
based on the DateFormat
and TimeFormat
properties.
[Sensor.Column2]
Description = "Report date"
Name = ReportDate
Type = Integer4
DateFormat = YYYYMMDD
[Sensor.Column3]
Description = "Report time"
Name = ReportTime
Type = Integer4
TimeFormat = hhmmss
Encode Date and Time as One Integer
One integer can be used to encode the date and time.
For example the date/time 2022-02-08T01:02:03
can be represented as a fourteen-digit integer 2022020810203
.
If Format = Hex
(specified in the global or message General
properties),
the following specification properties should be used (for example).
The integer as hex codes is first decoded to a long integer.
The parts of the long integer are then parsed into the report date and time
based on the DateTimeFormat
.
[Sensor.Column2]
Description = "Report date and time"
Name = ReportDateTime
Type = Integer8
DateTimeFormat = YYYYMMDDhhmmss
Encode Date and Time as Text using ASCII Format
Text can be used to encode the date and time.
For example the date/time 2022-02-08T01:02:03
can be transmitted as shown.
The original string is first decoded into characters (simple copy).
Then the text is parsed to determine the date and time parts.
A space can be used in the DateTimeFormat
to ignore the T
between date and time.
[Sensor.Column2]
Description = "Report date and time"
Name = ReportDateTime
Type = Char[]
Format = ASCII
DateTimeFormat = "YYYY-MM-DD hh-mm-ss"
Error Checking
Error checking is important to ensure that data are properly decoded and filed in the system. The NovaStar system implements error checking for each point and will mark out of range values as questionable. It is more difficult to detect values that are in range but are extreme, such as rapidly increasing water level. In these cases, the system tends to report all data so that real-time emergency management decisions have as much data as possible, and quality control may be required on data when time is available.
The code that parses this specification should implement basic checks where possible, including:
- message length:
- ASCII delimited transmissions should use
MessageSeparator
to control the end of one message and the start of the next message - binary transmissions should use
ValueCount
to indicate the number of data values to read, and binary messages must adhere
- ASCII delimited transmissions should use
- decoded numerical values should be valid numbers
- detect extra data columns that are not configured, such as extra columns in ASCII delimited messages
Problems in data should be indicated in the log file using clear messaging such as
ERROR
or WARNING
.
Standard NovaStar Properties
The custom specification allows integration of various data collection technologies with NovaStar.
The configuration of the transmitting station coupled with the specification file allows
data in messages to be inserted into NovaStar.
The Column Name
Property Values table describes how message column data is
mapped to NovaStar database table values.
Examples
The following examples illustrate contents of messages and specification file contents for the corresponding message type. A specification file should contain as many sections necessary to define general properties and properties for required message types.
General
General properties provide general information and defaults for message and column properties.
The following is used for binary encoding using big-endian byte order:
[General]
Encoding = Binary
Endianness = Big
The following is used for ASCII encoding using comma-delimited data and big-endian byte order. Note that comma is the default delimiter for ASCII encoding and big endian is also the default.
[General]
Encoding = ASCII
Delimiter = ","
Endianness = Big
Message Type: Sensor
Sensor
Binary Encoding
The following specification file properties would be used for Sensor
message type that transmits data similar to the following.
If necessary, include an appropriate Header
property in the main [General]
section.
MessageTypeNumber = 01 = 1 = Sensor
ValueCount = 1
ReportDate 4052021 = 04/05/2021
ReportTime 111940 = 11:19:40
PointNumId 99910, a precipitation point for station 99910
ValueRaw = 1, raw count of 1 tip
# Example of specification file contents for 'Sensor' message type.
# These properties can be appended to a specification file after the [General] section.
[Sensor.General]
MessageType = Sensor
MessageTypeNumber = 1
[Sensor.Column1]
Description= "Message type number"
Name = MessageTypeNumber
Type = Integer1
[Sensor.Column2]
Description= "Data value count"
Name = ValueCount
Type = Integer1
[Sensor.Column3]
Description = "Report date"
Name = ReportDate
Type = Integer4
DateFormat = MMDDYYYY
[Sensor.Column4]
Description = "Report time"
Name = ReportTime
Type = Integer4
TimeFormat = hhmmss
[Sensor.Column5]
Description = "NovaStar point numeric identifier"
Name = PointNumId
Type = Integer4
[Sensor.Column6]
Description = "Point raw data value from sensor"
Name = ValueRaw
Type = Integer4
# Optional Divisor will vary between points so get from the database. Can also use point calibration.
Divisor = ${ns.point:data_parameter}
Sensor
ASCII Encoding using Hexadecimal
The use of Format=Hex
is being evaluated.
The following specification file properties would be used for Sensor
message type that transmits data similar to
the following (spaces have been added for illustration but are not included in the actual message):
01 00 3D D4 35 00 01 B5 44 00 01 86 46 00 00 00 01
MessageTypeNumber = 01 = 1 = Sensor
ReportDate 00 3D D4 35 = 4052021 = 04/05/2021
ReportTime 00 01 B5 44 = 111940 = 11:19:40
PointNumId 00 01 86 46 = 99910, a precipitation point for station 99910
ValueRaw 00 00 00 01 = 1, raw count of 1 tip
# Example of specification file contents for 'Sensor' message type.
# These properties can be appended to a specification file after the [General] section.
[Sensor.General]
MessageType = Sensor
MessageTypeNumber = 1
Delimiter = None
Format = Hex
[Sensor.Column1]
Description= "Message type number"
Name = MessageTypeNumber
Type = Integer1
[Sensor.Column2]
Description = "Report date"
Name = ReportDate
Type = Integer4
DateFormat = MMDDYYYY
[Sensor.Column3]
Description = "Report time"
Name = ReportTime
Type = Integer4
TimeFormat = hhmmss
[Sensor.Column4]
Description = "NovaStar point numeric identifier"
Name = PointNumId
Type = Integer4
[Sensor.Column5]
Description = "Point raw data value from sensor"
Name = ValueRaw
Type = Integer4
# Optional Divisor will vary between points so get from the database. Can also use point calibration.
Divisor = ${ns.point:data_parameter}
Message Type: MultiSensor
MultiSensor
Binary Encoding
The following configuration file properties can be used for MultiSensor
message type that transmits data similar to the following.
If necessary, include an appropriate Header
property in the main [General]
section.
MessageType = 2 = MultiSensor
ValueCount = 5
ReportDate = 4292021 = 04/29/2021
ReportTime = 171250 = 17:12:50
StationNumId = 7470, Washout Gulch at Hwy 14 station setup in the WET GCP
ValueRaw = 11, raw count of 11 tips for point 747
ValueRaw = 177, master stage 1.77 ft for point 7473
ValueRaw = 266, remote stage of 2.66 ft for point 7474
ValueRaw = 1226, master battery of 12.26 volts for point 7475
ValueRaw = 1222, remote battery of 12.22 volts for point 7476
# Example of specification file contents for `MultiSensor` message type.
# These properties can be appended to a specification file after the [General] section.
[MultiSensor.General]
MessageType = MultiSensor
MessageTypeNumber = 2
[MultiSensor.Column1]
Description= "Message type number"
Name = MessageTypeNumber
Type = Integer1
[MultiSensor.Column2]
Description= "Data value count"
Name = ValueCount
Type = Integer1
[MultiSensor.Column3]
Description = "Report date"
Name = ReportDate
Type = Integer4
DateFormat = MMDDYYYY
[MultiSensor.Column4]
Description = "Report time"
Name = ReportTime
Type = Integer4
TimeFormat = hhmmss
[MultiSensor.Column5]
Description = "NovaStar station numeric identifier"
Name = StationNumId
Type = Integer4
[MultiSensor.Column*]
Description = "Point data raw value(s)"
Name = ValueRaw
Type = Integer4
# A value of data_position=1 in the database corresponds to the first data value column in the message.
PointOrder = ${ns.point:data_position}
# If Divisor is used, after the point is found using 'PointOrder', use the 'data_parameter' for the divisor value.
# Divisor is not needed if the point uses the NovaStar calibration to scale the data value.
Divisor = ${ns.point:data_parameter}
MultiSensor
ASCII Encoding using Hexadecimal
The use of Format=Hex
is being evaluated.
The following configuration file properties can be used for MultiSensor
message type that transmits data similar to the following.
02 00 41 7D B5 00 02 9C F2 00 00 1D 2E 00 00 00 0B 00 00 00 B1 00 00 01 0A 00 00 04 CA 00 00 04 C6
MessageType 02 = 2 = MultiSensor
ReportDate 00 41 7D B5 = 4292021 = 04/29/2021
ReportTime 00 02 9C F2 = 171250 = 17:12:50
StationNumId 00 00 1D 2E = 7470, Washout Gulch at Hwy 14 station setup in the WET GCP
ValueRaw 00 00 00 0B = 11, raw count of 11 tips for point 747
ValueRaw 00 00 00 B1 = 177, master stage 1.77 ft for point 7473
ValueRaw 00 00 01 0A = 266, remote stage of 2.66 ft for point 7474
ValueRaw 00 00 04 CA = 1226, master battery of 12.26 volts for point 7475
ValueRaw 00 00 04 C6 = 1222, remote battery of 12.22 volts for point 7476
# Example of specification file contents for `MultiSensor` message type.
# These properties can be appended to a specification file after the [General] section.
[MultiSensor.General]
MessageType = MultiSensor
MessageTypeNumber = 2
Delimiter = None
Format = Hex
[MultiSensor.Column1]
Description= "Message type number"
Name = MessageTypeNumber
Type = Integer1
[MultiSensor.Column2]
Description = "Report date"
Name = ReportDate
Type = Integer4
DateFormat = MMDDYYYY
[MultiSensor.Column3]
Description = "Report time"
Name = ReportTime
Type = Integer4
TimeFormat = hhmmss
[MultiSensor.Column4]
Description = "NovaStar station numeric identifier"
Name = StationNumId
Type = Integer4
[MultiSensor.Column*]
Description = "Point data raw value(s)"
Name = ValueRaw
Type = Integer4
# A value of data_position=1 in the database corresponds to the first data value column in the message.
PointOrder = ${ns.point:data_position}
# If Divisor is used, after the point is found using 'PointOrder', use the 'sensor_id' for the divisor value.
Divisor = ${ns.point:sensor_id}
nsrecdata
Implementation Example
This section provides a checklist for implementing the custom specification using nsrecdata
.
Following this checklist will ensure that implementation is consistent with the NovaStar software and database design.
The goal is to configure the NovaStar database to run a data collection command line similar to:
nsrecdata 0.0.0.0:5002 -Gcustomspec -d4 -c0 -S7 --customspec=/usr/ns/cus/nsrecdata-customspec.cfg
- Configure software on transmitting stations:
- The previous sections illustrate how data messages can be defined. Use a consistent approach throughout the system.
- Implement software on the station consistent with the message format:
- If integers are used for transmission,
handle the conversion of floating point measurements to integers using a scale factor.
The scale factor during decoding can be handled either using NovaStar point calibration factor
(in which case the scale factor will include transmission float/integer conversion)
or configure to use the
Divisor
in the specification file (in which case the the scale factor must be an integer and is processed independent of the calibration factor). - For each station, the order of data columns (1+) in a message must be mapped to NovaStar points (below). Note that the data columns are those with raw or scaled value. Keep track of the order because it is used below.
- If integers are used for transmission,
handle the conversion of floating point measurements to integers using a scale factor.
The scale factor during decoding can be handled either using NovaStar point calibration factor
(in which case the scale factor will include transmission float/integer conversion)
or configure to use the
- Create a custom specification file to allow ingest of the data:
- For example, name:
nsrecdata-customspec.cfg
- Save in the
/usr/ns/cus
folder on the NovaStar machine. - Set the
PointOrder
property in the configuration file for data columns to use:PointOrder = ${ns.point:data_position}
- Handle scale factor if station is configured to scale flointing point numbers to integers,
using one of the following approaches:
- If the point's calibration is used to handle scaling,
do not use
Divisor
in the custom specification file. - Set the
Divisor
property in the configuration file for data columns to use:Divisor = ${ns.point:data_parameter}
- If the point's calibration is used to handle scaling,
do not use
- Remember to set the main
[General]
properties forEncoding
,Delimiter
, andEndianness
.
- For example, name:
- Configure the station type data in the NovaStar database:
- What should this be set to? Is there a standard station type for custom data format stations, or reuse an existing station type?
- Can this be similar to stations that use
-G #,#,#
?
- Configure the station in the NovaStar database:
- Set the station's station type to the type defined above.
- Configure point data in the NovaStar database:
- There is currently no way to edit in the legacy Administrator so SQL must be used.
The new Administrator will allow editing and will ensure that users see appropriate entry fields.
The legacy Administrator does not provide an interface to edit
-G customspec
or--customspec
options in the configuration table. - Set the Data Position (
data_position
) value for the point to value 1+, consistent with the column in the message for the data. - Handle scaling using one of the following approaches if the transmitted raw value was
converted from float to integer using a multiplication factor:
- Set the point's calibration multiplier factor as appropriate,
for example
.01
if the floating point value was multipled by100
to create an integer for transmission. The multiplier must take into account other calibration scaling if any is implemented. - Set the Divisor (point's
data_parameter
) value for the point to the scale value that was applied to data value in the message. For example, set to100
if the original raw value was scaled by100
to convert floating point value to integer for transmission. If no scaling was done, set the value to 1 (which is the default ifDivisor
is not specified). Using this approach allows the transmission scaling factor to be separate from other calibration factor.
- Set the point's calibration multiplier factor as appropriate,
for example
- There is currently no way to edit in the legacy Administrator so SQL must be used.
The new Administrator will allow editing and will ensure that users see appropriate entry fields.
The legacy Administrator does not provide an interface to edit
- Enable the data ingest process:
- Note that the legacy Administator does not allow editing custom specification configuration. Use SQL. The new Administrator is being developed to edit the configuration.
- Add a configuration table entry with the following values:
- Name:
alert_portN
(where N is a number that is not already in use) - Description:
Example of custom data push to NovaStar
- Port name:
:5002
(where the port number is distinct from other ports being used) - Format:
customspec
(will result in-Gcustomspec
) - Custom specification file:
/usr/ns/cus/nsrecdata-customspec.cfg
(will result in--customspec=/usr/ns/cus/nsrecdata-customspec.cfg
) - Do not file data:
false
- Source: specify a line number that is unique from other data feeds
- Connect type:
listen
- The remaining options similar to
nsrecdata
ALERT2 command parameters are optional. For example, set debug level and timeout.
- Name:
Limitations
- The format has been developed for use with the
nsrecdata
program. Support in other software may be added over time. - The
Encoding=Binary
format is the initial focus of development. Other features will be fully enabled over time. - Binary support for floating point values has not been implemented. Use integers with scale (divisor) or use NovaStar calibration factor to scale.
- The encoded format specification is often controlled by limitations of the communication network,
for example bandwidth and cost limitations.
This can result in messages that are terse and depend on additional configuration data.
For example, the
MultiSensor
message type does not include point identifiers in the message and relies on the NovaStar database to provide the point identifiers based on the column position of data values.
Importing Data into NovaStar
Use the
nsrecdata
program
with a custom specification file to import data into NovaStar.
Exporting Data from NovaStar
The specification file is currently not used to export data. Data can be exported from NovaStar in various formats by various software and web services.