Skip to content

Commit

Permalink
Route all data values if a get all
Browse files Browse the repository at this point in the history
  • Loading branch information
tcamise-gpsw committed Jul 10, 2024
1 parent 8d09c73 commit e2b7bdc
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,6 @@ async def _get_json(
url = self._base_url + message.build_url(**kwargs)
logger.debug(f"Sending: {url}")
logger.info(Logger.build_log_tx_str(pretty_print(message._as_dict(**kwargs))))
response: GoProResp | None = None
for retry in range(1, GoProBase.HTTP_GET_RETRIES + 1):
try:
http_response = requests.get(url, timeout=timeout, **self._build_http_request_args(message))
Expand All @@ -414,7 +413,6 @@ async def _get_json(
else:
raise GpException.ResponseTimeout(GoProBase.HTTP_GET_RETRIES)

assert response is not None
logger.info(Logger.build_log_rx_str(pretty_print(response._as_dict())))
return response

Expand All @@ -441,7 +439,6 @@ async def _put_json(
url = self._base_url + message.build_url(**kwargs)
body = message.build_body(**kwargs)
logger.debug(f"Sending: {url} with body: {json.dumps(body, indent=4)}")
response: GoProResp | None = None
for retry in range(1, GoProBase.HTTP_GET_RETRIES + 1):
try:
http_response = requests.put(url, timeout=timeout, json=body, **self._build_http_request_args(message))
Expand All @@ -461,5 +458,4 @@ async def _put_json(
else:
raise GpException.ResponseTimeout(GoProBase.HTTP_GET_RETRIES)

assert response is not None
return response
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def __init__(
# Responses that we are waiting for.
self._sync_resp_wait_q: SnapshotQueue[types.ResponseType] = SnapshotQueue()
# Synchronous response that has been parsed and are ready for their sender to receive as the response.
self._sync_resp_ready_q: SnapshotQueue[types.ResponseType] = SnapshotQueue()
self._sync_resp_ready_q: SnapshotQueue[GoProResp] = SnapshotQueue()

self._listeners: dict[types.UpdateType, set[types.UpdateCb]] = defaultdict(set)

Expand Down Expand Up @@ -531,7 +531,6 @@ async def _enforce_message_rules(
self, wrapped: Callable, message: Message, rules: MessageRules = MessageRules(), **kwargs: Any
) -> GoProResp:
# Acquire ready lock unless we are initializing or this is a Set Shutter Off command
response: GoProResp
if self._should_maintain_state and self.is_open and not rules.is_fastpass(**kwargs):
logger.trace(f"{wrapped.__name__} acquiring lock") # type: ignore
await self._ready_lock.acquire()
Expand Down Expand Up @@ -641,7 +640,9 @@ async def _route_response(self, response: GoProResp) -> None:
response (GoProResp): parsed response to route
"""
original_response = deepcopy(response)
if response._is_query and not response._is_push:
# We only support queries for either one ID or all ID's. If this is an individual query, extract the value
# for cleaner response data
if response._is_query and not response._is_push and len(response.data) == 1:
response.data = list(response.data.values())[0]

# Check if this is the awaited synchronous response (id matches). Note! these have to come in order.
Expand Down Expand Up @@ -722,7 +723,7 @@ async def _send_ble_message(

# Wait to be notified that response was received
try:
response: GoProResp = await asyncio.wait_for(self._sync_resp_ready_q.get(), WirelessGoPro.WRITE_TIMEOUT)
response = await asyncio.wait_for(self._sync_resp_ready_q.get(), WirelessGoPro.WRITE_TIMEOUT)
except queue.Empty as e:
logger.error(f"Response timeout of {WirelessGoPro.WRITE_TIMEOUT} seconds!")
raise GpException.ResponseTimeout(WirelessGoPro.WRITE_TIMEOUT) from e
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ def build(self) -> GoProResp:
camera_state[param_id] = []
continue
param_val = buf[:param_len]
logger.critical(f"ID {param_id} has length {param_len}")
buf = buf[param_len:]

# Add parsed value to response's data dict
Expand Down
8 changes: 8 additions & 0 deletions demos/python/sdk_wireless_camera_control/open_gopro/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,14 @@ def __init__(self, maxsize: int = 0) -> None:
self._lock = asyncio.Lock()
super().__init__(maxsize)

async def get(self) -> T:
"""Wrapper for passing generic type through to subclass
Returns:
T: type of this Snapshot queue
"""
return await super().get()

async def peek_front(self) -> T | None:
"""Get the first element without dequeueing it
Expand Down
2 changes: 1 addition & 1 deletion demos/python/sdk_wireless_camera_control/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ log_file_level = "DEBUG"
log_file_format = "%(threadName)13s: %(name)40s:%(lineno)5d %(asctime)s.%(msecs)03d %(levelname)-8s | %(message)s"
log_file_date_format = "%H:%M:%S"
filterwarnings = "ignore::DeprecationWarning"
timeout = 10
# timeout = 10
addopts = [
"-s",
"--capture=tee-sys",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import pytest
import requests
import requests_mock
from numpy import byte

from open_gopro.communicator_interface import HttpMessage
from open_gopro.constants import SettingId, StatusId
from open_gopro.constants import ErrorCode, QueryCmdId, SettingId, StatusId
from open_gopro.exceptions import GoProNotOpened, ResponseTimeout
from open_gopro.gopro_wireless import Params, WirelessGoPro, types
from open_gopro.models.response import GlobalParsers
from open_gopro.models.response import GlobalParsers, GoProResp
from open_gopro.types import ResponseType
from tests import mock_good_response


Expand Down Expand Up @@ -145,6 +147,56 @@ async def receive_encoding_status(id: types.UpdateType, value: bool):
await asyncio.wait_for(event.wait(), 1)


@pytest.mark.asyncio
async def test_route_all_data(mock_wireless_gopro_basic: WirelessGoPro):
mock_wireless_gopro_basic._loop = asyncio.get_running_loop()

# GIVEN
mock_data = {"one": 1, "two": 2}
mock_response = GoProResp(
protocol=GoProResp.Protocol.BLE,
status=ErrorCode.SUCCESS,
data=mock_data,
identifier=QueryCmdId.GET_SETTING_VAL,
)

# WHEN
# Make it appear to be the synchronous response
await mock_wireless_gopro_basic._sync_resp_wait_q.put(mock_response)
# Route the mock response
await mock_wireless_gopro_basic._route_response(mock_response)
# Get the routed response
routed_response = await mock_wireless_gopro_basic._sync_resp_ready_q.get()

# THEN
assert routed_response.data == mock_data


@pytest.mark.asyncio
async def test_route_individual_data(mock_wireless_gopro_basic: WirelessGoPro):
mock_wireless_gopro_basic._loop = asyncio.get_running_loop()

# GIVEN
mock_data = {"one": 1}
mock_response = GoProResp(
protocol=GoProResp.Protocol.BLE,
status=ErrorCode.SUCCESS,
data=mock_data,
identifier=QueryCmdId.GET_SETTING_VAL,
)

# WHEN
# Make it appear to be the synchronous response
await mock_wireless_gopro_basic._sync_resp_wait_q.put(mock_response)
# Route the mock response
await mock_wireless_gopro_basic._route_response(mock_response)
# Get the routed response
routed_response = await mock_wireless_gopro_basic._sync_resp_ready_q.get()

# THEN
assert routed_response.data == 1


@pytest.mark.asyncio
async def test_get_update_unregister_all(mock_wireless_gopro_basic: WirelessGoPro):
event = asyncio.Event()
Expand Down

0 comments on commit e2b7bdc

Please sign in to comment.