# Responses, variables, and units

## ACK family

Acknowledgements occupy `0x78`–`0x7F`. The low three bits normally encode a
short response length using the same convention as commands.

| Request | Response body |
|---|---|
| Ping | `0x78` only; no CRC |
| Acknowledged write | `0x78`, request CRC; no newly calculated response CRC |
| Write range | `0x78`, request CRC; no newly calculated response CRC |
| Flash / set time | `0x78`, CRC |
| Echo | `0x79`, echoed byte, CRC |
| Uptime | `0x7C`, four-byte uptime, CRC |
| Clear log | `0x78`, CRC |
| Memory write | `0x78`, CRC calculated over written data |
| Memory read / log read | `0x7F`, extended length, data, CRC |

The ping exception is intentional: the single `0x78` is optimized for rapid
address discovery.

The host implementation sends `FLASH` as a
no-reply operation so the same API can also support group and broadcast flash,
then waits 500 ms before continuing.

## Read responses

For variable widths 1–4:

```text
0x79 value[1] crc
0x7A value[2] crc
0x7B value[3] crc
0x7C value[4] crc
```

Multi-byte numeric values are returned most significant byte first. Ranges and
larger values use `0x7F`, an extended length, packed data, then CRC. Variable
metadata determines how the packed bytes are divided.

## General node information

The base `GET_INFO` reply is an extended `0x7F` response with a `0x20`
payload length and these fields:

| Field | Size | Encoding |
|---|---:|---|
| Protocol version | 1 | integer |
| Number of variables | 1 | 0–255 |
| Node address | 2 | MSB, LSB |
| Group address | 2 | MSB, LSB |
| Revision | 2 | MSB, LSB |
| Node name | 16 | character bytes |
| RTC | 6 | BCD DD MM YY HH MM SS |
| Buffer size | 2 | MSB, LSB |
| CRC | 1 | CRC-8 |

`MSCB_INFO` supports additional device diagnostic fields. Clients should use
the library decoder rather than assume that all firmware returns only the base
layout.

## Variable information

The compact variable-information reply uses `0x7F` and these fields:

| Field | Size | Meaning |
|---|---:|---|
| Width | 1 | value size in bytes |
| Unit | 1 | unit code |
| Prefix | 1 | signed decimal exponent |
| Status | 1 | run-time status |
| Flags | 1 | type/access flags |
| Name | 8 or 16 | zero-terminated variable name |
| CRC | 1 | CRC-8 |

The decoder accepts both name widths. Applications should use
`mscb_info_variable()` instead of hard-coding a response size.

## Variable flags

The flags describe representation and access. Consult `include/mscb.h` for
the exact bit constants used by the checked-out firmware. The defined meanings
are floating-point, signed, data-less/control, hidden, remote input, and remote
output.
Width, flags, unit and prefix together are required to present a value
correctly.

## Metric prefixes

The prefix is a signed power of ten:

| Value | Prefix | Value | Prefix |
|---:|---|---:|---|
| −12 | pico (p) | 3 | kilo (k) |
| −9 | nano (n) | 6 | mega (M) |
| −6 | micro (µ) | 9 | giga (G) |
| −3 | milli (m) | 12 | tera (T) |
| 0 | none | | |

## Unit codes

| Code | Unit | Code | Unit |
|---:|---|---:|---|
| 1 | meter | 2 | gram |
| 3 | second | 4 | minute |
| 5 | hour | 6 | ampere |
| 7 | kelvin | 8 | degree Celsius |
| 9 | degree Fahrenheit | 20 | hertz |
| 21 | pascal | 22 | bar |
| 23 | watt | 24 | volt |
| 25 | ohm | 26 | tesla |
| 27 | liter/second | 28 | revolutions/minute |
| 29 | farad | 30 | joule |
| 31 | newton | 50 | boolean |
| 52 | byte | 53 | word |
| 54 | double word | 55 | ASCII character |
| 56 | string | 57 | baud |
| 90 | percent | 91 | parts per million |
| 92 | count | 93 | factor |
| 94 | volt/volt | | |

Undefined values should be shown as an unknown unit rather than guessed.
