Skip to content

Temperature Encoding

Nick Berardi edited this page Jul 19, 2026 · 7 revisions

Temperature Encoding

Rules

  1. All temperatures on the wire are Celsius.
  2. Display units (°F vs °C) are controlled by Setup / Scale (0x01 / 0x03) and apply only at the UI.
  3. Resolution is 0.5 °C via a packed single byte.
  4. Convert using the guide conversion table (0.5 °C steps). When F→C has duplicate F entries, use the first table row (e.g. 64 °F → 17.5 °C, not 18 °C).

Packed temperature byte

Bits Meaning
7 Sign: 0 = positive, 1 = negative
6 Half degree: 0 = .0, 1 = .5
5–0 Integer magnitude 0–63

Null on write

Condition Encoding
Do not change field Entire byte 0x00
Null heat/cool Positive sign, no half bit, magnitude 0

Valid ranges (setpoints — guide)

Field Typical valid magnitude region
Heat setpoint ~4–32 °C (bits 5–0)
Cool setpoint ~10–37 °C
Outdoor sensor value 0–55; negatives limited (notes ODT negatives limited to 40 magnitude)

Out-of-range writes → NACK 0x10.

Algorithms

encode(celsius):
 negative = celsius < 0
 mag = abs(celsius)
 half = 0x40 if (mag % 1) >= 0.5 else 0
 return floor(mag) + half + (0x80 if negative else 0)

decode(byte):
 value = byte & 0x3F
 if byte & 0x40: value += 0.5
 if byte & 0x80: value = -value
 return value

scrypted-aprilaire: convertTemperatureToByte / convertByteToTemperature in src/AprilaireClient.ts.

Documented examples

Physical °C Byte Notes
70 °F heat 21.0 0x15 Guide write example
80 °F cool 26.5 0x5A Guide write example
71 °F room 21.5 0x55 Guide COS example
110 °F heat (invalid) 43.5 0x6B Guide OOR → NACK 0x10

Away setpoint indices (not packed temps)

Away heat/cool use small integer indices, not the packed temperature byte — see Domain Scheduling

Full conversion table

See Temperature Conversion Table for the complete °C ↔ °F appendix.

Clone this wiki locally