= Open QuarterMaster Serial Driver Specification V1.0.0
AsciidocFX
:doctype: article
:encoding: utf-8
:lang: en
:toc: left
:numbered:

:imagesdir: images

<<<

== Introduction

This specification defines how the Open QuarterMaster system interacts with storage hardware.

=== Context

The context of how this specification is used is as follows. Most Arduino (and similar) consumer microcontroller hardware can communicate with a full computer with https://learn.sparkfun.com/tutorials/serial-communication/all[Serial over USB connection]. This specification is meant to define how the OpenQuarterMaster system interacts with the hardware over that Serial conection.

This is currently implemented for the system in the ../open-qm-driver-server/[Open QuarterMaster DriverServer].

== Specification

=== In general

==== The treatment of Serial output from hardware

==== What gets sent to the hardware

==== The treatment of Serial output from hardware

=== General Command Structure

This is the general command structure, both to and from the hardware:

`$<command code>|[<command content>[|<second command content>]]\n`

Where:

* `$` Denotes the start of a command
* `<command code>` Is a single character command code, which are defined below.
* `<command content>` Is the command content. Specific to the command given. Must contain UTF-8 compatible characters, excluding `|`, and `\n`
* `|` Is the command content separator. Use to denote separation between command sections.
* `;` Is used to separate sections within a particular part of a command.
* `\n` Denotes the end of the command. All commands are separated from each other (and other serial I/O) by a newline character.

==== Data types

===== Light number

Int value, identifies the light being addressed, based on the index in the device's storage array.

===== Date

In the ISO-8601 format: `uuuu-MM-dd`

Example: `2022-04-27`

===== Color

Standard hex color format (six char);

`FFFFFF`

===== Brightness

Integer value, `0`-`255`

===== Bin Light Setting

`<"ON", "OFF", or "FLASHING">,<color>,<brightness>`

This composite value is a CSV of the settings to set a bin light with. This is intended to be processed one at a time, each tweaking the setting as it goes through.

====== Examples:

All:

`ON,FFFFFF,255,true`

- State: ON
- Color: FFFFFF
- Brightness: 255

Off:

`OFF`

- State: OFF
- Color: <unchanged>
- Brightness: <unchanged>

On:

`ON`

- State: ON
- Color: <unchanged>
- Brightness <unchanged>

Color setting:

`FFFFFF`

- State: <unchanged>
- Color: FFFFFF
- Brightness <unchanged>

Brightness setting:

`50`

- State: <unchanged>
- Color: <unchanged>
- Brightness 50

Last as Off:

`FFFFFF,50,OFF`

- State: OFF
- Color: FFFFFF
- Brightness 50

=== General Command Conventions

==== No-return, acknowledgement of commands

`$O`

As in, "Ok"

==== Error

`$E[|<errMessage>]`

This is the way to return an error status when a command fails.


=== Commands the hardware accepts

==== Liveliness Ping

`$P`

A simple ping command to ensure the hardware is alive and properly processing commands

===== Returns

`$P`

==== Get Info

`$I`

Returns information about the hardware module. Used to identify, determine the capabilities of, and check that the hardware is op

===== Returns

`$I|<serialNo>|<manufactureDate>|<Comm Spec version>|<numStorageBlocks>`

==== Get State

`$S`

Returns information about the current state of the hardware.

===== Returns

`$S|<message>|<binLightSettings>`

(returns as many bin light settings as there are; separated by `;`. Ordered list of light settings reflecting how they are stored on device.)

==== Set Storage Block light

`$L|<light number>;<lightSettings>[|... <more light number/settings>]`

===== Returns

`$O`

==== Set Message

`$M|<message to display>`

===== Returns

`$O` If the message was displayed

`$E[|<errMessage>]` If the message could not be displayed (No screen to display on, for example)


=== Commands the driving software accepts

These commands are meant to alert the driver software of physical events. These are less commands, and more alerts so they do not require responses from the driving software.

These are mostly for future implementation, ideas listed for now.

==== Report Storage Block Opened/Cosed

==== Report Storage Block weight change

== Hardware Requirements

=== Responsiveness

==== When receiving a command

While the hardware is receiving data from the host, it is not to send any command messages back. The next non-log message sent will be the returning command.

TODO: when to give up on a command; on second command char

===== Characters to Ignore

`\r`

=== Log messages

Log messages are quite valid to be reported from the Serial device. Any line sent without the command start character (`$`) is to be interpreted as a log. These log messages are meant to be logged by the hardware, further outlined below.

== Driving Software Requirements

=== Log messages from hardware

Log messages are sent from the hardware to be reported by the driving software (see more above). Each log line should be logged by the driving software in the same manner that driving software logs itself, along with each line the serial number and port of the hardware.

As these log lines can build up over time in buffer memory, the driving software should periodically read all lines in buffer, report the logs, and do any additional processing. Anytime a command is sent or alerts are listened for are also candidate areas to read in log lines.

=== Message Error Handling

todo: retries, how long to wait for response, etc.