Skip to content

Releases: j5lien/enocean

2.1.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 15:03
2c0f283

Structured logs: every record names its kind in an event field and carries its context, so logs can be filtered and
aggregated without parsing messages (e.g. event:serial_error in VictoriaLogs). The events and their fields are listed
in the monitoring guide.

Added

  • event field on the library's log records: packet_received, packet_sent, teach_in, base_id_received,
    base_id_timeout, communicator_started/stopped, client_connected/disconnected, serial_error,
    processing_error, header_crc_error, data_crc_error, malformed_packet, unknown_profile, unknown_field...
  • Their context as fields: base_id; transport, port, host and client for the transports; error for serial
    port errors (also in the message, it was lost); length of a corrupted packet; data and optional (hex) of a
    malformed one, to replay it; eep and command of an unknown profile; shortcut of an unknown field; outcome of
    a teach-in.
  • Packet records also carry destination, status, repeater_count and eep.
  • SerialCommunicator.port, the serial port it was opened on.

Changed

  • The packet_type and rorg fields of log records are enum names (RADIO_ERP1, VLD) instead of integers, as in
    packet.to_dict(): log queries on their numeric values need updating.
  • The communicators' started/stopped messages name the port, and the TCP client messages the client's address.

2.0.2

Choose a tag to compare

@github-actions github-actions released this 29 Sep 15:00
c23733c

Fixed

  • RadioPacket.dbm is None for telegrams to send (those built by RadioPacket.create(), the actuators and UTE
    teach-in responses), instead of -255: their dBm byte is 0xFF, which ESP3 uses when sending, not a signal strength.
    This also fixes to_dict(), the dbm field of the Sending log, and str(packet), which no longer shows a signal
    strength when there is none.

2.0.1

Choose a tag to compare

@github-actions github-actions released this 29 Sep 14:44
916f446

Fixed

  • status and repeater_count of VLD (D2) telegrams: the status was read from the last optional byte (the security
    level, always 0) instead of the last data byte, so it was always 0. The status is now the last data byte and the
    repeater count its low nibble for every radio telegram (RPS, 1BS, 4BS, VLD, MSC, UTE...). Decoding is unchanged:
    no VLD profile has conditions on the status.

2.0.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 08:37
b562253

The 270 profiles of the official EnOcean Alliance specification, an integration API (device registry, packet
serialization, actuator commands, teach-in), monitoring (statistics, health, Prometheus, structured logs) and a
documentation site. Upgrading from 1.0: see the migration guide.

Breaking changes

  • The profiles are generated from the official EnOcean Alliance specification (EEP 2.6.8), and EEP.xml is replaced
    by enocean/protocol/profiles/ (EEP.xml_root by EEP.xml_index; EEP.telegrams loads profiles on access): field shortcuts and value
    descriptions are the official ones. Renamed shortcuts in previously supported profiles: A5-07-01 PIR → PIRS,
    A5-09-06 ACT → Act, A5-09-07 PM2.5/PM2.5a → PM25/PM25a, A5-09-0C CONC → Conc, A5-11-02 CTS → CST,
    D2-01-xx DE/DN/EP/QU/MDLSB/MDMSB → de/dn/ep/qu/MD_LSB/MD_MSB, F6-02-04 EB/RAO/RBO →
    EBO/RA0/RB0. 4BS and 1BS profiles now decode their learn bit (LRNB, LRN). Enum descriptions changed (e.g.
    'Button AI' → 'Button AI: "Switch light on" or ...'; ranges read 'Output channel (to load): 1'); create()
    still accepts the short label before the colon. Some enum ranges decode to numbers (e.g. D2-05 POS: 50.0 %).
  • Decoding aligned with the specification: A5-20-01 direction 2 TMP scale was inverted, A5-38-08 EDIM is a
    percentage (was the raw value), A5-13-01 only covers weather station telegrams with identifier 1 (the others are
    A5-13-02 to A5-13-06), F6-02-xx telegrams without the NU bit use the spec's "released / several buttons" variant.
  • SerialCommunicator requires its port (the default was /dev/ttyAMA0, a Raspberry Pi UART).
  • packet.received is a timezone-aware UTC datetime, set by Packet.parse_msg() (was a naive local datetime set by
    the communicator); comparing it with naive datetimes raises TypeError.
  • Packet(...) raises TypeError for data or optional data that isn't a list of ints, bytes, bytearray or a
    tuple (it was silently replaced by an empty list).
  • Removed PACKET.RADIO and PACKET.RADIO_ADVANCED: use PACKET.RADIO_ERP1 and PACKET.RADIO_ERP2
    (PACKET(1).name is now RADIO_ERP1).
  • Removed enocean.decorators (a test helper).
  • examples/enocean_example.py is no longer installed as a script.
  • enocean.protocol.eep no longer re-exports RORG: import it from enocean.protocol.constants.

Deprecated

  • UTETeachInPacket.channel: use number_of_channels.
  • RadioPacket.dBm: use dbm, which is None instead of 0 when the module didn't report the signal strength.

