Giter Site home page Giter Site logo

pybricks / pybricksdev Goto Github PK

View Code? Open in Web Editor NEW
45.0 45.0 15.0 1.77 MB

pybricksdev: Python Package with Pybricks developer tools

Home Page: https://pypi.org/project/pybricksdev/

License: MIT License

Python 99.44% Makefile 0.21% Assembly 0.11% C 0.24%
lego mindstorms powered-up python

pybricksdev's People

Contributors

alphacraft9658 avatar dependabot[bot] avatar dlech avatar laurensvalk avatar lobodpav avatar novakasa avatar nstrijbosch avatar pepijndevos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pybricksdev's Issues

[Question] pybricksdev Compile script error

I tried this example explained here and I get unrecognized arguments error:

C:\Users\Gianluca\pybricksdev>poetry run pybricksdev compile 'print("Hello!"); print("world!");'
usage: pybricksdev compile [-h] script
pybricksdev compile: error: unrecognized arguments: print(world!);'

Without the print("world!"); part, It works

C:\Users\Gianluca\pybricksdev>poetry run pybricksdev compile 'print("Hello!");'

Bytes:
b'M\x05\x00\x1f $\x00\n\x00\x07\x1abuild\\_tmp.py\x00Qc\x00\x00'

// MPY file. Version: 5. Size: 29
const uint8_t script[] =
    0x4D, 0x05, 0x00, 0x1F, 0x20, 0x24, 0x00, 0x0A,
    0x00, 0x07, 0x1A, 0x62, 0x75, 0x69, 0x6C, 0x64,
    0x5C, 0x5F, 0x74, 0x6D, 0x70, 0x2E, 0x70, 0x79,
    0x00, 0x51, 0x63, 0x00, 0x00,
};

C:\Users\Gianluca\pybricksdev>

Why?

Pybricksdev changes for Remote Control based on Pybrickdev-Demo

Hi guys

I am using pybricksdev to do remote control of RI robot.
I developed this from pybricksdev-demo a while back.
It was working fine but then I updated the pybrickdev library and seems like alot of changes happened and does not work anymore.
Mostly related to how we open the hub and check status now.
Looks like PybricksHub does not exist now and hub.program_running also and maybe some other hub methods.
Below is code that was working but now does not.

Can you give me some comments, examples, or other docs that might help me get upgraded to new lib?

from pybricksdev.connections import PybricksHub
from pybricksdev.ble import find_device
from asyncio import gather, sleep, run
import msvcrt

async def main():
    print('main: Start')
    hub = PybricksHub()   
    # You can search for the address like this:
    address = await find_device()
    await hub.connect(address)
    await gather(
    hub.run('robot_Blast.py', print_output=True),
    forwarder(hub)
    )

    # Disconnect from the hub
    await hub.disconnect()
    print('main: Stop')

async def forwarder(hub):    
    print("forwarder: Start")

    # Give the hubs some time to start
    while not hub.program_running :
        #print('forwarder: Waiting for Hub to Run')
        await sleep(2)
    print('forwarder: Hub Running')
 
    # Keyboard command input loop                   
    while hub.program_running :
        # Non blocking keyboard Input
        if msvcrt.kbhit():
            # get char with or without echo
            command = msvcrt.getch()
            
            # clear any extra characters
            while msvcrt.kbhit():
                msvcrt.getch()
        else:  
            command= ''
        # Try to send to the receiving hub
        if len(command) > 0:
            try:
                await hub.write(bytes([ord(command)]))
            except:
                pass          
        # wait some    
        await sleep(.1)

    # Hub has stopped
    print('forwarder: Hub Not Running')

#start it up
run(main())

DFU restore via pydfu was removed

It currently says

# TODO: implement this using pydfu

even though it was implemented before. This may have been accidental as pydfu still seems to be used for flashing.

We could leave it like that if we fix #12 .

Error in installing pybricksdev on raspberry

Hi!

I'm trying to install pybrickdev on rapberrypi 3 model b: pip3 install pybricksdev --pre

Everything installing correctly. Only issue with mpy-cross-v5 and mpy-cross-v6 dependencies.
As I understood this is special version of mpy-cross for this project?
Regular mpy-cross installs without any issues.

Also have this problems if installing using pipx. Have no any problems with installation on Macbook Pro M1.
Appreciate any help, thanks

Environment

python 3.9.2
pip 23.0
setuptools 67.3.1

Linux 5.15.61-v7+ 
armv7l
Raspbian GNU/Linux 11 (bullseye)

Installation errors

