使用第三方库构建脚本
我开始使用树莓派4和Python进行项目开发。在这个过程中,我发现了一个在GitHub上发布的Python库(keshavdv/victron-ble)。
我已经安装了这个库,并且可以在命令行界面(CLI)上成功运行一些命令(比如发现设备、读取数据、转储数据)。但是,当我尝试通过Python脚本来实现同样的功能时,我就有点困惑了。
我在命令行中使用的命令如下:
victron-ble discover
victron-ble dump "b5:55:aa:4d:99:33"
victron-ble read "b5:55:aa:4d:99:33"@"eb8c557386614231dbd741db97e457c5"
这是我尝试使用的代码:
from victron_ble.cli import discover
from victron_ble.cli import dump
from victron_ble.cli import read
my_id = b'b5:55:aa:4d:99:33'
#where my_id is the MAC address of the device I wish to observe
my_key = 'eb8c557386614231dbd741db97e457c5'
#where my_key is the encypytion key of the device I wish to observe
dump_result = dump(my_key)
print(dump_result)
discover_result = discover()
print(discover_result)
我尝试了以下格式的my_id变量,希望能成功:
b'b5:55:aa:4d:99:33'
'b5:55:aa:4d:99:33'
'b555aa4d9933'
b'b5-55-aa-4d-99-33'
[b5:55:aa:4d:99:33]
我想问的是,如何在脚本中复制命令行的指令,特别是MAC地址和密钥的格式要求。谢谢!
2 个回答
0
如果我运行你发布的代码/脚本,我会遇到以下错误:
$ python3 with_cli_funcs.py
Usage: with_cli_funcs.py [OPTIONS] ID
Try 'with_cli_funcs.py --help' for help.
Error: Got unexpected extra arguments (b 8 c 5 5 7 3 8 6 6 1 4 2 3 1 d b d 7 4 1 d b 9 7 e 4 5 7 c 5)
Process finished with exit code 2
看起来像是 click
这个库希望通过装饰器把值注入到 dump
函数里。https://github.com/keshavdv/victron-ble/blob/e28c5f8cc5f9f3062a2f36c2115d38214c07e741/victron_ble/cli.py#L45-L55
@cli.command(help="Dump all advertisements matching the given device ID")
@click.argument("id", type=str)
def dump(id: str):
loop = asyncio.get_event_loop()
async def scan():
scanner = DebugScanner(id)
await scanner.start()
asyncio.ensure_future(scan())
loop.run_forever()
我没有合适的设备,所以无法测试这个,但看起来下面的代码应该可以工作:
import asyncio
import logging
from victron_ble.scanner import DebugScanner
def my_scan(id: str):
loop = asyncio.get_event_loop()
async def scan():
scanner = DebugScanner(id)
await scanner.start()
asyncio.ensure_future(scan())
loop.run_forever()
if __name__ == '__main__':
my_id = 'b5:55:aa:4d:99:33'
logger = logging.getLogger("victron_ble")
logging.basicConfig()
logger.setLevel(logging.DEBUG)
my_scan(my_id)
1
根据库脚本和你的回答脚本,我进行了修改,试图实现读取功能:
@cli.command(help="Read data from specified devices")
@click.argument("device_keys", nargs=-1, type=DeviceKeyParam())
def read(device_keys: List[Tuple[str, str]]):
loop = asyncio.get_event_loop()
async def scan(keys):
scanner = Scanner(keys)
await scanner.start()
asyncio.ensure_future(scan({k: v for k, v in device_keys}))
loop.run_forever()
使用这个脚本:
import asyncio
import logging
from typing import List, Tuple
from victron_ble.scanner import Scanner
def my_scan(device_keys: List[Tuple[str, str]]):
loop = asyncio.get_event_loop()
async def scan(keys):
scanner = Scanner(keys)
await scanner.start()
asyncio.ensure_future(scan({k: v for k, v in device_keys}))
loop.run_forever()
if __name__ == '__main__':
my_id = ("b5:55:aa:4d:99:33","149c3c2865054b71962dcb06866524a9")
logger = logging.getLogger("victron_ble")
logging.basicConfig()
logger.setLevel(logging.DEBUG)
my_scan(my_id)
用上面提到的my_id的值,返回了错误:
asyncio.ensure_future(scan({k: v for k, v in device_keys}))
^^^^
ValueError: too many values to unpack (expected 2)
但是,如果我把my_id的值改成这个:
my_id = ("b5:55:aa:4d:99:33@149c3c2865054b71962dcb06866524a9")
返回的错误是:
asyncio.ensure_future(scan({k: v for k, v in device_keys}))
^^^^
ValueError: not enough values to unpack (expected 2, got 1)
运行这个命令行参数能得到正确的结果:
victron-ble read "b5:55:aa:4d:99:33"@"149c3c2865054b71962dcb06866524a9"
我在想,这可能是我脚本中的语法有问题??