You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: let each control field part serialize itself
`CEMIFlags.to_knx()` took a `frame_type` argument that shadowed its own
`frame_type` field, which reads as if the field were the default. Give
`CEMIFrameType` and the new `CEMIAddressType` their own `to_knx()` / `from_knx()`
placing their single bit, and let the frame compose:
self.flags.to_knx() | frame_type.to_knx() | self.address_type.to_knx()
`CEMIFlags.to_knx()` now only sets the bits it owns and takes no arguments, so
nothing shadows anything. Control fields are handled as one 16 bit value
(Ctrl1 << 8 | Ctrl2) to make the composition a plain OR; `to_knx()` returns an
int and `from_knx()` takes one, as `TPCI.to_knx()` already does for a bit level
field. The Frame Type and Address Type bit masks are gone from the module level
constants - each enum places its own bit - which was the only place where the
8/16 bit mixing was actually confusing.
`CEMILData.dst_is_group_address` is replaced by `CEMILData.address_type`.
`block_0()` and the `SecureData` methods take `address_type: CEMIAddressType`
accordingly; the B0 flags octet is literally the Address Type bit plus the
Extended Frame Format, so `address_type.to_knx()` is that octet and the manual
constant is gone. Byte vectors are unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/changelog.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,10 +17,10 @@ nav_order: 2
17
17
-`confirm_error: bool` - only meaningful in an L_Data.con frame
18
18
-`hop_count: int` - replaces the `CEMILData.hops` property, which was removed
19
19
-`frame_type: CEMIFrameType` and `frame_format: CEMIFrameFormat` - informational; they hold what was received and are ignored when serializing
20
-
The Frame Type of an outgoing frame is derived from its NPDU length and the Address Type from the type of the destination address (also available as `CEMILData.dst_is_group_address`), so neither can disagree with the frame that is put on the wire. The raw bit masks moved to `xknx.cemi.flags` as module level constants.
20
+
The Frame Type of an outgoing frame is derived from its NPDU length and the Address Type from the type of the destination address (`CEMILData.address_type`), so neither can disagree with the frame that is put on the wire. `CEMIFrameType` and the new `CEMIAddressType` place their own bit via `to_knx()` / `from_knx()`; `CEMILData` composes the control field as `flags.to_knx() | frame_type.to_knx() | address_type.to_knx()`. Ctrl1 and Ctrl2 are handled as one 16 bit int, so `CEMIFlags.to_knx()` returns an `int` and `CEMIFlags.from_knx()` takes one. The remaining bit masks moved to `xknx.cemi.flags` as module level constants.
21
21
-`CEMIFlags` has a compact `__str__` used in `CEMILData.__repr__` - eg. `LOW STANDARD hop_count=6`, listing only the boolean flags that are set. The full dataclass `__repr__` shows every field.
22
22
-`CEMILData(flags=...)` is optional now and defaults to `CEMIFlags()` - low priority, hop count 6, no acknowledge request.
23
-
-`xknx.secure.data_secure_asdu.block_0()`, `SecureData.init_from_plain_apdu()` and `SecureData.get_plain_apdu()` take `dst_is_group_address: bool` instead of `frame_flags: int`. Only the Address Type bit of Ctrl2 ever reached the CCM input; passing it explicitly removes the mask.
23
+
-`xknx.secure.data_secure_asdu.block_0()`, `SecureData.init_from_plain_apdu()` and `SecureData.get_plain_apdu()` take `address_type: CEMIAddressType` instead of `frame_flags: int`. Only the Address Type bit of Ctrl2 ever reached the CCM input, so the B0 flags octet is `address_type.to_knx()` and `B0_AT_FIELD_FLAGS_MASK` is gone.
0 commit comments