From 51eb496367ce33ba6408492ee55f13938f1b859f Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 11 Aug 2025 17:23:57 +1000 Subject: [PATCH 1/4] requirements: remove `typing-extensions` The `typing-extensions` module is no longer used. Signed-off-by: Jordan Yates --- pyproject.toml | 1 - requirements.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6b69543..95e7311 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,6 @@ dependencies = [ "rich", "simple-term-menu", "tabulate", - "typing-extensions", "keyring", "pyocd", "pyyaml", diff --git a/requirements.txt b/requirements.txt index 14616f7..4177401 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,5 @@ pyocd python-dateutil simple-term-menu tabulate -typing-extensions keyring paho-mqtt From 84f78775132cc8370200ac44fa4fe54ca43c4b7f Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 11 Aug 2025 17:35:01 +1000 Subject: [PATCH 2/4] tools: provision: Windows menu selection Use `console.choose_one`, which uses `simple_term_menu` internally but also provides a fallback for Windows. Signed-off-by: Jordan Yates --- src/infuse_iot/tools/provision.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/infuse_iot/tools/provision.py b/src/infuse_iot/tools/provision.py index c84f860..93df969 100644 --- a/src/infuse_iot/tools/provision.py +++ b/src/infuse_iot/tools/provision.py @@ -9,11 +9,6 @@ import sys from http import HTTPStatus -try: - from simple_term_menu import TerminalMenu -except NotImplementedError: - TerminalMenu = None - from infuse_iot.api_client import Client from infuse_iot.api_client.api.board import get_board_by_id, get_boards from infuse_iot.api_client.api.device import ( @@ -24,6 +19,7 @@ from infuse_iot.api_client.models import Board, DeviceMetadata, Error, NewDevice from infuse_iot.commands import InfuseCommand from infuse_iot.credentials import get_api_key +from infuse_iot.util.console import choose_one from infuse_iot.util.soc import nrf, soc, stm @@ -90,11 +86,7 @@ def create_device(self, client: Client, soc_name: str, hardware_id_str: str): sys.exit(f"Organisation query failed {orgs}") options = [f"{o.name:20s} ({o.id})" for o in orgs] - if TerminalMenu is None: - sys.exit("Specify organisation with --organisation:\n" + "\n".join(options)) - - terminal_menu = TerminalMenu(options) - idx = terminal_menu.show() + idx, _val = choose_one("Organisation", options) self._org = orgs[idx].id if self._board is None: @@ -103,11 +95,7 @@ def create_device(self, client: Client, soc_name: str, hardware_id_str: str): sys.exit(f"Board query failed {boards}") options = [f"{b.name:20s} ({b.id})" for b in boards] - if TerminalMenu is None: - sys.exit("Specify board with --board:\n" + "\n".join(options)) - - terminal_menu = TerminalMenu(options) - idx = terminal_menu.show() + idx, _val = choose_one("Board", options) self._board = boards[idx].id board = get_board_by_id.sync(client=client, id=self._board) if not isinstance(board, Board): From 5eb6c6a7dec2ba521bbfedbb3ebd7fa460e6b4eb Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 12 Aug 2025 20:30:52 +1000 Subject: [PATCH 3/4] tools: rpc_cloud: display route info Display route information in the output of `rpc_cloud query`. Signed-off-by: Jordan Yates --- src/infuse_iot/tools/rpc_cloud.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/infuse_iot/tools/rpc_cloud.py b/src/infuse_iot/tools/rpc_cloud.py index 3906e23..b2abcaa 100644 --- a/src/infuse_iot/tools/rpc_cloud.py +++ b/src/infuse_iot/tools/rpc_cloud.py @@ -86,9 +86,19 @@ def query(self, client: Client): rsp = get_rpc_by_id.sync(client=client, id=UUID(self._args.id)) if isinstance(rsp, Error) or rsp is None: sys.exit(f"Failed to query RPC state ({rsp})") - print(f"RPC State: {rsp.downlink_message.status}") - if rsp.downlink_message.status == DownlinkMessageStatus.COMPLETED: - rpc_rsp = rsp.downlink_message.rpc_rsp + downlink = rsp.downlink_message + print(f"RPC State: {downlink.status}") + if downlink.status in [DownlinkMessageStatus.SENT, DownlinkMessageStatus.COMPLETED]: + route = downlink.rpc_req.route + if downlink.sent_at: + print(f" At: {downlink.sent_at}") + if route: + if route.forwarded: + print(f" Through: {route.forwarded.device_id} ({route.forwarded.route.interface.upper()})") + else: + print(f" Through: Direct ({route.interface.upper()})") + if downlink.status == DownlinkMessageStatus.COMPLETED: + rpc_rsp = downlink.rpc_rsp assert isinstance(rpc_rsp, RpcRsp) print(f" Result: {rpc_rsp.return_code}") if rpc_rsp.params: From 8bf8b0607e3b70063ec112d0398b88ef0665c5c1 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 12 Aug 2025 20:31:53 +1000 Subject: [PATCH 4/4] tools: rpc_cloud: print command to query state Display the command that can be used to query the state of the queued command directly. Signed-off-by: Jordan Yates --- src/infuse_iot/tools/rpc_cloud.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/infuse_iot/tools/rpc_cloud.py b/src/infuse_iot/tools/rpc_cloud.py index b2abcaa..5c72e46 100644 --- a/src/infuse_iot/tools/rpc_cloud.py +++ b/src/infuse_iot/tools/rpc_cloud.py @@ -80,7 +80,8 @@ def queue(self, client: Client): rsp = send_rpc.sync(client=client, body=rpc_msg) if isinstance(rsp, Error) or rsp is None: sys.exit(f"Failed to queue RPC ({rsp})") - print(f"Queued RPC ID: {rsp.id}") + print("Query RPC state with:") + print(f"\tinfuse rpc_cloud query --id {rsp.id}") def query(self, client: Client): rsp = get_rpc_by_id.sync(client=client, id=UUID(self._args.id))