pybricks / support

Pybricks support and general discussion
MIT License
108 stars 6 forks source link

[Question] Is there standard procedure to install pybricks firmware on Spike Essential (small) hub? #626

Closed estoykov closed 2 years ago

estoykov commented 2 years ago

Today I acquired this cute little piece of hardware and because its functionallity is very limitted via official Spike App I want to use it with pybricks. I see that it should be supported (https://github.com/pybricks/support/issues/439) and there is a firmware in the CI builds, but there is no word for it in https://github.com/pybricks/support/issues/591. When I connect the small hub via USB and click 'Connect' in the above install page, I get this: image

However, I'm not sure that I can proceed with installing.

Is there some official way to install the latest working (beta ofc) pybrics build?

Thanks and keep the good work!

laurensvalk commented 2 years ago

If you try, the installation will check the hub type and safely stop before actually doing any updates :)

So the temporary install page is only suited for Robot Inventor and SPIKE Prime at the moment. We could add SPIKE Essential Hub here also if there's demand for it, but we were thinking to just wait until we add the proper installer to our main Pybricks Code app.

You could still install it via Pybricksdev if you don't mind installing some Python packages.

estoykov commented 2 years ago

I already have pybricksdev installed: image and if everything is correct in the picture, i.e. pybricksdev and Python version, I could give it a try.

I still need some more info though:

Overall, I see (in the code) that there is a support for this hub and if you think that it will work (with a little help from you) I'm happy to test it ;)

laurensvalk commented 2 years ago

Thanks for taking the time to test this, we appreciate it. As you have guessed correctly, it is still a bit early for this hub since it's so new. But in terms of functionality it's really done to the same level as Prime Hub/ Inventor Hub because it is almost the same hardware.

but from which build you suggest to get the essential hub firmware artifact

I'd generally pick the latest succeeding master build.

Exact pybricksdev command will be nice too

Connect the hub via USB. The hub LED will turn white. Run:

pybricksdev flash path/to/essentialhub/firmware.zip

The hub turns off pretty quickly; if it turned off before you ran this you can just press the button again.

The Pybricksdev output should look very similar to what you might have seen for the Inventor Hub installer.

Recovery works the same as well.

Also, I don't see EssentialHub type or similar in both public API pages and in https://github.com/pybricks/pybricks-api I suppose that its functionality (except Display and LEFT/RIGHT buttons) should be the same as the PrimeHub. With only two ports of course.

This is all correct :+1: We will be adding the Essential Hub page eventually.

estoykov commented 2 years ago

Okay, I'll give it a try. One last question regarding recovering, though: In the Prime/Inventor hub install page, FW recovery process is described as running just a simple script from the beta code editor. However, there is a an additional page - https://dfu.pybricks.com (if something went wrong) which shows how to install some backed up original FW in DFU mode and update it later via the original Lego software. So, if there is possibility to do this with the small hub as well? I see that pybricksdev has an ability to save/restore firmware in DFU mode and I was able to put the hub in this mode (as the Windows reported) while holding the button and pluging in the USB (it flashes only in pink though). Sorry, for bothering you again, but I want to be prepared as much as I can ;)

Regarding documentation, I see in the pybricks-micropython code that the class name (as I supposed) is EssentialHub ;)

dlech commented 2 years ago

Yes, the pybricks dfu restore command that you found does the same as dfu.pybricks.com. The light won't change color until you actually run the command.

laurensvalk commented 2 years ago

So, if there is possibility to do this with the small hub as well? I see that pybricksdev has an ability to save/restore firmware in DFU mode and I was able to put the hub in this mode (as the Windows reported) while holding the button and pluging in the USB (it flashes only in pink though).

Yes, this aspect also works the same across these hub types.

We should probably add a downloadable backup file for the Essential Hub too, just in case people forget to make a backup.

When you install Pybricks via pybricksdev flash path/to/essentialhub/firmware.zip when the hub is in normal mode, it will store the backup on the hub itself.

All of this complexity (multiple ways to do the same thing) should be abstracted away eventually in Pybricks Code.

estoykov commented 2 years ago

I did it ;)

  1. Made a backup (after installing WinUSB for DFU mode as described in https://dfu.pybricks.com/extra.html) image
  2. Installed latest master build image
  3. And the success story: image

Thank you all, you're the best!

P.S. The only thing that I'm really missing is to work from VS Code. No offense - your web code editor is REALLY great, but its intellisense is somewhat limited.

laurensvalk commented 2 years ago

Somehow I missed your response. This is great, glad you got it working!

Meanwhile our dfu page has a backup file for the Essential hub too, just in case.

estoykov commented 2 years ago

Thank you for the update ;) Btw, I'm wondering is it safe to pre-flash the hub so I can change the name instead of the default one? Also, why the FW that I saved is much bigger than yours - mine is almost 1MB, yours is half of that? I saved it with via 'backup' command as shown in the screenshots above.

