Skip to content

Devices and decoding

Telegrams don't say which profile they follow: the receiver must know each device's profile. A DeviceRegistry records them, and communicators given one deliver packets already decoded.

import json

from enocean import RORG, DeviceRegistry, Packet

devices = DeviceRegistry.from_config(
    {
        '00:37:7E:06': {'eep': 'F6-02-02', 'name': 'Office wall switch', 'room': 'office'},
        '05:99:77:AF': {'eep': 'D2-01-12', 'name': 'Office light'},
    },
    defaults={RORG.RPS: 'F6-02-02'},  # profile to try for unknown devices, by RORG
    ignored=['FF:E8:06:02'],  # dropped by communicators using this registry
)

# The office light reporting channel 1 on (D2-01-12, command 4)
_, _, packet = Packet.parse_msg(bytes.fromhex('55 00 09 07 01 56 d2 04 61 e4 05 99 77 af 00 01 ff ff ff ff 49 00 93'))
device = devices.decode(packet)  # communicators given devices= do this for you

print(device.name, packet.eep_id, packet.command)  # Office light D2-01-12 4
print(packet.parsed['OV']['value'])  # Output value 1% to 100% or ON: 100
print(json.dumps(packet.to_dict(), indent=2))  # e.g. to index or publish it
assert packet.parsed['IO']['raw_value'] == 1

With a communicator

from enocean import RORG, DeviceRegistry, SerialCommunicator

devices = DeviceRegistry.from_config(
    {
        '00:37:7E:06': {'eep': 'F6-02-02', 'name': 'Office wall switch'},
        '05:99:77:AF': {'eep': 'D2-01-12', 'name': 'Office light'},
    },
    defaults={RORG.RPS: 'F6-02-02'},
    ignored=['FF:E8:06:02'],
)
communicator = SerialCommunicator(port='/dev/ttyUSB0', devices=devices)
communicator.start()

packet = communicator.receive.get()
print(packet.device.name if packet.device else 'unknown', packet.eep_id, packet.parsed)
  • Known devices are decoded with their profile, and the variant of multi-command profiles is recognized from the telegram. packet.device is the Device, packet.eep_id the profile applied and packet.command the variant.
  • Unknown devices are decoded with the default profile of their RORG, if any; packet.device is None.
  • Telegrams from ignored devices are dropped (and counted as packets_ignored in the statistics).
  • Teach-in requests and non-radio packets are delivered as they are.

Configuration

DeviceRegistry.from_config() takes a mapping, e.g. loaded from JSON, YAML or TOML: eep is the profile, name a label, and any other key goes to device.metadata. The {'rorg': ..., 'func': ..., 'type': ...} form is accepted instead of eep. Devices can also be added at run time: devices.add(Device('05:99:77:AF', EEPId.parse('D2-01-12'))).

Serializing packets

packet.to_dict() gives a JSON-serializable view: IDs and bytes as hex strings, enum names that fall back to hex for unknown values, the ISO 8601 reception time (UTC), the EEP, the decoded values and the device. It is meant for indexing, publishing (MQTT…) or logging packets.