|
27 | 27 | ) |
28 | 28 | from zigpy.zdo.types import SimpleDescriptor |
29 | 29 |
|
30 | | -from zigpy_deconz.exception import APIException, CommandError, MismatchedResponseError |
| 30 | +from zigpy_deconz.exception import CommandError, MismatchedResponseError, ParsingError |
31 | 31 | import zigpy_deconz.types as t |
32 | 32 | import zigpy_deconz.uart |
33 | 33 | from zigpy_deconz.utils import restart_forever |
@@ -568,7 +568,11 @@ async def _command(self, cmd, **kwargs): |
568 | 568 |
|
569 | 569 | if self._uart is None: |
570 | 570 | # connection was lost |
571 | | - raise CommandError(Status.ERROR, "API is not running") |
| 571 | + raise CommandError( |
| 572 | + "API is not running", |
| 573 | + status=Status.ERROR, |
| 574 | + command=command, |
| 575 | + ) |
572 | 576 |
|
573 | 577 | async with self._command_lock(priority=self._get_command_priority(command)): |
574 | 578 | seq = self._seq |
@@ -616,11 +620,15 @@ def data_received(self, data: bytes) -> None: |
616 | 620 | try: |
617 | 621 | params, rest = t.deserialize_dict(command.payload, rx_schema) |
618 | 622 | except Exception: |
619 | | - LOGGER.warning("Failed to parse command %s", command, exc_info=True) |
| 623 | + LOGGER.debug("Failed to parse command %s", command, exc_info=True) |
620 | 624 |
|
621 | 625 | if fut is not None and not fut.done(): |
622 | 626 | fut.set_exception( |
623 | | - APIException(f"Failed to deserialize command: {command}") |
| 627 | + ParsingError( |
| 628 | + f"Failed to parse command: {command}", |
| 629 | + status=Status.ERROR, |
| 630 | + command=command, |
| 631 | + ) |
624 | 632 | ) |
625 | 633 |
|
626 | 634 | return |
@@ -677,7 +685,11 @@ def data_received(self, data: bytes) -> None: |
677 | 685 | # Make sure we do not resolve the future |
678 | 686 | fut = None |
679 | 687 | elif status != Status.SUCCESS: |
680 | | - exc = CommandError(status, f"{command.command_id}, status: {status}") |
| 688 | + exc = CommandError( |
| 689 | + f"{command.command_id}, status: {status}", |
| 690 | + status=status, |
| 691 | + command=command, |
| 692 | + ) |
681 | 693 |
|
682 | 694 | if fut is not None: |
683 | 695 | try: |
@@ -905,10 +917,21 @@ async def change_network_state(self, new_state: NetworkState) -> None: |
905 | 917 | async def add_neighbour( |
906 | 918 | self, nwk: t.NWK, ieee: t.EUI64, mac_capability_flags: t.uint8_t |
907 | 919 | ) -> None: |
908 | | - await self.send_command( |
909 | | - CommandId.update_neighbor, |
910 | | - action=UpdateNeighborAction.ADD, |
911 | | - nwk=nwk, |
912 | | - ieee=ieee, |
913 | | - mac_capability_flags=mac_capability_flags, |
914 | | - ) |
| 920 | + try: |
| 921 | + await self.send_command( |
| 922 | + CommandId.update_neighbor, |
| 923 | + action=UpdateNeighborAction.ADD, |
| 924 | + nwk=nwk, |
| 925 | + ieee=ieee, |
| 926 | + mac_capability_flags=mac_capability_flags, |
| 927 | + ) |
| 928 | + except ParsingError as exc: |
| 929 | + # Older Conbee III firmwares send back an invalid response |
| 930 | + status = Status(exc.command.payload[0]) |
| 931 | + |
| 932 | + if status != Status.SUCCESS: |
| 933 | + raise CommandError( |
| 934 | + f"{exc.command.command_id}, status: {status}", |
| 935 | + status=status, |
| 936 | + command=exc.command, |
| 937 | + ) from exc |
0 commit comments