Added

  • Documentation site (https://j5lien.github.io/enocean/): getting started, concepts, guides, API reference generated
    from the docstrings (now on the whole public API), migration guide; its examples are run by the tests.
  • Profiles are loaded on first use (one file per profile under enocean/protocol/profiles/): building EEP()
    reads a small index (0.6 ms instead of 16 ms for the single 1.5 MB file), and importing enocean takes about half
    the time (__version__ is resolved on demand).
  • 270 profiles, generated from the official specification (205 more than before), with make eep; profiles
    missing from or unusable in the spec kept in tools/eep_additions.xml (D2-14-30, D2-14-41, F6-10-00, F6-10-01).
  • Profile variants selected by conditions on data or status bits (e.g. F6-02-02 by T21/NU, D2-01 extended commands by
    ECID), and enum ranges carrying a scale.
  • packet.to_dict(): JSON-serializable view of a packet (hex IDs, enum names that don't raise on unknown values,
    ISO reception time, EEP and decoded values).
  • EEPId (EEPId.parse('D2-01-12')), packet.eep_id and packet.command: the profile and command variant applied.
  • communicator.learn(timeout, max_devices): a teach-in window answering UTE teach-in requests even with
    teach_in=False, adding the taught-in devices to the device registry and returning them.
  • SwitchActuator (D2-01: set_output, turn_on, turn_off, query_status) and BlindActuator (D2-05: go_to,
    stop, query_position) in enocean.actuators, sending from the module's base ID.
  • DeviceRegistry / Device (enocean.devices): known devices and their profiles, default profiles per RORG and
    ignored devices. Communicators given devices= deliver packets decoded with their device's profile (packet.device,
    packet.parsed) and drop ignored devices (packets_ignored statistic and metric).
  • Profile introspection: EEP().profiles() lists the profiles, EEP().describe('D2-01-12') their variants and
    fields (kind, position, unit, ranges, enum values).
  • The public API is importable from the package: from enocean import SerialCommunicator, RadioPacket, RORG;
    enocean.__version__.
  • SerialCommunicator(teach_in=...), like TCPCommunicator.
  • Packet(...) accepts bytes and bytearray data.

Fixed

  • F6-10-00 window handle position read the right bits with wrong labels (now: horizontal/open, up/tilted,
    down/closed).
  • create(command=0) ignored the command.
  • UTE teach-in: deletion requests were answered as accepted teach-ins; they are now answered as deletions (as are
    non-specific requests from devices already known), and requests for profiles unknown to EEP.xml are refused.
  • Profiles with several commands (e.g. D2-01-12, D2-05-00): decoding without command= picks the variant the
    telegram carries instead of the profile's first one (e.g. a D2-01-12 "set output" command was decoded with the
    status layout).
  • create(command=...) wrote the command into a field named CMD only: A5-13-01 and A5-38-08 packets were sent with
    command 0.
  • A5-04-02 temperature scale: raw range 0...250 per the EEP specification (was 0...255, reading up to 1.6 °C low).
  • UTETeachInPacket.number_of_channels was never read from the telegram (always 0xFF).
  • Packet(type, bytearray(...)) silently lost its data.

1.0.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 14:03

First release of the j5lien/enocean fork of
kipe/enocean, whose last release was 0.60.1.

Breaking changes

  • Python 3.10 or later is required; Python 2 compatibility code is gone.
  • EEP.xml is loaded with the standard library's xml.etree instead of BeautifulSoup: EEP.soup is replaced by
    EEP.xml_root, and EEP.telegrams holds xml.etree.ElementTree.Element objects.
  • The beautifulsoup4 and enum-compat dependencies are dropped; pyserial>=3.5 is the only dependency.
  • RadioPacket.create() raises ValueError for an unknown VLD profile (was AttributeError).

Added

  • EEP profiles: A5-04-02, A5-09-06, A5-09-07, A5-09-0C, A5-12-00, A5-13-01, D2-01-12, D2-14-30, D2-14-41,
    F6-02-03, F6-02-04.
  • TCPCommunicator accepts callback and teach_in, like SerialCommunicator.
  • Type annotations for the whole package (py.typed); decoded fields are typed as FieldValue.

Fixed

  • ESP3 parser: a corrupted header or a stray 0x55 no longer makes the parser drop the valid packets that follow; it
    now resynchronizes on the next sync byte after any CRC error.
  • Radio packets without optional data (allowed by ESP3, omitted by some gateways) no longer crash the parser.
  • Packets too short for their type are returned unparsed instead of raising or being reported as CRC errors.
  • Decoding a telegram shorter than its EEP profile no longer raises.
  • UTE teach-in received before the base ID is known: the base ID is now requested and the teach-in answered, instead of
    blocking the communicator thread, raising TypeError and losing the packet.
  • Communicator.base_id works with a callback, and no longer reorders the receive queue while fetching the base ID.
  • TCPCommunicator crashed on every client connection, and only parsed data once the client disconnected.
  • communicators.utils.send_to_tcp_socket was broken on Python 3.
  • SerialCommunicator logs write errors before stopping.
  • EEP definitions: D2-01-12 enum values written in binary (default state, external button mode), out-of-range dim
    timers and measurement delta ranges; missing telegram length on D2-14-30 and D2-14-41 (create() failed); an
    attribute on A5-13-01 that only worked with a case-insensitive parser.
  • SUPPORTED_PROFILES.md lists every profile again.

Changed

  • Loading EEP.xml is about 20× faster and packet creation/decoding about 5× faster.
  • Development: uv, pytest (with end-to-end communicator tests on a pseudo-terminal, property-based parser tests and
    tests over every EEP profile), ruff, mypy, pre-commit hooks, GitHub Actions CI and Dependabot.