laurensvalk commented 2 years ago

The flash size is 1 MB, so your backup also includes all of the empty space after it. Both will work.

And yes, you can set the name by adding --name your_name to the pybricksdev flash command.

Kefs88 commented 2 years ago

Looking good! My hopes are up that the Essential hub will get an official introduction together with the RI and Spike Hub :) I know it's still new but having such a small unit to program will be so nice 🗡️

Keep up the good work! (This seems a bit to hard for me to get working for now)

TheVinhLuong102 commented 2 years ago

I have just tried flashing the Essential Hub firmware by pybricksdev flash essentialhub-firmware.zip but encountered KeyError: "There is no item named 'main.py' in the archive".

The firmware file was from the latest successful master build https://github.com/pybricks/pybricks-micropython/actions/runs/2457715521.

pybricksdev version is v1.0.0a25.

May I ask where I might have done it wrong?

Thank you David & Laurens!

laurensvalk commented 2 years ago

This is something we're currently actively working on, so you may be better off using the latest beta release for the moment (instead of the very latest master build). You can download it here: https://github.com/pybricks/pybricks-micropython/actions/runs/2436129709 Install it with pybricksdev v1.0.0a25.

If you are feeling adventurous, upgrade pybricksdev v1.0.0a26 and use the latest master firmware build, including today's fixes.

For everyone else: this means that a simplified installation in our app is coming ever so slightly closer :smile:

TheVinhLuong102 commented 2 years ago

Laurens, I've just tried the adventurous route (pybricksdev a26 and the latest master build), and encountered the following error: :)

 File ".../pybricksdev", line 8, in <module>
    sys.exit(main())
  File ".../site-packages/pybricksdev/cli/__init__.py", line 376, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File ".../site-packages/pybricksdev/cli/__init__.py", line 224, in run
    from .flash import flash_firmware
  File ".../site-packages/pybricksdev/cli/flash.py", line 41, in <module>
    from ..flash import BootloaderConnection, create_firmware
  File ".../site-packages/pybricksdev/flash.py", line 25, in <module>
    from .firmware import ExtendedFirmwareMetadata, AnyFirmwareMetadata
  File ".../site-packages/pybricksdev/firmware.py", line 17, in <module>
    "device-id": Literal[0x40] | Literal[0x41] | Literal[0x80] | Literal[0x81],
TypeError: unsupported operand type(s) for |: '_LiteralGenericAlias' and '_LiteralGenericAlias'

Does this require Python 3.10+? (I used Python 3.9)

dlech commented 2 years ago

We change change that line to allow older Python for a while longer.

dlech commented 2 years ago

You can apply this change locally and it will be fixed in the next release. https://github.com/pybricks/pybricksdev/commit/4060d1fc1561dacd879bb6e8c721e093a025572d

TheVinhLuong102 commented 2 years ago

David, I believe line 17 in that firmware.py module needs a change as well.

dlech commented 2 years ago

yes, I missed that, thanks

TheVinhLuong102 commented 2 years ago

David, we've passed that error now. :)

However the firmware installation did not succeed:

pybricksdev flash essentialhub-firmware.zip
Creating firmware...
Connecting to /dev/cu.usbmodem3189376A34391
Connected!
Hub is ready.
Uploading _firmware/install_pybricks.py (8241 bytes)
Uploading _firmware/firmware.metadata.json (434 bytes)
Uploading _firmware/firmware.bin (231936 bytes)
**Could not find hub in standard firmware mode. Trying DFU.
No working DFU found. Please install libusb or ensure dfu-util is in PATH.**
dlech commented 2 years ago

What operating system?

TheVinhLuong102 commented 2 years ago

Mine is macOS Big Sur v11.6.6

dlech commented 2 years ago

On macOS you need to brew install libusb or brew install dfu-util.

dlech commented 2 years ago

Or install them a different way if you don't use brew.

TheVinhLuong102 commented 2 years ago

I guessed so too, and have done those brew installs.

Now we're up against this next: :D

pybricksdev flash essentialhub-firmware.zip
Creating firmware...
Connecting to /dev/cu.usbmodem3189376A34391
Connected!
Hub is ready.
Uploading _firmware/install_pybricks.py (8241 bytes)
Uploading _firmware/firmware.metadata.json (434 bytes)
Uploading _firmware/firmware.bin (231936 bytes)
Installing firmware

