diff --git a/zigpy_zboss/api.py b/zigpy_zboss/api.py index 791f7e6..599b8a1 100644 --- a/zigpy_zboss/api.py +++ b/zigpy_zboss/api.py @@ -140,10 +140,7 @@ def frame_received(self, frame: Frame) -> bool: command_cls = c.COMMANDS_BY_ID[frame.hl_packet.header] - try: - command, _ = command_cls.from_frame(frame) - except ValueError: - raise + command = command_cls.from_frame(frame) LOGGER.debug("Received command: %s", command) matched = False diff --git a/zigpy_zboss/types/commands.py b/zigpy_zboss/types/commands.py index 19b4b8c..ea73fef 100644 --- a/zigpy_zboss/types/commands.py +++ b/zigpy_zboss/types/commands.py @@ -503,6 +503,13 @@ def from_frame(cls, frame, *, align=False) -> "CommandBase": else: params[param.name], data = param.type.deserialize(data) except ValueError: + if frame.hl_packet.header.control_type == ControlType.RSP: + # If the response to a request failed, the status code + # is different from 0 and the NCP does not send more data. + # Return a partial command object including the status. + status_code = params["StatusCode"] + if status_code != 0: + return cls(**params, partial=True) if not data and param.optional: # If we're out of data and the parameter is optional, # we're done @@ -517,13 +524,7 @@ def from_frame(cls, frame, *, align=False) -> "CommandBase": else: # Otherwise, let the exception happen raise - - # if data: - # raise ValueError( - # f"Frame {frame} contains trailing data after parsing: {data}" - # ) - - return cls(**params), data + return cls(**params) def matches(self, other: "CommandBase") -> bool: """Match parameters and values with other CommandBase."""