-
Notifications
You must be signed in to change notification settings - Fork 55
Description
I am in the process of writing a matter application to control a window covering.
The import!(WindowCovering) macro generates the handler trait, which contains this required method:
pub trait ClusterAsyncHandler {
// ...
async fn operational_status(
&self,
ctx: &ReadContext<'_>,
) -> Result<OperationalStatus, rs_matter::error::Error>;
// ...
}The method corresponds to the attribute OperationalStatus with the data type OperationalStatusBitmap in the Matter Application Cluster Specification R1.4.
The specification defines the data type in section 5.3.5.3 as an 8-bit bitmap type where
- the first 2 bits are "global operation state",
- the next two are for "lift operational state"
- and the next two for the "tilt operational state".
Then it defines that for each of the above bitranges how the two bits should be interpreted
0b00= Currently not moving0b01= Currently opening0b10= Currently closing
Assuming, I understand this correctly, the specification defines it like this:
enum CurrentMovement {
NotMoving,
Opening,
Closing
}
struct OperationalStatus {
global: CurrentMovement,
lift: CurrentMovement,
tilt: CurrentMovement,
}Three states that indicate the status of the operations.
The definition doesn't specify the interpretations for each of the state bits:
rs-matter/rs-matter-macros/src/idl/parser/controller-clusters.matter
Lines 5484 to 5488 in 2cf6302
| bitmap OperationalStatus : bitmap8 { | |
| kGlobal = 0x3; | |
| kLift = 0xC; | |
| kTilt = 0x30; | |
| } |
That is why the macro then generates something like this:
bitflags::bitflags! {
struct OperationalStatus: u8 {
const GLOBAL = 0x03; // 0b0000_0011
const LIFT = 0x0C; // 0b0000_1100
const TILT = 0x30; // 0b0011_1111
}
}
which is wrong, 0b11` is not a valid state for any of the operations.
I couldn't find any method to set the individual bits of each of the ranges, which makes this unusable?
I think the definition should look like this:
bitflags::bitflags! {
struct OperationalStatus: u8 {
const GLOBAL_OPENING = 0x01; // 0b0000_0001
const GLOBAL_CLOSING = 0x02; // 0b0000_0010
const LIFT_OPENING = 0x04; // 0b0000_0100
const LIFT_CLOSING = 0x08; // 0b0000_1000
const TILT_OPENING = 0x10; // 0b0001_0000
const TILT_CLOSING = 0x20; // 0b0010_0000
}
}which could then be used like this:
return OperationalStatus::GLOBAL_OPENING | OperationalStatus::LIFT_OPENING;