Detected LEGO firmware:
    Version: v1.0.00.0071-191f3ad
    Size: 584.0 KB
The detected firmware is not compatible with this installer.
Pybricks will not be installed.
dlech commented 2 years ago

We haven't tested that firmware yet. You can edit install_pybricks.py inside of the firmware.zip file. That version will need to be added to this list:

KNOWN_SPIKE_ESSENTIAL_FW_VERSIONS = {
    "v1.0.00.0000-d94a557": "SPIKE App v2.0.0",
    "v1.0.00.0070-51a2ff4": "SPIKE App v2.0.4",
}
Kefs88 commented 2 years ago

Awesome to hear official support for the essential hub is close. :) Kudos for everyone allready getting it to work! :D

TheVinhLuong102 commented 2 years ago

David, there's a problem installing pybricksdev in the editable mode: https://github.com/pybricks/pybricksdev/issues/32. Could you take a look at that as well?

dlech commented 2 years ago

I already replied there.

TheVinhLuong102 commented 2 years ago

After manually adding "v1.0.00.0071-191f3ad" in install_pybricks.py and re-zipping, I'm now getting this next error:

pybricksdev flash essentialhub-firmware.zip             
Creating firmware...
Connecting to /dev/cu.usbmodem3189376A34391
Connected!
Hub is ready.
Uploading _firmware/install_pybricks.py (8289 bytes)
Uploading _firmware/firmware.metadata.json (434 bytes)
Uploading _firmware/firmware.bin (231936 bytes)
0 b">>> I\x08\x1b[K\r\n>>> '\x08\x1b[K\r\n>>> -\x08\x1b[K\r\n>>> [\r\n>>> \r\n>>> P*\x08\x08\r\n>>> " b' ' b'# File transfer complete\r\n'
Traceback (most recent call last):
  File ".../pybricksdev", line 8, in <module>
    sys.exit(main())
  File ".../site-packages/pybricksdev/cli/__init__.py", line 376, in main
    asyncio.run(subparsers.choices[args.tool].tool.run(args))
  File ".../asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File ".../asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File ".../site-packages/pybricksdev/cli/flash.py", line 312, in flash_firmware
    await hub.upload_file("_firmware/firmware.bin", firmware)
  File ".../site-packages/pybricksdev/connections/lego.py", line 270, in upload_file
    await self.exec_line("# File transfer complete")
  File ".../site-packages/pybricksdev/connections/lego.py", line 154, in exec_line
    raise ValueError("Failed to execute line: {0}.".format(line))
ValueError: Failed to execute line: # File transfer complete.
dlech commented 2 years ago

To ignore the problem and go a different direction, you could put the hub in DFU mode and flash it that way (turn off the hub and unplug USB, then press and hold the button until it flashes purple and plugin in the USB). Then run pybricksdev flash while the hub is in this state.

TheVinhLuong102 commented 2 years ago

David, yes, that now succeeds! :)

Lots of hoops to jump through, but the most important thing is it now works.

Really looking forward to the new installer utility through Pybricks Code. Thank you for the awesome work!

pybricksdev flash essentialhub-firmware.zip
Creating firmware...
Could not find hub in standard firmware mode. Trying DFU.
File: /var/folders/_r/pclm3n6x2b54y_1frhn2jh3c0000gn/T/tmpinjct2hc/firmware.dfu
    b'DfuSe' v1, image size: 232229, targets: 1
    b'Target' 0, alt setting: 0, name: "ST...", size: 231944, elements: 1
      0, address: 0x08008000, size: 231936
    usb: 0694:000c, device: 0x0000, dfu: 0x011a, b'UFD', 16, 0x5c5d2dbb
Erasing flash...
Writing new firmware...
0x08008000  231936 [=========================] 100% 
Done.
laurensvalk commented 2 years ago

Maybe I shouldn't have mentioned the adventurous approach :smile:

laurensvalk commented 2 years ago

For what it's worth, you were very close. "v1.0.00.0071-191f3ad" does work just fine. We can add it to the list of known firmwares. And in your previous attempt, the file upload did work. For some reason it just didn't work the last time you tried. This sounds very similar to the issue you had with the SPIKE Prime web installer previously.

Once the easy install is included in Pybricks Code, I think we should just drop this particular USB serial installer from pybricksdev and just use DFU only. That's one less thing to support/debug and no great loss.

dlech commented 2 years ago

The new standard is to use https://beta.pybricks.com. Support for this hub was added in v3.2.0b3 (Pybricks Beta v2.0.0-beta.4).