使用第三方库构建脚本

-2 投票
2 回答
67 浏览
提问于 2025-04-12 19:38

我开始使用树莓派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"

我在想,这可能是我脚本中的语法有问题??

撰写回答