enocean

package
v0.687.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package enocean decodes EnOcean ESP3 packets and the ERP1 radio telegrams they carry — the self-powered 868 / 902 / 315 MHz building- automation protocol behind batteryless light switches, occupancy / window-contact / temperature sensors and actuators. A USB gateway (USB300/400J) or an SDR emits ESP3 frames; decoding them yields the device identity (32-bit sender ID), the telegram type, the radio signal strength and an integrity check — the reconnaissance a building-automation RF pentest starts from.

Wrap-vs-native judgement

Native. ESP3 is a fixed, fully-public framing (EnOcean Serial
Protocol 3): 0x55 sync, a 4-byte header (16-bit data length,
8-bit optional length, 8-bit packet type), a header CRC-8, the
data, the optional data, and a data CRC-8. The CRC is the
standard CRC-8 (polynomial 0x07). The RADIO_ERP1 data is
RORG + payload + 4-byte sender ID + status byte. All of that is
byte-field extraction plus one table-driven CRC-8, reimplemented
here from the EnOcean spec / the kipe enocean reference — no new
dependency, no shell-out.

What this covers

  • ESP3 framing: sync, data / optional lengths, packet type (+ name), and BOTH CRC-8s (header + data) recomputed and reported valid / invalid.
  • RADIO_ERP1 telegram (packet type 1): RORG (+ name: RPS / 1BS / 4BS / VLD / MSC / UTE / …), the payload, the 32-bit sender ID, the status byte (+ repeater count), and the optional data (sub-telegram count, destination ID, RSSI in -dBm, security level).

Deliberately deferred

EEP (EnOcean Equipment Profile) payload decode — the meaning of
the data bytes (which rocker was pressed, the contact open/closed
state, a 4BS sensor's temperature/humidity) depends on the device's
FUNC/TYPE profile, which the telegram does NOT carry, so it would
be a confidently-wrong guess; the raw payload + RORG are surfaced
instead. Over-the-air ERP1/ERP2 radio framing (an SDR capture
before ESP3 wrapping) and AES secure telegrams are also deferred.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type RadioERP1

type RadioERP1 struct {
	RORG          string         `json:"rorg"`
	RORGName      string         `json:"rorg_name"`
	PayloadHex    string         `json:"payload_hex,omitempty"`
	SenderID      string         `json:"sender_id"`
	Status        string         `json:"status"`
	RepeaterCount int            `json:"repeater_count"`
	Optional      *RadioOptional `json:"optional,omitempty"`
}

RadioERP1 is the decoded RADIO_ERP1 (packet type 1) telegram.

type RadioOptional

type RadioOptional struct {
	SubTelegramNum int    `json:"sub_telegram_num"`
	DestinationID  string `json:"destination_id"`
	RSSIdBm        int    `json:"rssi_dbm"`
	SecurityLevel  int    `json:"security_level"`
}

RadioOptional is the optional-data block of a received RADIO_ERP1.

type Result

type Result struct {
	SyncByteOK      bool       `json:"sync_byte_ok"`
	DataLength      int        `json:"data_length"`
	OptionalLength  int        `json:"optional_length"`
	PacketType      int        `json:"packet_type"`
	PacketTypeName  string     `json:"packet_type_name"`
	HeaderCRC8      string     `json:"header_crc8"`
	HeaderCRC8Valid bool       `json:"header_crc8_valid"`
	DataCRC8        string     `json:"data_crc8"`
	DataCRC8Valid   bool       `json:"data_crc8_valid"`
	DataHex         string     `json:"data_hex,omitempty"`
	OptionalHex     string     `json:"optional_hex,omitempty"`
	Radio           *RadioERP1 `json:"radio_erp1,omitempty"`
	Notes           []string   `json:"notes,omitempty"`
}

Result is the decoded ESP3 packet.

func Decode

func Decode(hexStr string) (*Result, error)

Decode parses an EnOcean ESP3 packet from hex. ':' / '-' / '_' / whitespace separators and a '0x' prefix are tolerated.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL