response.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. # responses.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro).
  2. # This copyright was auto-generated on Wed, Sep 1, 2021 5:05:49 PM
  3. """Any responses that are returned from GoPro commands."""
  4. from __future__ import annotations
  5. import enum
  6. import logging
  7. from dataclasses import dataclass
  8. from typing import Generic, TypeVar
  9. from open_gopro.domain.enum import GoProIntEnum
  10. from open_gopro.models.constants import ErrorCode, QueryCmdId
  11. from open_gopro.models.types import ResponseType
  12. from open_gopro.util import pretty_print
  13. logger = logging.getLogger(__name__)
  14. T = TypeVar("T")
  15. class GoProBlePacketHeader(enum.Enum):
  16. """Packet Headers."""
  17. GENERAL = 0b00
  18. EXT_13 = 0b01
  19. EXT_16 = 0b10
  20. RESERVED = 0b11
  21. CONT = enum.auto()
  22. @dataclass
  23. class GoProResp(Generic[T]):
  24. """The object used to encapsulate all GoPro responses.
  25. It consists of several common properties / attribute and a data attribute that varies per response.
  26. >>> gopro = WirelessGoPro()
  27. >>> await gopro.open()
  28. >>> response = await (gopro.ble_setting.resolution).get_value()
  29. >>> print(response)
  30. Now let's inspect the responses various attributes / properties:
  31. >>> print(response.status)
  32. ErrorCode.SUCCESS
  33. >>> print(response.ok)
  34. True
  35. >>> print(response.identifier)
  36. QueryCmdId.GET_SETTING_VAL
  37. >>> print(response.protocol)
  38. Protocol.BLE
  39. Now let's print it's data as (as JSON):
  40. >>> print(response)
  41. {
  42. "id" : "QueryCmdId.GET_SETTING_VAL",
  43. "status" : "ErrorCode.SUCCESS",
  44. "protocol" : "Protocol.BLE",
  45. "data" : {
  46. "SettingId.RESOLUTION" : "Resolution.RES_4K_16_9",
  47. },
  48. }
  49. Attributes:
  50. protocol (GoProResp.Protocol): protocol response was received on
  51. status (ErrorCode): status of response
  52. data (T): parsed response data
  53. identifier (ResponseType): response identifier, the type of which will vary depending on the response
  54. """
  55. class Protocol(enum.Enum):
  56. """Protocol that Command will be sent on."""
  57. BLE = "BLE"
  58. HTTP = "HTTP"
  59. protocol: GoProResp.Protocol
  60. status: ErrorCode
  61. data: T
  62. identifier: ResponseType
  63. def _as_dict(self) -> dict:
  64. """Represent the response as dictionary, merging it's data and meta information
  65. Returns:
  66. dict: dict representation
  67. """
  68. d = {
  69. "id": self.identifier,
  70. "status": self.status,
  71. "protocol": self.protocol,
  72. }
  73. if self.data:
  74. d["data"] = self.data # type: ignore
  75. return d
  76. def __eq__(self, obj: object) -> bool:
  77. if isinstance(obj, GoProIntEnum):
  78. return self.identifier == obj
  79. if isinstance(obj, GoProResp):
  80. return self.identifier == obj.identifier
  81. raise TypeError("Equal can only compare GoProResp and ResponseType")
  82. def __str__(self) -> str:
  83. return pretty_print(self._as_dict())
  84. def __repr__(self) -> str:
  85. return f"GoProResp <{str(self.identifier)}>"
  86. @property
  87. def ok(self) -> bool:
  88. """Are there any errors in this response?
  89. Returns:
  90. bool: True if the response is ok (i.e. there are no errors), False otherwise
  91. """
  92. return self.status in [ErrorCode.SUCCESS, ErrorCode.UNKNOWN]
  93. @property
  94. def _is_push(self) -> bool:
  95. """Was this response an asynchronous push?
  96. Returns:
  97. bool: True if yes, False otherwise
  98. """
  99. return self.identifier in [
  100. QueryCmdId.STATUS_VAL_PUSH,
  101. QueryCmdId.SETTING_VAL_PUSH,
  102. QueryCmdId.SETTING_CAPABILITY_PUSH,
  103. ]
  104. @property
  105. def _is_query(self) -> bool:
  106. """Is this response to a settings / status query?
  107. Returns:
  108. bool: True if yes, False otherwise
  109. """
  110. return isinstance(self.identifier, QueryCmdId)