Building wheels for collected packages: mpy-cross-v5, mpy-cross-v6
  Building wheel for mpy-cross-v5 (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for mpy-cross-v5 (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [64 lines of output]
      /tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/config/pyprojecttoml.py:108: _BetaConfiguration: Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*.
        warnings.warn(msg, _BetaConfiguration)
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib
      creating build/lib/mpy_cross_v5
      copying src/mpy_cross_v5/__main__.py -> build/lib/mpy_cross_v5
      copying src/mpy_cross_v5/__init__.py -> build/lib/mpy_cross_v5
      running egg_info
      writing src/mpy_cross_v5.egg-info/PKG-INFO
      writing dependency_links to src/mpy_cross_v5.egg-info/dependency_links.txt
      writing entry points to src/mpy_cross_v5.egg-info/entry_points.txt
      writing top-level names to src/mpy_cross_v5.egg-info/top_level.txt
      reading manifest file 'src/mpy_cross_v5.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      no previously-included directories found matching 'micropython/mpy-cross/build*'
      no previously-included directories found matching 'micropython/ports*'
      warning: no previously-included files found matching 'src/mpy_cross_v5/mpy-cross*'
      writing manifest file 'src/mpy_cross_v5.egg-info/SOURCES.txt'
      make: Entering directory '/tmp/pip-install-p0qb8eao/mpy-cross-v5_e00d7b26be71488ca5a9cfaff8de7a54/micropython/mpy-cross'
      Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
      ../py/py.mk:289: ../extmod/extmod.mk: No such file or directory
      make: *** No rule to make target '../extmod/extmod.mk'.  Stop.
      make: Leaving directory '/tmp/pip-install-p0qb8eao/mpy-cross-v5_e00d7b26be71488ca5a9cfaff8de7a54/micropython/mpy-cross'
      Traceback (most recent call last):
        File "/home/ml/Development/remote-machine/venv/lib/python3.9/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/home/ml/Development/remote-machine/venv/lib/python3.9/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/home/ml/Development/remote-machine/venv/lib/python3.9/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
          return _build_backend().build_wheel(wheel_directory, config_settings,
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 413, in build_wheel
          return self._build_with_temp_dir(['bdist_wheel'], '.whl',
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 398, in _build_with_temp_dir
          self.run_setup()
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 335, in run_setup
          exec(code, locals())
        File "<string>", line 79, in <module>
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/__init__.py", line 108, in setup
          return distutils.core.setup(**attrs)
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 185, in setup
          return run_commands(dist)
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
          dist.run_commands()
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
          self.run_command(cmd)
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 1221, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/wheel/bdist_wheel.py", line 325, in run
          self.run_command("build")
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
          self.distribution.run_command(command)
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 1221, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-eerkmbtn/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "<string>", line 52, in run
        File "/usr/lib/python3.9/subprocess.py", line 373, in check_call
          raise CalledProcessError(retcode, cmd)
      subprocess.CalledProcessError: Command '['make', '-C', PosixPath('/tmp/pip-install-p0qb8eao/mpy-cross-v5_e00d7b26be71488ca5a9cfaff8de7a54/micropython/mpy-cross'), 'BUILD=build-linux-armv7l']' returned non-zero exit status 2.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for mpy-cross-v5
  Building wheel for mpy-cross-v6 (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for mpy-cross-v6 (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [87 lines of output]
      /tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/config/pyprojecttoml.py:108: _BetaConfiguration: Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*.
        warnings.warn(msg, _BetaConfiguration)
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib
      creating build/lib/mpy_cross_v6
      copying src/mpy_cross_v6/__main__.py -> build/lib/mpy_cross_v6
      copying src/mpy_cross_v6/__init__.py -> build/lib/mpy_cross_v6
      running egg_info
      writing src/mpy_cross_v6.egg-info/PKG-INFO
      writing dependency_links to src/mpy_cross_v6.egg-info/dependency_links.txt
      writing entry points to src/mpy_cross_v6.egg-info/entry_points.txt
      writing top-level names to src/mpy_cross_v6.egg-info/top_level.txt
      reading manifest file 'src/mpy_cross_v6.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      no previously-included directories found matching 'micropython/mpy-cross/build*'
      no previously-included directories found matching 'micropython/ports*'
      warning: no previously-included files found matching 'src/mpy_cross_v6/mpy-cross*'
      writing manifest file 'src/mpy_cross_v6.egg-info/SOURCES.txt'
      make: Entering directory '/tmp/pip-install-p0qb8eao/mpy-cross-v6_ce0835038be947d289e34dd64d96afb5/micropython/mpy-cross'
      Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
      mkdir -p build-linux-armv7l/genhdr
      GEN build-linux-armv7l/genhdr/mpversion.h
      GEN build-linux-armv7l/genhdr/qstr.i.last
      ../py/modsys.c:39:10: fatal error: extmod/moduplatform.h: No such file or directory
         39 | #include "extmod/moduplatform.h"
            |          ^~~~~~~~~~~~~~~~~~~~~~~
      compilation terminated.
      Traceback (most recent call last):
        File "/tmp/pip-install-p0qb8eao/mpy-cross-v6_ce0835038be947d289e34dd64d96afb5/micropython/mpy-cross/../py/makeqstrdefs.py", line 203, in <module>
          preprocess()
        File "/tmp/pip-install-p0qb8eao/mpy-cross-v6_ce0835038be947d289e34dd64d96afb5/micropython/mpy-cross/../py/makeqstrdefs.py", line 73, in preprocess
          for output in p.imap(pp(flags), chunks):
        File "/usr/lib/python3.9/multiprocessing/pool.py", line 870, in next
          raise value
        File "/usr/lib/python3.9/multiprocessing/pool.py", line 125, in worker
          result = (True, func(*args, **kwds))
        File "/tmp/pip-install-p0qb8eao/mpy-cross-v6_ce0835038be947d289e34dd64d96afb5/micropython/mpy-cross/../py/makeqstrdefs.py", line 57, in run
          return subprocess.check_output(args.pp + flags + files)
        File "/usr/lib/python3.9/subprocess.py", line 424, in check_output
          return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
        File "/usr/lib/python3.9/subprocess.py", line 528, in run
          raise CalledProcessError(retcode, process.args,
      subprocess.CalledProcessError: Command '['gcc', '-E', '-I.', '-Ibuild-linux-armv7l', '-I..', '-Wall', '-Werror', '-Wextra', '-Wno-unused-parameter', '-Wpointer-arith', '-std=gnu99', '-Os', '-fdata-sections', '-ffunction-sections', '-fno-asynchronous-unwind-tables', '-DNO_QSTR', '../py/objzip.c', '../py/opmethods.c', '../py/sequence.c', '../py/stream.c', '../py/binary.c', '../py/builtinimport.c', '../py/builtinevex.c', '../py/builtinhelp.c', '../py/modarray.c', '../py/modbuiltins.c', '../py/modcollections.c', '../py/modgc.c', '../py/modio.c', '../py/modmath.c', '../py/modcmath.c', '../py/modmicropython.c', '../py/modstruct.c', '../py/modsys.c', '../py/moduerrno.c', '../py/modthread.c', '../py/vm.c', '../py/bc.c', '../py/showbc.c', '../py/repl.c', '../py/smallint.c', '../py/frozenmod.c']' returned non-zero exit status 1.
      make: *** [../py/mkrules.mk:108: build-linux-armv7l/genhdr/qstr.i.last] Error 1
      make: *** Deleting file 'build-linux-armv7l/genhdr/qstr.i.last'
      make: Leaving directory '/tmp/pip-install-p0qb8eao/mpy-cross-v6_ce0835038be947d289e34dd64d96afb5/micropython/mpy-cross'
      Traceback (most recent call last):
        File "/home/ml/Development/remote-machine/venv/lib/python3.9/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/home/ml/Development/remote-machine/venv/lib/python3.9/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/home/ml/Development/remote-machine/venv/lib/python3.9/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
          return _build_backend().build_wheel(wheel_directory, config_settings,
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 413, in build_wheel
          return self._build_with_temp_dir(['bdist_wheel'], '.whl',
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 398, in _build_with_temp_dir
          self.run_setup()
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 335, in run_setup
          exec(code, locals())
        File "<string>", line 79, in <module>
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/__init__.py", line 108, in setup
          return distutils.core.setup(**attrs)
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 185, in setup
          return run_commands(dist)
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
          dist.run_commands()
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
          self.run_command(cmd)
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 1221, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/wheel/bdist_wheel.py", line 325, in run
          self.run_command("build")
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
          self.distribution.run_command(command)
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 1221, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-s_9j_jm6/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "<string>", line 52, in run
        File "/usr/lib/python3.9/subprocess.py", line 373, in check_call
          raise CalledProcessError(retcode, cmd)
      subprocess.CalledProcessError: Command '['make', '-C', PosixPath('/tmp/pip-install-p0qb8eao/mpy-cross-v6_ce0835038be947d289e34dd64d96afb5/micropython/mpy-cross'), 'BUILD=build-linux-armv7l']' returned non-zero exit status 2.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for mpy-cross-v6
Failed to build mpy-cross-v5 mpy-cross-v6
ERROR: Could not build wheels for mpy-cross-v5, mpy-cross-v6, which is required to install pyproject.toml-based projects

Allow Python > 3.8

We currently require python = "~3.8", so users with 3.9 have to install pyenv.

@dlech , I think we did this due to a limitation in bleak at the time. Do you know if this has been resolved?

USB connection to Mindstorms Inventor does not work on macOS

Installed PyBricks on my Lego Mindstorms Inventor Hub using https://install.pybricks.com and tried to run an app on the hub.

The pybricksdev tool fails to find the hub. The https://code.pybricks.com works fine, though.

Envionment

  • macOS 12.1
  • Python 3.9.9
  • pybricksdev v1.0.0a19

Replication steps

Execute pybricksdev -d run usb --name "Pybricks Hub" test.py.

An error is thrown:

2021-12-30 19:52:59,546: DEBUG: asyncio: Using selector: KqueueSelector
Traceback (most recent call last):
  File "/Users/pavel/.local/bin/pybricksdev", line 8, in <module>
    sys.exit(main())
  File "/Users/pavel/.local/pipx/venvs/pybricksdev/lib/python3.10/site-packages/pybricksdev/cli/__init__.py", line 432, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "/usr/local/Cellar/[email protected]/3.10.1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/Cellar/[email protected]/3.10.1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
    return future.result()
  File "/Users/pavel/.local/pipx/venvs/pybricksdev/lib/python3.10/site-packages/pybricksdev/cli/__init__.py", line 200, in run
    await hub.connect(device_or_address)
  File "/Users/pavel/.local/pipx/venvs/pybricksdev/lib/python3.10/site-packages/pybricksdev/connections.py", line 457, in connect
    raise OSError("Could not find hub.")
OSError: Could not find hub.

When running this program:

from serial.tools import list_ports

devices = list_ports.comports()

for device in devices:
    print(device.product, ':', device.vid)

I get Pybricks Hub : 1155.

When looking into the ~/.local/pipx/venvs/pybricksdev/lib/python3.10/site-packages/pybricksdev/connections.py, line 451, I can see: a condition looking for a hard-coded string rather than the name supplied over the command line argument.

async def connect(self, device=None):
    """Connects to a SPIKE Prime or MINDSTORMS Inventor Hub."""

    # Go through all comports.
    port = None
    devices = list_ports.comports()
    for dev in devices:
        if dev.product == "LEGO Technic Large Hub in FS Mode" or dev.vid == 0x0694:
            port = dev.device
            break

This, however, does not make any sense. Neither the Pybricks Hub product nor 1155 VID will ever match the condition.

When changing the condition to

if dev.product == "Pybricks Hub" or dev.vid == 0x0694:

The connection is successful.

Multi-hub firmware download option

It's easy to miss minor differences between hubs, see e.g. this one.

This issue is to add a convenient command line option that will simply update all Pybricks Hubs in the neighborhood, even those not in bootloader mode already.

It is intended for developers, so instead of a zip path it will just require the path to pybricks-micropython. Since it is all async, all the ingredients are already there.

So the syntax is:

pybricksdev skynet /path/to/pybricks-micropython

Fix Python version

Recently the Python requirement was reduced to 3.6, and yet 3.8 features were used, like importlib.

We might want to fix the Python version or place an upper limit so we don't use features that don't actually exist in the versions that are supposed to work, or resolve it some other way.

This package is currently broken on Ubuntu 18.04, for example.

no repl

The online https://code.pybricks.com environment supports a repl for python.

I developed a repl in a python script at https://github.com/harcokuppens/repl_pybricks/ .
I also took the time to develop good handling of turning of the repl by pressing the button on the brick,
or for some cases the bluetooth connection brakes. ( eg. brick to far away).

I look at the source code of pybricksdev I learned how to implement the repl.
I think it also would be better for this repl to be integrated in pybricksdev. My intention was to make an implementation myself and do a pull request. However, I do not have the time to do this. Therefore I decided to make an issue instead.

Expected checksum

On Ubuntu 20.04 and ('primehub', '3.0.0b4', 'a0856ec1 on 2021-04-09'), I'm getting this:

pybricksdev run ble "Pybricks Hub" ~/git-pybricks/pybricks-micropython/tests/pup/sensors/color_color.py 
Searching for Pybricks Hub
Downloading 748 bytes in 8 steps.
Progress: 12%
Progress: 25%
Progress: 38%
Progress: 50%
Progress: 62%
Progress: 75%
Progress: 88%
Progress: 100%
2021-04-09 11:59:19,975: WARNING: Expected checksum 197 but got 13
2021-04-09 11:59:19,976: WARNING: Expected checksum 197 but got 32

...done.

It does run despite this.

This was working before.

TimeoutError when running simple program via pybricksdev on Mac OS X

Alright so I'll try to be as detailed as possible. I have this very simple program:

from pybricks.hubs import TechnicHub
from pybricks.parameters import Color
from pybricks.tools import wait

print("Hello, World!")

# Initialize the hub.
hub = TechnicHub()

# Turn the light on and off 5 times.
for i in range(5):

    hub.light.on(Color.RED)
    wait(1000)

    hub.light.off()
    wait(500)

It works fine via https://code.pybricks.com/. Then I simply followed the pybricksdev instructions over here and ran the program.

For a few seconds the light on my brick is just blue (not blinking), as if it is frozen. It doesn't seem like the program is being executed. In the logs see it finds and connects to my technic hub, eventually disconnects and throws a timeout error.

I also captured the bluetooth traffic via PacketLogger by the way: packetlog.zip

Any help is appreciated 😄

$ pybricksdev -d run ble robot.py 
2024-04-27 13:31:30,171: DEBUG: asyncio: Using selector: KqueueSelector
Searching for any hub with Pybricks service...
2024-04-27 13:31:30,382: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManagerDidUpdateState_
2024-04-27 13:31:30,383: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Bluetooth powered on
2024-04-27 13:31:30,383: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: 'isScanning' changed
2024-04-27 13:31:30,409: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,410: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,412: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 05BFA874-E12D-21CD-CD37-5FE0DA16D4D3: LE_WH-1000XM4 @ RSSI: -37 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,413: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 05BFA874-E12D-21CD-CD37-5FE0DA16D4D3: LE_WH-1000XM4 @ RSSI: -38 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,435: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,436: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,436: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device A5249550-D5DE-09D0-9A80-1F521BB6FF7C: iPhone van Thomas @ RSSI: -69 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataTimestamp', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,437: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device A5249550-D5DE-09D0-9A80-1F521BB6FF7C: iPhone van Thomas @ RSSI: -69 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataTimestamp', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,613: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,614: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,616: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 05BFA874-E12D-21CD-CD37-5FE0DA16D4D3: LE_WH-1000XM4 @ RSSI: -38 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,616: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 05BFA874-E12D-21CD-CD37-5FE0DA16D4D3: LE_WH-1000XM4 @ RSSI: -38 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,639: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,639: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 13:31:30,640: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 166E8D19-D855-BB6F-9F52-C81E85EB1A39: Technic Hub A @ RSSI: -45 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataServiceUUIDs', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataIsConnectable'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,640: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 166E8D19-D855-BB6F-9F52-C81E85EB1A39: Technic Hub A @ RSSI: -45 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fb4ee3cddb0>
2024-04-27 13:31:30,641: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: 'isScanning' changed
2024-04-27 13:31:30,641: INFO: pybricksdev.connections: Connecting to 166E8D19-D855-BB6F-9F52-C81E85EB1A39
2024-04-27 13:31:30,641: DEBUG: bleak.backends.corebluetooth.client: CentralManagerDelegate  at <CentralManagerDelegate: 0x7fb4eadbdfe0>
2024-04-27 13:31:30,641: DEBUG: bleak.backends.corebluetooth.client: Connecting to BLE device @ 166E8D19-D855-BB6F-9F52-C81E85EB1A39
2024-04-27 13:31:31,011: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didConnectPeripheral_
2024-04-27 13:31:31,012: DEBUG: bleak.backends.corebluetooth.client: Retrieving services...
2024-04-27 13:31:32,210: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverServices_
2024-04-27 13:31:32,210: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Services discovered
2024-04-27 13:31:32,211: DEBUG: bleak.backends.corebluetooth.client: Retrieving characteristics for service 180A
2024-04-27 13:31:32,570: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverCharacteristicsForService_error_
2024-04-27 13:31:32,570: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Characteristics discovered
2024-04-27 13:31:32,571: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 2A26
2024-04-27 13:31:32,571: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:32,571: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 10
2024-04-27 13:31:32,572: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 2A28
2024-04-27 13:31:32,572: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:32,573: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 12
2024-04-27 13:31:32,573: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 2A50
2024-04-27 13:31:32,573: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:32,573: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 14
2024-04-27 13:31:32,574: DEBUG: bleak.backends.corebluetooth.client: Retrieving characteristics for service C5F50001-8280-46DA-89F4-6D8051E4AEEF
2024-04-27 13:31:32,811: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverCharacteristicsForService_error_
2024-04-27 13:31:32,812: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Characteristics discovered
2024-04-27 13:31:32,812: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic C5F50002-8280-46DA-89F4-6D8051E4AEEF
2024-04-27 13:31:32,930: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:32,931: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 17
2024-04-27 13:31:32,932: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic C5F50003-8280-46DA-89F4-6D8051E4AEEF
2024-04-27 13:31:32,932: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:32,933: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 20
2024-04-27 13:31:32,933: DEBUG: bleak.backends.corebluetooth.client: Retrieving characteristics for service 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
2024-04-27 13:31:33,171: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverCharacteristicsForService_error_
2024-04-27 13:31:33,171: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Characteristics discovered
2024-04-27 13:31:33,172: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 6E400002-B5A3-F393-E0A9-E50E24DCCA9E
2024-04-27 13:31:33,172: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:33,173: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 23
2024-04-27 13:31:33,173: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E
2024-04-27 13:31:33,290: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 13:31:33,291: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 25
2024-04-27 13:31:33,291: DEBUG: bleak.backends.corebluetooth.client: Services resolved for BleakClientCoreBluetooth (166E8D19-D855-BB6F-9F52-C81E85EB1A39)
2024-04-27 13:31:33,291: INFO: pybricksdev.connections: Connected successfully!
2024-04-27 13:31:33,410: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 13:31:33,410: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Read characteristic value
2024-04-27 13:31:33,410: DEBUG: bleak.backends.corebluetooth.client: Read Characteristic 00002a28-0000-1000-8000-00805f9b34fb : bytearray(b'1.3.0')
2024-04-27 13:31:33,530: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 13:31:33,530: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Read characteristic value
2024-04-27 13:31:33,531: DEBUG: bleak.backends.corebluetooth.client: Read Characteristic 00002a50-0000-1000-8000-00805f9b34fb : bytearray(b'\x01\x97\x03\x80\x00\x00\x00')
2024-04-27 13:31:33,649: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateNotificationStateForCharacteristic_error_
2024-04-27 13:31:33,650: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Character Notify Update
2024-04-27 13:31:33,769: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateNotificationStateForCharacteristic_error_
2024-04-27 13:31:33,769: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Character Notify Update
2024-04-27 13:31:33,773: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 13:31:33,783: DEBUG: bleak.backends.corebluetooth.client: Write Characteristic 6e400002-b5a3-f393-e0a9-e50e24dcca9e : b'\xeb\x00\x00\x00'
2024-04-27 13:31:34,250: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 13:31:34,284: INFO: pybricksdev.connections: Disconnecting...
2024-04-27 13:31:34,285: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDisconnectPeripheral_error_
2024-04-27 13:31:34,285: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Peripheral Device disconnected!
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/locks.py", line 212, in wait
    await fut
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/thomasbrus/Code/lego-camera/.venv/bin/pybricksdev", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/thomasbrus/Code/lego-camera/.venv/lib/python3.12/site-packages/pybricksdev/cli/__init__.py", line 431, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 685, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/thomasbrus/Code/lego-camera/.venv/lib/python3.12/site-packages/pybricksdev/cli/__init__.py", line 202, in run
    await hub.run(script_path, args.wait)
  File "/Users/thomasbrus/Code/lego-camera/.venv/lib/python3.12/site-packages/pybricksdev/connections.py", line 367, in run
    await self.send_block(length)
  File "/Users/thomasbrus/Code/lego-camera/.venv/lib/python3.12/site-packages/pybricksdev/connections.py", line 340, in send_block
    await asyncio.wait_for(self.checksum_ready.wait(), timeout=0.5)
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 519, in wait_for
    async with timeouts.timeout(timeout):
  File "/usr/local/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

I cannot install pybricksdev

Windows 11
python 3.12.1

pip install pybricksdev
Collecting pybricksdev
Using cached pybricksdev-1.0.0a17-py3-none-any.whl (196 kB)
Collecting aioserial<2.0.0,>=1.3.0 (from pybricksdev)
Using cached aioserial-1.3.1.tar.gz (9.6 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting appdirs<2.0.0,>=1.4.4 (from pybricksdev)
Using cached appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB)
Collecting argcomplete<2.0.0,>=1.11.1 (from pybricksdev)
Using cached argcomplete-1.12.3-py2.py3-none-any.whl (38 kB)
Collecting asyncssh<3.0.0,>=2.2.1 (from pybricksdev)
Using cached asyncssh-2.14.2-py3-none-any.whl.metadata (9.9 kB)
Collecting bleak<0.13.0,>=0.12.1 (from pybricksdev)
Using cached bleak-0.12.1-py2.py3-none-any.whl (123 kB)
Collecting mpy-cross==1.14 (from pybricksdev)
Using cached mpy_cross-1.14-py2.py3-none-win_amd64.whl (158 kB)
Collecting prompt-toolkit<4.0.0,>=3.0.18 (from pybricksdev)
Using cached prompt_toolkit-3.0.43-py3-none-any.whl.metadata (6.5 kB)
Collecting pyusb<2.0.0,>=1.0.2 (from pybricksdev)
Using cached pyusb-1.2.1-py3-none-any.whl (58 kB)
Collecting semver<3.0.0,>=2.13.0 (from pybricksdev)
Using cached semver-2.13.0-py2.py3-none-any.whl (12 kB)
Collecting tqdm<5.0.0,>=4.46.1 (from pybricksdev)
Using cached tqdm-4.66.1-py3-none-any.whl.metadata (57 kB)
Collecting validators<0.19.0,>=0.18.2 (from pybricksdev)
Using cached validators-0.18.2-py3-none-any.whl (19 kB)
INFO: pip is looking at multiple versions of pybricksdev to determine which version is compatible with other requirements. This could take a while.
Collecting pybricksdev
Using cached pybricksdev-1.0.0a16-py3-none-any.whl (195 kB)
Using cached pybricksdev-1.0.0a15-py3-none-any.whl (197 kB)
Using cached pybricksdev-1.0.0a14-py3-none-any.whl (197 kB)
Using cached pybricksdev-1.0.0a13-py3-none-any.whl (196 kB)
Using cached pybricksdev-1.0.0a12-py3-none-any.whl (196 kB)
Using cached pybricksdev-1.0.0a11-py3-none-any.whl (195 kB)
Collecting bleak==0.12.0 (from pybricksdev)
Using cached bleak-0.12.0-py2.py3-none-any.whl (123 kB)
Collecting pybricksdev
Using cached pybricksdev-1.0.0a10-py3-none-any.whl (195 kB)
INFO: pip is still looking at multiple versions of pybricksdev to determine which version is compatible with other requirements. This could take a while.
ERROR: Cannot install pybricksdev==1.0.0a10, pybricksdev==1.0.0a11, pybricksdev==1.0.0a12, pybricksdev==1.0.0a13, pybricksdev==1.0.0a14, pybricksdev==1.0.0a15, pybricksdev==1.0.0a16 and pybricksdev==1.0.0a17 because these package versions have conflicting dependencies.

The conflict is caused by:
pybricksdev 1.0.0a17 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a16 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a15 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a14 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a13 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a12 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a11 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
pybricksdev 1.0.0a10 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"

To fix this you could try to:

  1. loosen the range of package versions you've specified
  2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

Timeout error connecting to hub

Summary

We are trying to switch from using the pybricks built-in IDE to VSCode. I am unable to connect and upload code to my Spike Prime hub with the following errors below.

Have confirmed

  • Completed firmware update from beta.pybricks.com
  • Named the hub pyswirle and can successfully connect and upload code in pybricks IDA
  • Attempting to connect and upload by name --name "pyswirle" or omitting the name results in similar timeout error
  • Hub is on (and works with pybricks IDE to upload code)

Environment

Mac OS: Sonoma14.4.1
Pybricks: 3.5
Pybricksdev: 1.0.0a17

Steps to reproduce

Without a named hub

(.venv) nina@Ninas-MacBook-Pro masterpiece-2023-2024 % pybricksdev --debug run ble master_missions.py
2024-04-27 15:52:46,008: DEBUG: asyncio: Using selector: KqueueSelector
Searching for any hub with Pybricks service...
2024-04-27 15:52:46,252: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManagerDidUpdateState_
2024-04-27 15:52:46,252: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Bluetooth powered on
2024-04-27 15:52:46,253: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: 'isScanning' changed
2024-04-27 15:52:46,286: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:52:46,286: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:52:46,289: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 50D0BE37-3CEC-418F-3E78-6BFC97462916: Hatch Rest @ RSSI: -102 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7f93551cf6f0>
2024-04-27 15:52:46,290: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device C3E4509F-ACB0-E00A-0810-89E17F099DAD: None @ RSSI: -89 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataTimestamp', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7f93551cf6f0>
2024-04-27 15:52:46,307: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:52:46,307: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:52:46,308: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF: pyswirle @ RSSI: -44 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataServiceUUIDs', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataIsConnectable'])>) and Central: <CBCentralManager: 0x7f93551cf6f0>
2024-04-27 15:52:46,309: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF: pyswirle @ RSSI: -44 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7f93551cf6f0>
2024-04-27 15:52:46,309: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: 'isScanning' changed
2024-04-27 15:52:46,309: INFO: pybricksdev.connections: Connecting to 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF
2024-04-27 15:52:46,309: DEBUG: bleak.backends.corebluetooth.client: CentralManagerDelegate  at <CentralManagerDelegate: 0x7f93551b0320>
2024-04-27 15:52:46,309: DEBUG: bleak.backends.corebluetooth.client: Connecting to BLE device @ 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF
2024-04-27 15:52:46,443: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didConnectPeripheral_
2024-04-27 15:52:46,444: DEBUG: bleak.backends.corebluetooth.client: Retrieving services...
2024-04-27 15:52:46,608: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverServices_
2024-04-27 15:52:46,608: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Services discovered
2024-04-27 15:52:46,609: DEBUG: bleak.backends.corebluetooth.client: Retrieving characteristics for service 180A
2024-04-27 15:52:46,638: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverCharacteristicsForService_error_
2024-04-27 15:52:46,638: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Characteristics discovered
2024-04-27 15:52:46,638: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 2A26
2024-04-27 15:52:46,639: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,639: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 5
2024-04-27 15:52:46,640: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 2A28
2024-04-27 15:52:46,640: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,640: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 7
2024-04-27 15:52:46,641: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 2A50
2024-04-27 15:52:46,641: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,641: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 9
2024-04-27 15:52:46,642: DEBUG: bleak.backends.corebluetooth.client: Retrieving characteristics for service C5F50001-8280-46DA-89F4-6D8051E4AEEF
2024-04-27 15:52:46,668: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverCharacteristicsForService_error_
2024-04-27 15:52:46,669: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Characteristics discovered
2024-04-27 15:52:46,669: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic C5F50002-8280-46DA-89F4-6D8051E4AEEF
2024-04-27 15:52:46,698: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,698: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 12
2024-04-27 15:52:46,699: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic C5F50003-8280-46DA-89F4-6D8051E4AEEF
2024-04-27 15:52:46,700: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,700: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 15
2024-04-27 15:52:46,700: DEBUG: bleak.backends.corebluetooth.client: Retrieving characteristics for service 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
2024-04-27 15:52:46,728: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverCharacteristicsForService_error_
2024-04-27 15:52:46,728: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Characteristics discovered
2024-04-27 15:52:46,729: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 6E400002-B5A3-F393-E0A9-E50E24DCCA9E
2024-04-27 15:52:46,729: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,729: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 18
2024-04-27 15:52:46,730: DEBUG: bleak.backends.corebluetooth.client: Retrieving descriptors for characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E
2024-04-27 15:52:46,758: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didDiscoverDescriptorsForCharacteristic_error_
2024-04-27 15:52:46,758: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Descriptor discovered 20
2024-04-27 15:52:46,758: DEBUG: bleak.backends.corebluetooth.client: Services resolved for BleakClientCoreBluetooth (18D791B2-57C5-9CC5-3618-AF93AE4D0CFF)
2024-04-27 15:52:46,758: INFO: pybricksdev.connections: Connected successfully!
2024-04-27 15:52:46,787: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 15:52:46,788: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Read characteristic value
2024-04-27 15:52:46,788: DEBUG: bleak.backends.corebluetooth.client: Read Characteristic 00002a28-0000-1000-8000-00805f9b34fb : bytearray(b'1.3.0')
2024-04-27 15:52:46,817: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 15:52:46,818: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Read characteristic value
2024-04-27 15:52:46,818: DEBUG: bleak.backends.corebluetooth.client: Read Characteristic 00002a50-0000-1000-8000-00805f9b34fb : bytearray(b'\x01\x97\x03\x81\x00\x00\x00')
2024-04-27 15:52:46,848: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateNotificationStateForCharacteristic_error_
2024-04-27 15:52:46,848: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Character Notify Update
2024-04-27 15:52:46,879: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateNotificationStateForCharacteristic_error_
2024-04-27 15:52:46,879: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: Character Notify Update
2024-04-27 15:52:46,879: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 15:52:46,912: DEBUG: bleak.backends.corebluetooth.client: Write Characteristic 6e400002-b5a3-f393-e0a9-e50e24dcca9e : b'k\x0e\x00\x00'
2024-04-27 15:52:47,371: DEBUG: bleak.backends.corebluetooth.PeripheralDelegate: peripheral_didUpdateValueForCharacteristic_error_
2024-04-27 15:52:47,417: INFO: pybricksdev.connections: Disconnecting...
2024-04-27 15:52:47,418: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDisconnectPeripheral_error_
2024-04-27 15:52:47,418: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Peripheral Device disconnected!
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/locks.py", line 212, in wait
    await fut
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/bin/pybricksdev", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/cli/__init__.py", line 431, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/cli/__init__.py", line 202, in run
    await hub.run(script_path, args.wait)
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/connections.py", line 367, in run
    await self.send_block(length)
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/connections.py", line 340, in send_block
    await asyncio.wait_for(self.checksum_ready.wait(), timeout=0.5)
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 519, in wait_for
    async with timeouts.timeout(timeout):
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

With a named hub

(.venv) nina@Ninas-MacBook-Pro masterpiece-2023-2024 % pybricksdev --debug run ble --name "pyswirle" master_missions.py
2024-04-27 15:53:49,100: DEBUG: asyncio: Using selector: KqueueSelector
Searching for pyswirle...
2024-04-27 15:53:49,409: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManagerDidUpdateState_
2024-04-27 15:53:49,410: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Bluetooth powered on
2024-04-27 15:53:49,410: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: 'isScanning' changed
2024-04-27 15:53:49,442: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,445: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 01302B65-D00E-5C54-DF94-AA407CC1352C: None @ RSSI: -84 (kCBAdvData <nsdict_keys(['kCBAdvDataManufacturerData', 'kCBAdvDataTimestamp', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,460: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,461: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,463: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 89B51201-88DE-2CD1-06C4-43C998AFE012: None @ RSSI: -86 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,463: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,464: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,465: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 89B51201-88DE-2CD1-06C4-43C998AFE012: None @ RSSI: -86 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,465: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 973BBC82-EA01-04B5-BD3D-27242E51178B: None @ RSSI: -92 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,466: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 4215CCD5-7F5C-0E1A-D01E-B028C1423922: None @ RSSI: -90 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,470: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,471: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,471: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDiscoverPeripheral_advertisementData_RSSI_
2024-04-27 15:53:49,472: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF: pyswirle @ RSSI: -101 (kCBAdvData <nsdict_keys(['kCBAdvDataTimestamp', 'kCBAdvDataServiceData', 'kCBAdvDataRxPrimaryPHY', 'kCBAdvDataIsConnectable', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataLocalName', 'kCBAdvDataTxPowerLevel', 'kCBAdvDataServiceUUIDs'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,472: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 059BC33F-D780-72F4-2104-A8E240EA5700: None @ RSSI: -85 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,473: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Discovered device 059BC33F-D780-72F4-2104-A8E240EA5700: None @ RSSI: -85 (kCBAdvData <nsdict_keys(['kCBAdvDataIsConnectable', 'kCBAdvDataManufacturerData', 'kCBAdvDataRxSecondaryPHY', 'kCBAdvDataTimestamp', 'kCBAdvDataRxPrimaryPHY'])>) and Central: <CBCentralManager: 0x7fa70ba4f7f0>
2024-04-27 15:53:49,473: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: 'isScanning' changed
2024-04-27 15:53:49,473: INFO: pybricksdev.connections: Connecting to 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF
2024-04-27 15:53:49,473: DEBUG: bleak.backends.corebluetooth.client: CentralManagerDelegate  at <CentralManagerDelegate: 0x7fa70e2957c0>
2024-04-27 15:53:49,474: DEBUG: bleak.backends.corebluetooth.client: Connecting to BLE device @ 18D791B2-57C5-9CC5-3618-AF93AE4D0CFF
2024-04-27 15:53:59,475: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Connection timed out after 10.0 seconds.
2024-04-27 15:53:59,476: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: centralManager_didDisconnectPeripheral_error_
2024-04-27 15:53:59,477: DEBUG: bleak.backends.corebluetooth.CentralManagerDelegate: Peripheral Device disconnected!
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/bin/pybricksdev", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/cli/__init__.py", line 431, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/cli/__init__.py", line 199, in run
    await hub.connect(device_or_address)
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/pybricksdev/connections.py", line 294, in connect
    await self.client.connect(disconnected_callback=disconnected_handler)
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/bleak/backends/corebluetooth/client.py", line 118, in connect
    await manager.connect(self._peripheral, disconnect_callback, timeout=timeout)
  File "/Users/nina/Sites/masterpiece-2023-2024/.venv/lib/python3.12/site-packages/bleak/backends/corebluetooth/CentralManagerDelegate.py", line 157, in connect
    await asyncio.wait_for(future, timeout=timeout)
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 519, in wait_for
    async with timeouts.timeout(timeout):
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

Is jupyter really a depedency?

I don't see anywhere we are actually using it directly and it seems like a rather large dependency to force on people who may want to use the library or the command line tool but not use jupyter.

From zero to flashed, complete instructions for Ubuntu

@dlech , as someone may get stuck, here and there, I've prepared a bit more detailed walk-through for your convenience to flash a Control+ Hub with a freshly built firmware, the complete workflow in a single place.

Enjoy!

sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl

mkdir PyBricks (or your choice)
cd PyBricks
curl https://pyenv.run | bash

edit ~/.bashrc so that last lines are:

# pyenv & poetry paths you'll need later on
export PATH="/home/<user>/.pyenv/bin:/home/<user>/.poetry/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Then restart your terminal or, just issue:

exec "$SHELL"

Clone the code base to build the firmware you'll upload, if you don't have a firmware.zip:

git clone https://github.com/pybricks/pybricks-micropython
cd pybricks-micropython/
make
make cplushub

Clone pybricksdev as per instructions, install Python 3.8.2 and check it, then install poetry:

git clone https://github.com/pybricks/pybricksdev.git
cd pybricksdev
pyenv install 3.8.2
python -V 
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
poetry install

Skip this if you're fine with Bluetooth on Linux.
Check you have a working bluetooth dongle with the command lsusb , you should see a line similar to this:

Bus 001 Device 002: ID 0a5c:21e8 Broadcom Corp. BCM20702A0 Bluetooth 4.0

Power-on your LEGO hub, launch the command line tool bluetoothctl, then issue a scan on:

[NEW] Controller 00:02:72:3F:BC:F3 <yourpc> [default]
Agent registered

[bluetooth]# scan on
Discovery started
[CHG] Controller 00:02:72:3F:BC:F3 Discovering: yes
[NEW] Device 90:84:**:**:**:3E Pybricks Hub
[NEW] Device DB:A9:**:**:**:19 Mi Smart Band 4
[CHG] Device DB:A9:**:**:**:19 UUIDs: 0000fee0-0000-1000-8000-0080********

(it is always a good idea to have other BLE gears if avaialble in the area, just to double-check everything is fine)

To flash, first power off your hub.
Prepare the command below (and don't hit Enter) in your shell as you're supposed to have just two hand.
poetry run pybricksdev flash ../pybricks-micropython/bricks/cplushub/build/firmware.zip -d 15
Press and keep pressed the green button until it flashes multicolor (red green blue).
Mind the batteries, of course you checked there's plenty of charge in them.
Now run the command above with Enter.

It is safe to remove your finger from the green button once you see the progress bar moving after the update, now it is uploading the firmware (or when your finger becomes blue and cold, whichever comes first).

Creating firmware
Searching for LEGO Bootloader
Found: 90:84:**:**:**:3E
Connecting to 90:84:**:**:**:3E
Connected successfully!
Erasing flash and starting update
100%|███████████████████████████████████████████████████| 157k/157k [02:41<00:00, 971B/s]

You're done!

Make the `run` command wait for Hub to get ready

Introduction

When fine-tuning programs and running them via pybricksdev, I often run the program several times per minute.
However, what happens to me frequently is that

  1. the Hub is off (turns off itself after a certain inactivity period)
  2. the Hub is running the old program when I forget to stop it by pressing the Hub's button

In both cases, the execution fails and I have to either turn the Hub on or stop the program, and then re-run pybricksdev run command.

It would be much more user firiendly if pybricksdev would handle these scenarios:

  1. If the Hub is turned off while pybricksdev run is waiting for connection, the program should be loaded and executed once the Hub is turned on
  2. If the Hub runs a program while pybricksdev run is executed, pybricksdev should
    1. either wait a moment till the user stops the old running program and then load and run the new one
    2. or even better, stop the old program and run the new one

Environment

macOS 12
Python 3.10.1
pybricksdev v1.0.0-alpha.24
Inventor Hub

Replication steps

  1. Switch off the Hub
  2. Execute pybricksdev run ble program.py
  3. Switch on the Hub
  4. Actual behaviour: asyncio.exceptions.TimeoutError
  5. Expected behaviour: The program should be uploaded and executed

Stack trace


Traceback (most recent call last):
  File "/Users/pavel/.pyenv/versions/3.8.12/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Users/pavel/.pyenv/versions/3.8.12/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/pavel/Git/Other/pybricksdev/pybricksdev/__main__.py", line 9, in <module>
    main()
  File "/Users/pavel/Git/Other/pybricksdev/pybricksdev/cli/__init__.py", line 374, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "/Users/pavel/.pyenv/versions/3.8.12/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Users/pavel/.pyenv/versions/3.8.12/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/Users/pavel/Git/Other/pybricksdev/pybricksdev/cli/__init__.py", line 198, in run
    await hub.run(script_path, args.wait)
  File "/Users/pavel/Git/Other/pybricksdev/pybricksdev/connections.py", line 367, in run
    await self.send_block(length)
  File "/Users/pavel/Git/Other/pybricksdev/pybricksdev/connections.py", line 340, in send_block
    await asyncio.wait_for(self.checksum_ready.wait(), timeout=0.5)
  File "/Users/pavel/.pyenv/versions/3.8.12/lib/python3.8/asyncio/tasks.py", line 501, in wait_for
    raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError

Analysis (cli/__init__.py and connections.py)

  1. The device_or_address = await find_device(args.name) works with a default 10s timeout
  2. Increasing the await asyncio.wait_for(self.checksum_ready.wait(), timeout=0.5) timeout does not help
  3. The nus_handler isn't caled at all for some reason, once the Hub is turned on
  4. If I do sleep before a connection is made, everything works.
diff --git a/pybricksdev/connections.py b/pybricksdev/connections.py
index c56d1f4..520e8b3 100644
--- a/pybricksdev/connections.py
+++ b/pybricksdev/connections.py
@@ -291,6 +291,7 @@ class PybricksHub:
             logger.info("Disconnected!")
             self.connected = False
 
+        await asyncio.sleep(5)
         await self.client.connect(disconnected_callback=disconnected_handler)
         try:
             logger.info("Connected successfully!")

I've tried to fix the problem myself but failed. Would you guide me on how could I achieve the behaviour described in the Introduction section? Happy to code the stuff myself if that's possible.

DFU restore is broken

The device is currently specified like this:

                f"{SPIKE_PRIME_DEVICE},{MINDSTORMS_INVENTOR_DEVICE}",

which does not seem to work on Ubuntu.

It does work when simply doing:

SPIKE_PRIME_DEVICE

Testers wanted for new dual-boot script

We are considering a few ways to improve the Pybricks installer for SPIKE Prime and MINDSTORMS Robot Inventor. Ultimately, we'd like to provide something in Pybricks Code. One promising solution seems to be web serial, which lets us talk to the hub via the USB cable.

Before we add it to the app, we're doing some tests in pybricksdev. This helps us test at least the hub side of things, before we implement it in the web app.

If you have previously installed pybricksdev, it would be great if you want to help us test this. Perhaps @BertLindeman, @JorgePe, @johnscary-ev3, @HeyLlama would be interested if you have some time to spare.

Instructions

  • Make sure you have the latest pybricksdev.
  • Boot the hub into the regular firmware and plug in USB.
  • Download the latest firmware build, e.g. this link and save it somewhere.
  • Run this, and replace the download path with yours:
poetry run pybricksdev dual-boot path/to/the/downloaded/primehub-firmware.zip

There should be some output in the terminal. And all 25 pixels will turn on one by one. When done, it should reboot and install the firmware. Now it should work the same as before, so a long press will give you Pybricks.

LWP3 repl initial traceback

Hi!

When I open pybricksdev lwp3 repl, after connecting to a device, it gets a huge traceback (see below).
Then it seems to work fine...
Below:

  • traceback
  • installed packages (pip list)

Environment: Windows 11, Python 3.12.3, pybricksdev 1.0.0a49.

Traceback:

pybricksdev lwp3 repl
[08:43:35.871] INFO: scanning...
[08:43:42.653] INFO: found device
[08:43:44.894] INFO: connected
--- Logging error ---
Traceback (most recent call last):
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 1160, in emit
    msg = self.format(record)
          ^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 999, in format
    return fmt.format(record)
           ^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 703, in format
    record.message = record.getMessage()
                     ^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 392, in getMessage
    msg = msg % self.args
          ~~~~^~~~~~~~~~~
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\ble\lwp3\messages.py", line 537, in __repr__
    return f"{self.__class__.__name__}({repr(self.port)}, {repr(self.device)}, {repr(self.hw_ver)}, {repr(self.fw_ver)})"
                                             ^^^^^^^^^
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\ble\lwp3\messages.py", line 494, in port
    return PortID(self._data[3])
           ^^^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\enum.py", line 761, in __call__
    raise TypeError(
TypeError: <enum 'PortID'> has no members; specify `names=()` if you meant to create a new, empty, enum
Call stack:
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "D:\Program Files\Python312\Scripts\pybricksdev.exe\__main__.py", line 7, in <module>
    sys.exit(main())
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\cli\__init__.py", line 389, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "D:\Program Files\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
  File "D:\Program Files\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 674, in run_until_complete
    self.run_forever()
  File "D:\Program Files\Python312\Lib\asyncio\windows_events.py", line 322, in run_forever
    super().run_forever()
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 641, in run_forever
    self._run_once()
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 1987, in _run_once
    handle._run()
  File "D:\Program Files\Python312\Lib\asyncio\events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\cli\lwp3\repl.py", line 159, in handle_notify
    logger.info("received: %s", msg)
Unable to print the message and arguments - possible formatting error.
Use the traceback above to help find the error.
--- Logging error ---
Traceback (most recent call last):
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 1160, in emit
    msg = self.format(record)
          ^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 999, in format
    return fmt.format(record)
           ^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 703, in format
    record.message = record.getMessage()
                     ^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 392, in getMessage
    msg = msg % self.args
          ~~~~^~~~~~~~~~~
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\ble\lwp3\messages.py", line 537, in __repr__
    return f"{self.__class__.__name__}({repr(self.port)}, {repr(self.device)}, {repr(self.hw_ver)}, {repr(self.fw_ver)})"
                                             ^^^^^^^^^
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\ble\lwp3\messages.py", line 494, in port
    return PortID(self._data[3])
           ^^^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\enum.py", line 761, in __call__
    raise TypeError(
TypeError: <enum 'PortID'> has no members; specify `names=()` if you meant to create a new, empty, enum
Call stack:
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "D:\Program Files\Python312\Scripts\pybricksdev.exe\__main__.py", line 7, in <module>
    sys.exit(main())
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\cli\__init__.py", line 389, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "D:\Program Files\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
  File "D:\Program Files\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 674, in run_until_complete
    self.run_forever()
  File "D:\Program Files\Python312\Lib\asyncio\windows_events.py", line 322, in run_forever
    super().run_forever()
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 641, in run_forever
    self._run_once()
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 1987, in _run_once
    handle._run()
  File "D:\Program Files\Python312\Lib\asyncio\events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\cli\lwp3\repl.py", line 159, in handle_notify
    logger.info("received: %s", msg)
Unable to print the message and arguments - possible formatting error.
Use the traceback above to help find the error.
--- Logging error ---
Traceback (most recent call last):
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 1160, in emit
    msg = self.format(record)
          ^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 999, in format
    return fmt.format(record)
           ^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 703, in format
    record.message = record.getMessage()
                     ^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\logging\__init__.py", line 392, in getMessage
    msg = msg % self.args
          ~~~~^~~~~~~~~~~
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\ble\lwp3\messages.py", line 537, in __repr__
    return f"{self.__class__.__name__}({repr(self.port)}, {repr(self.device)}, {repr(self.hw_ver)}, {repr(self.fw_ver)})"
                                             ^^^^^^^^^
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\ble\lwp3\messages.py", line 494, in port
    return PortID(self._data[3])
           ^^^^^^^^^^^^^^^^^^^^^
  File "D:\Program Files\Python312\Lib\enum.py", line 761, in __call__
    raise TypeError(
TypeError: <enum 'PortID'> has no members; specify `names=()` if you meant to create a new, empty, enum
Call stack:
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "D:\Program Files\Python312\Scripts\pybricksdev.exe\__main__.py", line 7, in <module>
    sys.exit(main())
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\cli\__init__.py", line 389, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File "D:\Program Files\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
  File "D:\Program Files\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 674, in run_until_complete
    self.run_forever()
  File "D:\Program Files\Python312\Lib\asyncio\windows_events.py", line 322, in run_forever
    super().run_forever()
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 641, in run_forever
    self._run_once()
  File "D:\Program Files\Python312\Lib\asyncio\base_events.py", line 1987, in _run_once
    handle._run()
  File "D:\Program Files\Python312\Lib\asyncio\events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "D:\Program Files\Python312\Lib\site-packages\pybricksdev\cli\lwp3\repl.py", line 159, in handle_notify
    logger.info("received: %s", msg)
Unable to print the message and arguments - possible formatting error.
Use the traceback above to help find the error.
Type message and press ENTER to send. Press CTRL+D to exit.
>>> HubPropertyRequestUpdate(HubProperty.NAME)

[08:43:50.543] INFO: sending: HubPropertyRequestUpdate(<HubProperty.NAME: 1>)
[08:43:50.685] INFO: received: HubPropertyUpdate(<HubProperty.NAME: 1>, 'abc')
>>>

Installed packages

pip list
Package                                                 Version
------------------------------------------------------- --------
aioserial                                               1.3.1
appdirs                                                 1.4.4
argcomplete                                             1.12.3
asyncssh                                                2.14.2
bleak                                                   0.22.2
cffi                                                    1.16.0
colorama                                                0.4.6
cryptography                                            42.0.8
distlib                                                 0.3.8
filelock                                                3.14.0
hidapi                                                  0.14.0
mpy-cross-v5                                            1.0.2
mpy-cross-v6                                            1.0.2
packaging                                               22.0
pip                                                     24.0
platformdirs                                            4.2.1
prompt_toolkit                                          3.0.47
pybricksdev                                             1.0.0a49
pycparser                                               2.22
pyserial                                                3.5
pyusb                                                   1.2.1
reactivex                                               4.0.4
semver                                                  2.13.0
setuptools                                              70.1.1
tqdm                                                    4.66.4
typing_extensions                                       4.12.2
virtualenv                                              20.26.1
wcwidth                                                 0.2.13
winrt-runtime                                           2.1.0
winrt-Windows.Devices.Bluetooth                         2.1.0
winrt-Windows.Devices.Bluetooth.Advertisement           2.1.0
winrt-Windows.Devices.Bluetooth.GenericAttributeProfile 2.1.0
winrt-Windows.Devices.Enumeration                       2.1.0
winrt-Windows.Foundation                                2.1.0
winrt-Windows.Foundation.Collections                    2.1.0
winrt-Windows.Storage.Streams                           2.1.0

Reading the stdout info from hub instead of printing it?

Hi guys,
I am using prybricksdev to communicate with my Inventor Hub. This is working fine.
However, the stdout from the hub just gets printed to my terminal, but I would like to process it now in my PC side program.
Documentation shows some options in the hub.run method but is not too clear on how I should read this data into my program.
I guess I should set print_output rag to False but what are calls to get this data? Looks like line_handler arg True will give me one line at a time which is great but then how do I get the lines of data into a variable in my program?
Do you have some docs on this or a simple example?

Thanks.

def run(
    py_path: str | None = None,
    wait: bool = True,
    print_output: bool = True,
    line_handler: bool = True
) -> Coroutine[Any, Any, None]:
"""
Compiles and runs a user program.

Args:
    py_path: The path to the .py file to compile. If None, runs a
        previously downloaded program.
    wait: If true, wait for the user program to stop before returning.
    print_output: If true, echo stdout of the hub to sys.stdout.
    line_handler: If true enable hub stdout line handler features.
"""

Data logging does not work

A program such as one of the following used to produce local text files on the host, but this no longer works in the new protocol.

# Output between the begin/end commands will be saved to "control.txt".
print("_file_begin_", "control.txt")
print("57,56,2,0,2,32000,4,84,4,88,50000,0,-18000,1073898496")
print("62,61,2,0,2,54500,4,91,4,90,50000,0,4500,65")
print("67,66,2,0,2,48000,5,100,5,106,75000,0,-27000,65")
print("72,71,2,0,2,48000,5,100,5,106,75000,0,-27000,65")
print("_file_end_")
from pybricks.pupdevices import Motor
from pybricks.tools import wait
from pybricks.parameters import Port
from pybricks import version

print(version)

# Initialize the motor.
motor = Motor(Port.A)

# Allocate the data logs.
DURATION = 4000
motor.log.start(DURATION)
motor.control.log.start(DURATION)

# Run the motor.
motor.run_target(500, 360)

# Wait so we can also log the stopped behavior.
wait(500)
motor.stop()

# Transfer data logs.
print("Transferring data...")
motor.log.save("servo.txt")
motor.control.log.save("control.txt")
print("Done")

Bluetooth does not work on macOS 12

Apple broke Bluetooth on macOS 12, so it is currently not possible to make Bluetooth connections with pybricksdev on macOS 12. If you are running macOS 12, please file an issue with Apple using the Feedback Assistant. See hbldh/bleak#635 for more details.

download and run to move hub fails on windows (and probably mac too)

The move hub has MTU of 23, so we can only send 20 bytes at a time. However we are sending 100 bytes at a time.

This probably works on Linux since BlueZ will be smart and divide it up but other OSes don't do this.

To fix this, we need to be able to read the hub type and or MTU of the active bluetooth connection. The former is blocked by https://github.com/pybricks/pybricks-micropython/issues/49 and the latter was just merged into Bleak (with the caveat that it always returns 23 on Linux). The latter would actually be best since the OS could negotiate a smaller MTU than the one requested by the device (although this is not known to happen on any known OS).

Unable to Install macOS with M1 CPU

macOS 11.4. python 3.9.6

I installed pipx through brew and then ran pipx ensurepath.

Then I tried to install pybricksdev:

PIPX_DEFAULT_PYTHON=python3.8 pipx install pybricksdev

pipx.util.PipxError: Default python interpreter 'python3.8' is invalid.

So I tried 3.9 because that's the version I have installed:

PIPX_DEFAULT_PYTHON=python3.9 pipx install pybricksdev

Fatal error from pip prevented installation. Full pip output in file:
    /Users/jakeedmonds/.local/pipx/logs/cmd_2021-07-22_06.23.56_pip_errors.log

pip seemed to fail to build package:
    pybricksdev

Some possibly relevant errors from pip install:
    ERROR: Cannot install pybricksdev==1.0.0a10 and pybricksdev==1.0.0a11 because these package versions have conflicting dependencies.
    ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies

Error installing pybricksdev.

Then I tried:

pipx install pybricksdev and I get the same error as PIPX_DEFAULT_PYTHON=python3.8 pipx install pybricksdev

Error in installing pybricksdev in editable dev mode

Installing pybricksdev using the editable development mode (python3 -m pip install -e . --user) returns the following problem:

Installing collected packages: pybricksdev
  Running setup.py develop for pybricksdev
    error: subprocess-exited-with-error
    
    × python setup.py develop did not run successfully.
    │ exit code: 1
    ╰─> [14 lines of output]
        error: Multiple top-level packages discovered in a flat-layout: ['demo', 'pybricksdev'].
        
        To avoid accidental inclusion of unwanted files or directories,
        setuptools will not proceed with this build.
        
        If you are trying to create a single distribution with multiple packages
        on purpose, you should not rely on automatic discovery.
        Instead, consider the following options:
        
        1. set up custom discovery (`find` directive with `include` or `exclude`)
        2. use a `src-layout`
        3. explicitly set `py_modules` or `packages` with a list of names
        
        To find more information, look for "package discovery" on setuptools docs.
        [end of output]
    
    note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× python setup.py develop did not run successfully.
│ exit code: 1
╰─> [14 lines of output]
    error: Multiple top-level packages discovered in a flat-layout: ['demo', 'pybricksdev'].
    
    To avoid accidental inclusion of unwanted files or directories,
    setuptools will not proceed with this build.
    
    If you are trying to create a single distribution with multiple packages
    on purpose, you should not rely on automatic discovery.
    Instead, consider the following options:
    
    1. set up custom discovery (`find` directive with `include` or `exclude`)
    2. use a `src-layout`
    3. explicitly set `py_modules` or `packages` with a list of names
    
    To find more information, look for "package discovery" on setuptools docs.
    [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.

Run command disconnects from HUB

Having a simple application for learning PID control on an InventorHub's motor. Once I execute it, it prints out about 200 times and then stops. The program keeps on running on the hub, but the output is not printed into the terminal anymore.

About a 1 attempt out of 10 works well and the connection is not interrupted. Most of the time, however, it does not work.

Environment

  • InventorHub
  • macOS 12
  • pybricksdev v1.0.0a23
  • latest FW (pybricks-micropython,1cba7db3485c336902ed4ab98f80f65cfea50ff0 commit)

Replication steps

  1. Execute the code below by running pybricksdev run ble derivative_control.py. The code increments a counter every time the while loop is at its end.
  2. Actual result: About 200 lines are printed only, while the code execution goes on and the motor is turning.
  3. Expected result: The connection with the Hub shall not be terminated.

The code

from math import trunc

from pybricks.parameters import Port
from pybricks.pupdevices import Motor

motor = Motor(Port.A)

# the ranges observed on a real Inventor motor
duty_cycle_range = range(0, 100)
speed_range = range(0, 1080)

dc_coef = duty_cycle_range.stop / speed_range.stop
def angle_to_dc(angle_speed_deg: int) -> int:
    # bound the speed to the allowed range
    speed = min(speed_range.stop, max(angle_speed_deg, speed_range.start))

    # recalculate the speed to the duty cycle (linear to speed)
    duty = trunc((speed - speed_range.start) * dc_coef + duty_cycle_range.start)

    # bound the duty cycle to the allowed range
    return min(duty_cycle_range.stop, max(duty, duty_cycle_range.start))

# proportional coefficient
kp = 0.5

# the desired target angle speed
set_point = 360
counter = 0

print("Counter, Speed, Duty cycle")
while True:
    speed = motor.speed()

    # the difference between set point and the actual motor speed
    error = set_point - speed

    # the proportional function
    fp = trunc(error * kp)

    command = set_point + fp
    duty_cycle = angle_to_dc(command)
    motor.dc(duty_cycle)

    print(counter, ",", speed, ",", duty_cycle)

    counter += 1

install with pipx

pipx is a nice way to install Python command line tools. It should be considerably simpler for those that just want to use pybricksdev from the command line.

Keeping notes here until we have a reasonable understanding of how it works, then we can update README, etc.

Install

Ubuntu

sudo apt install pipx
pipx install --spec=git+https://github.com/pybricks/pybricksdev@master pybricksdev

Bash Completion

sudo apt install python3-argcomplete
activate-global-python-argcomplete3 --user

~/.bash_completion (if it doesn't already exist)

# https://serverfault.com/a/831184/301470
for bcfile in ~/.bash_completion.d/* ; do
    [ -f "$bcfile" ] && . $bcfile
done

If global activation is not desirable:

source <(register-python-argcomplete pybricksdev)

Device Permissions

/etc/udev/rules.d/99-lego.rules:

# NXT brick 
SUBSYSTEM=="usb", ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0002", SYMLINK+="legonxt-%k", MODE="0666"

# NXT brick in firmware update mode (Atmel SAM-BA mode)
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="6124", SYMLINK+="legonxt-%k", MODE="0666"

# EV3 brick 
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0005", SYMLINK+="legoev3-%k", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0005", MODE="0666"

# EV3 brick in firmware update mode
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0006", SYMLINK+="legoev3-%k", MODE="0666"

# SPIKE Prime brick in firmware update mode
SUBSYSTEM=="usb", ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0008", SYMLINK+="legoprime-%k", MODE="0666"

macOS

brew install pipx

v1.0.0a29 run command not working

Hi guys,

I am using an Intel Macbook and I installed v1.0.0a29. If I am trying to execute the "run" command pybricksdev connects to the robot and uploads the file but it does not execute.

I get the error message "ValueError: incompatible .mpy file"

However, downgrading to v1.0.0a28 fixes the issue.

Maybe, there is a bug in the newest revision.

Add support for Python v3.11

When I try to in install pybricksdev with:

pipx install pybricksdev

I get this:

Fatal error from pip prevented installation. Full pip output in file:
    C:\Users\fabio\.local\pipx\logs\cmd_2022-12-09_17.54.06_pip_errors.log

pip seemed to fail to build package:
    pybricksdev

Some possibly relevant errors from pip install:
    ERROR: Cannot install pybricksdev==1.0.0a10, pybricksdev==1.0.0a11, pybricksdev==1.0.0a12, pybricksdev==1.0.0a13, pybricksdev==1.0.0a14, pybricksdev==1.0.0a15, pybricksdev==1.0.0a16 and pybricksdev==1.0.0a17 because these package versions have conflicting dependencies.
    ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

Error installing pybricksdev.

more in deep the related error is:

ERROR: Cannot install pybricksdev==1.0.0a10, pybricksdev==1.0.0a11, pybricksdev==1.0.0a12, pybricksdev==1.0.0a13, pybricksdev==1.0.0a14, pybricksdev==1.0.0a15, pybricksdev==1.0.0a16 and pybricksdev==1.0.0a17 because these package versions have conflicting dependencies.

The conflict is caused by:
    pybricksdev 1.0.0a17 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a16 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a15 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a14 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a13 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a12 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a11 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"
    pybricksdev 1.0.0a10 depends on winrt<2.0.0 and >=1.0.21033; sys_platform == "win32"

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

My environment:
OS: Windows 10 Pro x64
Python: 3.11.1
pip: 22.3.1
pipx: 1.1.0

Mac compatibility

We use Bleak as a cross-platform BLE package, but we seem to be experiencing this:

hbldh/bleak#206

I don't have a Mac so I'm not able to debug at this time - thanks @JanderII for raising this one.

run command should pipe stdin to the hub

Currently the run command pipes stdout from the hub to stdout of pybricksdev, but we need the other way around to work as well so that we can, for example, send CTRL+C to interupt a program.

AccessDenied error when trying to flash firmware to Technic hub from Windows

I'm pretty sure this is a bug in the LEGO bootloader combined with the way the Windows Bluetooth stack works combined with the way Bleak works. So we might be able to work around this by fixing Bleak.

Running the command

pybricksdev flash .\bricks\technichub\build\firmware.zip -d5

gives

Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2288.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2288.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 87, in _run_code  
    exec(code, run_globals)
  File "C:\Users\david\Documents\GitHub\Pybricks\pybricks-micropython\.venv\Scripts\pybricksdev.exe\__main__.py", line 7, in <module>        
  File "c:\users\david\documents\github\pybricks\pybricks-micropython\.venv\lib\site-packages\pybricksdev\cli\__init__.py", line 326, in main    loop.run_until_complete(subparsers.choices[args.tool].tool.run(args))
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2288.0_x64__qbz5n2kfra8p0\lib\asyncio\base_events.py", line 616, in run_until_complete
    return future.result()
  File "c:\users\david\documents\github\pybricks\pybricks-micropython\.venv\lib\site-packages\pybricksdev\cli\__init__.py", line 198, in run 
    await updater.connect(device)
  File "c:\users\david\documents\github\pybricks\pybricks-micropython\.venv\lib\site-packages\pybricksdev\ble.py", line 139, in connect      
    await self.client.connect(disconnected_callback=self.disconnected_handler)
  File "c:\users\david\documents\github\pybricks\pybricks-micropython\.venv\lib\site-packages\bleak\backends\dotnet\client.py", line 243, in 
connect
    await self.get_services()
  File "c:\users\david\documents\github\pybricks\pybricks-micropython\.venv\lib\site-packages\bleak\backends\dotnet\client.py", line 464, in 
get_services
    raise BleakDotNetTaskError(
bleak.exc.BleakDotNetTaskError: Could not get GATT characteristics for Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService: AccessDenied

Windows Bluetooth capture.

bth_hci.zip

In the Bluetooth capture, we can see that the hub claims that it claims that it has a Service Changed characteristic with indications

Frame 44: 17 bytes on wire (136 bits), 17 bytes captured (136 bits)
Bluetooth
Bluetooth HCI H1 Rcvd ACL Data
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth Attribute Protocol
    Opcode: Read By Type Response (0x09)
    Length: 7
    Attribute Data, Handle: 0x0002, Characteristic Handle: 0x0003, UUID: Service Changed
        Handle: 0x0002 (GATT Characteristic Declaration)
        Characteristic Properties: 0x20, Indicate
        Characteristic Value Handle: 0x0003 (Service Changed)
        UUID: Service Changed (0x2a05)
    [UUID: GATT Characteristic Declaration (0x2803)]
    [Request in Frame: 42]

Windows tries to enable indications on this characteristic

Frame 51: 13 bytes on wire (104 bits), 13 bytes captured (104 bits)
Bluetooth
Bluetooth HCI H1 Sent ACL Data
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth Attribute Protocol
    Opcode: Write Request (0x12)
    Handle: 0x0004 (Service Changed: Client Characteristic Configuration)
    Characteristic Configuration Client: 0x0002, Indication
        0000 0000 0000 00.. = Reseved: 0x0000
        .... .... .... ..1. = Indication: True
        .... .... .... ...0 = Notification: False

But the hub replies with an error.

Frame 53: 13 bytes on wire (104 bits), 13 bytes captured (104 bits)
Bluetooth
Bluetooth HCI H1 Rcvd ACL Data
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth Attribute Protocol
    Opcode: Error Response (0x01)
    Request Opcode in Error: Write Request (0x12)
    Handle in Error: 0x0004 (Service Changed: Client Characteristic Configuration)
    Error Code: Write Not Permitted (0x03)

There are a few more characteristic enumeration packets sent back and forth after this, but I have a feeling that this error bubbles up in Bleak which causes the connect method to fail since the connect method also enumerates services (and I suppose characteristics)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.