Skip to content

Commit a39d40d

Browse files
authored
Read 0 bytes when checking for script support (#841)
* Read only 1 byte when checking for script support * Update script support check to read 0 bytes
1 parent 39fe1e4 commit a39d40d

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

aioshelly/rpc_device/device.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,19 @@ async def script_list(self) -> list[ShellyScript]:
359359
scripts: list[ShellyScript] = data["scripts"]
360360
return scripts
361361

362-
async def script_getcode(self, script_id: int) -> ShellyScriptCode:
363-
"""Get script code from 'Script.GetCode'."""
364-
return cast(
365-
ShellyScriptCode, await self.call_rpc("Script.GetCode", {"id": script_id})
366-
)
362+
async def script_getcode(
363+
self, script_id: int, offset: int = 0, bytes_to_read: int | None = None
364+
) -> ShellyScriptCode:
365+
"""Get script code from 'Script.GetCode'.
366+
367+
offset: The offset in bytes to start reading from.
368+
bytes_to_read: The number of bytes to read from the script.
369+
If None, read the whole script.
370+
"""
371+
params = {"id": script_id, "offset": offset}
372+
if bytes_to_read is not None:
373+
params["len"] = bytes_to_read
374+
return cast(ShellyScriptCode, await self.call_rpc("Script.GetCode", params))
367375

368376
async def script_putcode(self, script_id: int, code: str) -> None:
369377
"""Set script code from 'Script.PutCode'."""
@@ -616,8 +624,8 @@ async def _retrieve_blutrv_components(self, components: dict[str, Any]) -> None:
616624
async def supports_scripts(self) -> bool:
617625
"""Check if the device supports scripts.
618626
619-
Try to read a script to check if the device supports scripts,
620-
if it supports scripts, it should return the script
627+
Try to read 0 byte from a script to check if the device supports scripts,
628+
if it supports scripts, it should reply with '{"data":"", "left":0}'
621629
or a specific error code if the script does not exist.
622630
{"code":-105,"message":"Argument 'id', value 1 not found!"}
623631
@@ -630,7 +638,7 @@ async def supports_scripts(self) -> bool:
630638
{"code":404,"message":"No handler for Script.GetCode"}
631639
"""
632640
try:
633-
await self.script_getcode(1)
641+
await self.script_getcode(1, bytes_to_read=0)
634642
except RpcCallError as err:
635643
# The device supports scripts, but the script does not exist
636644
if err.code == RPC_CALL_ERR_INVALID_ARG:
@@ -643,5 +651,5 @@ async def supports_scripts(self) -> bool:
643651
return False
644652
raise
645653

646-
# The device returned a script, it supports scripts
654+
# The device returned a script response, it supports scripts
647655
return True

tests/rpc_device/test_device.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ async def test_script_getcode(rpc_device: RpcDevice) -> None:
532532
assert result == {"data": "super duper script"}
533533
assert rpc_device.call_rpc_multiple.call_count == 1
534534
assert rpc_device.call_rpc_multiple.call_args[0][0][0][0] == "Script.GetCode"
535-
assert rpc_device.call_rpc_multiple.call_args[0][0][0][1] == {"id": 8}
535+
assert rpc_device.call_rpc_multiple.call_args[0][0][0][1] == {"id": 8, "offset": 0}
536536

537537

538538
@pytest.mark.asyncio
@@ -819,7 +819,11 @@ async def test_supports_scripts(
819819
assert result == supports_scripts
820820
assert rpc_device.call_rpc_multiple.call_count == 1
821821
assert rpc_device.call_rpc_multiple.call_args[0][0][0][0] == "Script.GetCode"
822-
assert rpc_device.call_rpc_multiple.call_args[0][0][0][1] == {"id": 1}
822+
assert rpc_device.call_rpc_multiple.call_args[0][0][0][1] == {
823+
"id": 1,
824+
"len": 0,
825+
"offset": 0,
826+
}
823827

824828

825829
@pytest.mark.asyncio

0 commit comments

Comments
 (0)