Skip to content

Instantly share code, notes, and snippets.

@chuma
Created June 16, 2026 14:26
Show Gist options
  • Select an option

  • Save chuma/8d867ccb0e91eb721727b6722455a143 to your computer and use it in GitHub Desktop.

Select an option

Save chuma/8d867ccb0e91eb721727b6722455a143 to your computer and use it in GitHub Desktop.
Reversomatic HRV protocol

Reversomatic HRV control bus

It's similar to but different from the NZ HRV protocol from https://web.archive.org/web/20170426041752/http://www.chimera.co.nz/electronics/hrv-esp8266.ino via https://www.geekzone.co.nz/forums.asp?forumid=141&topicid=195424

Control bus overview

Each bus has a single controller device and zero or more peripheral devices connected to it.

The controller is programmed with a list of peripheral addresses that may be connected to the bus.

Each peripheral type is programmed with a specific peripheral address value. Some addresses are reserved for specific peripheral types.

Every 500ms, the controller sends a polling message containing a specific peripheral address value. If a peripheral with the corresponding address receives the polling message, it responds with its current configuration state, before the controller polls the next address. The controller then updates the HRV's internal state accordingly, if necessary.

Physical connection

Control devices are daisy-chained from the control board using three wires: +5V, GND, and DATA.

The single DATA wire carries 5V TTL-level bi-directional serial data bus at 1200bps, no start bits, 8 data bits, one stop bit.

Devices default to receiving data from the wire, unless they are the controller polling for peripherals, or peripherals responding to a poll request.

Message protocol

Within this section, values in monospace are hexadecimal.

Each data packet is composed of a prefix, data section, and checksum.

   Prefix byte only sent by controller
   |                                                Checksum
   |               Data section                      |
  \/               \/----------------------------\/  \/
----------------------------------------------------------
| [80] | 7E | 7E | TP | ID | PL | PL | PL | PL | PL | CK |
----------------------------------------------------------
         ^^^^^^^   ^^   ^^
            |      |    Device address
            |      |
            |      Packet type
            |
          Message start indicator

Packet prefix

Packets sent by the HRV main board are 11 bytes long and start with the prefix 80 7E 7E.

Packets sent by control devices are 10 bytes long and start with the prefix 7E 7E.

Packet data section

The data section is seven bytes long. The first byte is probably a device or message type value. The only value that has been observed is 07.

The second byte is the peripheral address. When sent from the controller, the ID is in the high nybble. Peripherals respond with their address value in the low nybble.

The remaining 5 bytes are used for data. Polling messages sent by the controller always set these bytes to 00.

Checksum byte

How checksum is calculated.

Device addresses / types and data formats

Wall timer with off mode

This device uses address 3, and responds with the following data values depending on its state:

  • 00 00 FF 00 00: Off mode
  • 00 00 00 00 00: Low speed
  • FF 00 00 00 00: High speed
  • 00 FF 00 00 00: Intermittent (20 minutes on, 40 minutes off)

Example messages

Controller polls device 3 with the message 80 7E 7E 07 03 00 00 00 00 00 FC

Device 3 responds with 7E 7E 07 30 00 00 FF 00 00 D0 indicating that the HRV should be off.

Multiple bus peripherals

  • messages starting with 80 7E 7E 07 0? are sent FROM the HRV board to other switch types
  • This makes sense because the documentation says:
    • you can have up to FOUR of these type of switches, and we see messages to 01, 02, 03, 04
    • "unit takes command from the switch pressed last"
    • "each switch indicates the current status and will show remaining time"
  • messages starting with 7E 7E 07 30 are sent FROM the lo/hi/int controller
sequenceDiagram

loop All devices
    participant Controller@{ "type" : "control", "style": "border: dashed" }

    Controller->>+Peripheral_1: What is your state?
    Peripheral_1-->>-Controller: [State]
    participant Peripheral_2@{  }
    Controller->>+Peripheral_2: What is your state?
    Note over Controller,Peripheral_2: no response

    Controller->>+Peripheral_3: What is your state?
    Peripheral_3-->>-Controller: [State]

end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment