virantha / bricknil Goto Github PK
View Code? Open in Web Editor NEWControl LEGO Bluetooth Sensors and Motors with Python
Home Page: https://virantha.github.io/bricknil
License: Apache License 2.0
Control LEGO Bluetooth Sensors and Motors with Python
Home Page: https://virantha.github.io/bricknil
License: Apache License 2.0
Summary:
On Windows 10 with the latest Python 3.8.1, pip3 install bricknil
(following https://virantha.github.io/bricknil/readme.html#installation) fails when installing pythonnet
due to missing dependency wheel
.
pip3 install wheel
resolves that, but building fails due to ModuleNotFoundError: No module named 'pycparser'
. pip3 install pycparser
solves that, but building fails.
Digging deeper:
https://pypi.org/project/pythonnet/#files last wheel release from mid 2019, so Python 3.7 needed, e.g.
https://www.python.org/ftp/python/3.7.6/python-3.7.6.exe
>%localappdata%\Programs\Python\Python37-32\Scripts\pip3.7.exe install pythonnet
>%localappdata%\Programs\Python\Python37-32\Scripts\pip3.7.exe install bricknil
works.
Then, running https://virantha.github.io/bricknil/readme.html#using-the-duplo-train-and-playing-sounds as brick.py:
Traceback (most recent call last):
File "brick.py", line 70, in <module>
start(system)
File "%localappdata%\Programs\Python\Python37-32\lib\site-packages\bricknil\bricknil.py", line 207, in start
from .bleak_interface import Bleak
File "%localappdata%\Programs\Python\Python37-32\lib\site-packages\bricknil\bleak_interface.py", line 20, in <module>
import bleak
File "%localappdata%\Programs\Python\Python37-32\lib\site-packages\bleak\__init__.py", line 68, in <module>
from bleak.backends.dotnet.discovery import discover # noqa
File "%localappdata%\Programs\Python\Python37-32\lib\site-packages\bleak\backends\dotnet\discovery.py", line 17, in <module>
from Windows.Devices.Bluetooth.Advertisement import BluetoothLEAdvertisementWatcher
ModuleNotFoundError: No module named 'Windows'
Google finds this issue and solution: hbldh/bleak#53 (comment)
i.e. %localappdata%\Programs\Python\Python37-32\Scripts\bleak-lescan
runs without error, albeit not giving any output.
The bricknil example does not find anything (Android nrF Connect has no issue connecting to the train) and "crashes":
Awaiting on bleak discover
Done Awaiting on bleak discover
INFO:BLE Event Q.0:Rescanning for 00001623-1212-efde-1623-785feabcd123 (1 tries left)
ERROR:curio.kernel:Task Crash: Task(id=6, name='BLEventQ.connect', state='TERMINATED')
Traceback (most recent call last):
...
curio.errors.TaskError: Task crash
which I cannot quit (CTRL+C or anything else).
So my Bluetooth 4.0 dongle (CSR) and Windows likely are the actual problem.
https://www.lego.com/en-us/service/device-guide/duplo-connected-train
Bluetooth low power technology (Bluetooth 4.1 or higher)
Although BLE is part of Bluetooth since 4.0!?
I'll try this on Linux.
Same error on Timeout in Ubuntu:
Issue with bluetooth adapter ("dongle")?
~$ lsusb
Bus 001 Device 007: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
user@desktop-ubuntu:~$ hcitool dev
Devices:
hci0 00:0x:xx:xx:xx:xx
user@desktop-ubuntu:~$ sudo hcitool lescan
Set scan parameters failed: Input/output error
user@desktop-ubuntu:~$ hciconfig
hci0: Type: Primary Bus: USB
BD Address: 00:xx:xx:xx:xx:xx ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING
RX bytes:2417 acl:0 sco:0 events:150 errors:0
TX bytes:2168 acl:0 sco:0 commands:121 errors:0
user@desktop-ubuntu:~$ hciconfig -a hci0
hci0: Type: Primary Bus: USB
BD Address: 00:xx:xx:xx:xx:xx ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING
RX bytes:2417 acl:0 sco:0 events:150 errors:0
TX bytes:2168 acl:0 sco:0 commands:121 errors:0
Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH HOLD SNIFF PARK
Link mode: SLAVE ACCEPT
Name: 'desktop-ubuntu'
Class: 0x1c0104
Service Classes: Rendering, Capturing, Object Transfer
Device Class: Computer, Desktop workstation
HCI Version: 2.0 (0x3) Revision: 0xc5c
LMP Version: 2.0 (0x3) Subversion: 0xc5c
Manufacturer: Cambridge Silicon Radio (10)
So it seems it's only a Bluetooth 2.0 Dongle and does not support BLE... Argh!
sudo apt update
pi@raspberrypi:~ $ hciconfig
hci0: Type: Primary Bus: UART
BD Address: xx:xx:xx:xx:xx:xx ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:1385 acl:0 sco:0 events:77 errors:0
TX bytes:2174 acl:0 sco:0 commands:77 errors:0
pi@raspberrypi:~ $ hciconfig -a hci0
hci0: Type: Primary Bus: UART
BD Address: xx:xx:xx:xx:xx:xx ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:1385 acl:0 sco:0 events:77 errors:0
TX bytes:2174 acl:0 sco:0 commands:77 errors:0
Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH SNIFF
Link mode: SLAVE ACCEPT
Name: 'raspberrypi'
Class: 0x000000
Service Classes: Unspecified
Device Class: Miscellaneous,
HCI Version: 4.1 (0x7) Revision: 0x168
LMP Version: 4.1 (0x7) Subversion: 0x2209
Manufacturer: Broadcom Corporation (15)
pi@raspberrypi:~ $ sudo hcitool lescan
LE Scan ...
xx:xx:xx:xx:xx:xx (unknown)
...
18:04:ED:EB:FB:BB Train Base
...
xx:xx:xx:xx:xx:xx (unknown)
^C
sudo apt install python3-pip
pip install bricknil
pi@raspberrypi:~ $ nano brick.py
(paste example code)
pi@raspberrypi:~ $ python3 brick.py
started thread for curio
inside curio run loop
INFO:BLE Event Q.0:using bleak
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
Traceback (most recent call last):
File "brick.py", line 70, in <module>
start(system)
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 65, in asyncio_loop
devices = await bleak.discover(timeout=1, loop=self.loop)
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 100, in discover
loop
txdbus.error.RemoteError: org.freedesktop.DBus.Error.AccessDenied: Rejected send message, 2 matched rules; type="method_call", sender=":1.13" (uid=1000 pid=1487 comm="python3 brick.py ") interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" error name="(unset)" requested_reply="0" destination="org.bluez" (uid=0 pid=359 comm="/usr/lib/bluetooth/bluetoothd ")
^CException ignored in: <module 'threading' from '/usr/lib/python3.7/threading.py'>
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 1281, in _shutdown
t.join()
File "/usr/lib/python3.7/threading.py", line 1032, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
KeyboardInterrupt
pi@raspberrypi:~ $ sudo python3 brick.py
Traceback (most recent call last):
File "brick.py", line 2, in <module>
from curio import sleep
ModuleNotFoundError: No module named 'curio'
pi@raspberrypi:~ $ ls /etc/dbus-1/system.d/
avahi-dbus.conf bluetooth.conf wpa_supplicant.conf
pi@raspberrypi:~ $ sudo nano /etc/dbus-1/system.d/bluetooth.conf
pi@raspberrypi:~ $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi
pi@raspberrypi:~ $ sudo adduser pi bluetooth
Adding user `pi' to group `bluetooth' ...
Adding user pi to group bluetooth
Done.
pi@raspberrypi:~ $ python3 brick.py
started thread for curio
inside curio run loop
INFO:BLE Event Q.0:using bleak
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
Traceback (most recent call last):
File "brick.py", line 70, in <module>
start(system)
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 65, in asyncio_loop
devices = await bleak.discover(timeout=1, loop=self.loop)
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 100, in discover
loop
txdbus.error.RemoteError: org.freedesktop.DBus.Error.AccessDenied: Rejected send message, 2 matched rules; type="method_call", sender=":1.13" (uid=1000 pid=557 comm="python3 brick.py ") interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" error name="(unset)" requested_reply="0" destination="org.bluez" (uid=0 pid=351 comm="/usr/lib/bluetooth/bluetoothd ")
Following
seems to fix the access problem, but there is another Exception:
pi@raspberrypi:~ $ busctl tree org.bluez
Failed to introspect object / of service org.bluez: Access denied
No objects discovered.
pi@raspberrypi:~ $ sudo busctl tree org.bluez
ââ/org
ââ/org/bluez
ââ/org/bluez/hci0
pi@raspberrypi:~ $ sudo adduser pi bluetooth
The user `pi' is already a member of `bluetooth'.
pi@raspberrypi:~ $ newgrp bluetooth
pi@raspberrypi:~ $ busctl tree org.bluez
Failed to introspect object / of service org.bluez: Access denied
No objects discovered.
pi@raspberrypi:~ $ systemctl status bluetooth
â bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-01-22 13:00:21 GMT; 12min ago
Docs: man:bluetoothd(8)
Main PID: 351 (bluetoothd)
Status: "Running"
Memory: 2.6M
CGroup: /system.slice/bluetooth.service
ââ351 /usr/lib/bluetooth/bluetoothd
Jan 22 13:00:21 raspberrypi systemd[1]: Starting Bluetooth service...
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Bluetooth daemon 5.50
Jan 22 13:00:21 raspberrypi systemd[1]: Started Bluetooth service.
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Starting SDP server
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Bluetooth management interface 1.14 initialized
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Sap driver initialization failed.
Jan 22 13:00:21 raspberrypi bluetoothd[351]: sap-server: Operation not permitted (1)
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Failed to set privacy: Rejected (0x0b)
pi@raspberrypi:~ $ sudo systemctl status bluetooth
â bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-01-22 13:00:21 GMT; 12min ago
Docs: man:bluetoothd(8)
Main PID: 351 (bluetoothd)
Status: "Running"
Memory: 2.6M
CGroup: /system.slice/bluetooth.service
ââ351 /usr/lib/bluetooth/bluetoothd
Jan 22 13:00:21 raspberrypi systemd[1]: Starting Bluetooth service...
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Bluetooth daemon 5.50
Jan 22 13:00:21 raspberrypi systemd[1]: Started Bluetooth service.
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Starting SDP server
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Bluetooth management interface 1.14 initialized
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Sap driver initialization failed.
Jan 22 13:00:21 raspberrypi bluetoothd[351]: sap-server: Operation not permitted (1)
Jan 22 13:00:21 raspberrypi bluetoothd[351]: Failed to set privacy: Rejected (0x0b)
pi@raspberrypi:~ $ sudo reboot
pi@raspberrypi:~ $ busctl tree org.bluez
ââ/org
ââ/org/bluez
ââ/org/bluez/hci0
pi@raspberrypi:~ $ python3 brick.py
started thread for curio
inside curio run loop
INFO:BLE Event Q.0:using bleak
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
Done Awaiting on bleak discover
INFO:BLE Event Q.0:Rescanning for 00001623-1212-efde-1623-785feabcd123 (60 tries left)
Awaiting on bleak discover
Done Awaiting on bleak discover
INFO:BLE Event Q.0:Rescanning for 00001623-1212-efde-1623-785feabcd123 (59 tries left)
Awaiting on bleak discover
Unhandled Error
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 140, in dataReceived
self.rawDBusMessageReceived(raw_msg)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 266, in rawDBusMessageReceived
self.signalReceived(m)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/client.py", line 642, in signalReceived
self.router.routeMessage(msig)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/router.py", line 128, in routeMessage
r.match(m)
--- <exception caught here> ---
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/router.py", line 67, in match
self.callback(m)
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 65, in parse_msg
device_interface = message.body[1].get("org.bluez.Device1", {})
builtins.AttributeError: 'list' object has no attribute 'get'
Unhandled Error
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 140, in dataReceived
self.rawDBusMessageReceived(raw_msg)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 266, in rawDBusMessageReceived
self.signalReceived(m)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/client.py", line 642, in signalReceived
self.router.routeMessage(msig)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/router.py", line 128, in routeMessage
r.match(m)
--- <exception caught here> ---
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/router.py", line 67, in match
self.callback(m)
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 65, in parse_msg
device_interface = message.body[1].get("org.bluez.Device1", {})
builtins.AttributeError: 'list' object has no attribute 'get'
Unhandled Error
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 140, in dataReceived
self.rawDBusMessageReceived(raw_msg)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 266, in rawDBusMessageReceived
self.signalReceived(m)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/client.py", line 642, in signalReceived
self.router.routeMessage(msig)
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/router.py", line 128, in routeMessage
r.match(m)
--- <exception caught here> ---
File "/home/pi/.local/lib/python3.7/site-packages/txdbus/router.py", line 67, in match
self.callback(m)
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 65, in parse_msg
device_interface = message.body[1].get("org.bluez.Device1", {})
builtins.AttributeError: 'list' object has no attribute 'get'
Traceback (most recent call last):
File "brick.py", line 70, in <module>
start(system)
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/pi/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 65, in asyncio_loop
devices = await bleak.discover(timeout=1, loop=self.loop)
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 167, in discover
returnSignature='a{sv}').asFuture(loop)
txdbus.error.RemoteError: org.freedesktop.DBus.Error.UnknownObject: Method "GetAll" with signature "s" on interface "org.freedesktop.DBus.Properties" doesn't exist
I just did a clean installation of Python 32bit and Bricknil under Windows 10 1903:
pip install bricknil
...
'Successfully installed bluebrick-Adafruit-BluefruitLE-0.9.13 bricknil-0.9.3 bricknil-bleak-0.3.1 curio-1.2 future-0.18.2 pythonnet-2.4.0 pyyaml-5.3.1'
and tried this sample:
from curio import sleep
from bricknil import attach, start
from bricknil.hub import PoweredUpHub
from bricknil.sensor import TrainMotor
@attach(TrainMotor, name='motor')
class Train(PoweredUpHub):
async def run(self):
for i in range(2): # Repeat this control two times
await self.motor.ramp_speed(80,5000) # Ramp speed to 80 over 5 seconds
await sleep(6)
await self.motor.ramp_speed(0,1000) # Brake to 0 over 1 second
await sleep(2)
async def system():
hub = Train("My train", ble_id="90:84:2B:03:xx:xx")
if __name__ == '__main__':
start(system)
and it didn't work:
Type "help", "copyright", "credits" or "license()" for more information.
>>>
============= RESTART: C:\Users\User\Desktop\Bricknil\bricktest.py ============
Traceback (most recent call last):
File "C:\Users\User\Desktop\Bricknil\bricktest.py", line 20, in <module>
start(system)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\bricknil\bricknil.py", line 207, in start
from .bleak_interface import Bleak
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\bricknil\bleak_interface.py", line 20, in <module>
import bleak
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\bleak\__init__.py", line 68, in <module>
from bleak.backends.dotnet.discovery import discover # noqa
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\bleak\backends\dotnet\discovery.py", line 17, in <module>
from Windows.Devices.Bluetooth.Advertisement import BluetoothLEAdvertisementWatcher
ModuleNotFoundError: No module named 'Windows'
>>>
```
For some reason, I randomly hit following error and no clue how it happens.
From error message, I guess it's because of some random events that old version of bleak can't handle properly. I made some minor changes to use the latest bleak and it works well. As my knowledge of entire code base is limited, I'm not sure if it works well for other part of the code. Attached is diff.
Traceback (most recent call last):
File "technic_4x4.py", line 38, in <module>
start(system)
File "/home/fxie/dev/venv/lego/lib/python3.6/site-packages/bricknil-0.9.3-py3.6.egg/bricknil/bricknil.py", line 214, in start
File "/home/fxie/dev/venv/lego/lib/python3.6/site-packages/bricknil-0.9.3-py3.6.egg/bricknil/bleak_interface.py", line 52, in run
File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
return future.result()
File "/home/fxie/dev/venv/lego/lib/python3.6/site-packages/bricknil-0.9.3-py3.6.egg/bricknil/bleak_interface.py", line 65, in asyncio_loop
File "/home/fxie/dev/venv/lego/lib/python3.6/site-packages/bricknil_bleak-0.3.1-py3.6.egg/bleak/backends/bluezdbus/discovery.py", line 167, in discover
returnSignature='a{sv}').asFuture(loop)
txdbus.error.RemoteError: org.freedesktop.DBus.Error.UnknownObject: Method "GetAll" with signature "s" on interface "org.freedesktop.DBus.Properties" doesn't exist
Diffs
diff --git a/bricknil/ble_queue.py b/bricknil/ble_queue.py
index b32179a..0e85d20 100644
--- a/bricknil/ble_queue.py
+++ b/bricknil/ble_queue.py
@@ -1,11 +1,11 @@
-# Copyright 2019 Virantha N. Ekanayake
-#
+# Copyright 2019 Virantha N. Ekanayake
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -117,9 +117,9 @@ class BLEventQ(Process):
def _check_devices_for(self, devices, name, manufacturer_id, address):
"""Check if any of the devices match what we're looking for
-
+
First, check to make sure the manufacturer_id matches. If the
- manufacturer_id is not present in the BLE advertised data from the
+ manufacturer_id is not present in the BLE advertised data from the
device, then fall back to the name (although this is unreliable because
the name on the device can be changed by the user through the LEGO apps).
@@ -168,11 +168,11 @@ class BLEventQ(Process):
devices = await self.ble.out_queue.get() # Wait for discovered devices
await self.ble.out_queue.task_done()
# Filter out no-matching uuid
- devices = [d for d in devices if str(uart_uuid) in d.uuids]
+ devices = [d for d in devices if str(uart_uuid) in d.metadata['uuids']]
# NOw, extract the manufacturer_id
for device in devices:
- assert len(device.manufacturer_data) == 1
- data = next(iter(device.manufacturer_data.values())) # Get the one and only key
+ assert len(device.metadata['manufacturer_data']) == 1
+ data = next(iter(device.metadata['manufacturer_data'].values())) # Get the one and only key
device.manufacturer_id = data[1]
else:
devices = self.ble.find_devices(service_uuids=[uart_uuid])
@@ -221,7 +221,7 @@ class BLEventQ(Process):
try:
ble_id = uuid.UUID(hub.ble_id) if hub.ble_id else None
except ValueError:
- # In case the user passed in a
+ # In case the user passed in a
self.message_info(f"ble_id {hub.ble_id} is not a parseable UUID, so assuming it's a BLE network addresss")
ble_id = hub.ble_id
@@ -234,7 +234,7 @@ class BLEventQ(Process):
device = await self.ble.out_queue.get()
await self.ble.out_queue.task_done()
hub.ble_id = self.device.address
- self.message_info(f'Device advertised: {device.characteristics}')
+ self.message_info(f'Device advertised: {device.services.characteristics}')
hub.tx = (device, hub.char_uuid) # Need to store device because the char is not an object in Bleak, unlike Bluefruit library
# Hack to fix device name on Windows
if self.device.name == "Unknown" and hasattr(device._requester, 'Name'):
diff --git a/setup.py b/setup.py
index 411f139..df31a47 100644
--- a/setup.py
+++ b/setup.py
@@ -80,7 +80,7 @@ setup (
include_package_data = True,
packages = packages,
install_requires = required + ['pyobjc ; sys.platform == "darwin"',
- 'bricknil-bleak ; sys.platform != "darwin"'],
+ 'bleak ; sys.platform != "darwin"'],
dependency_links = dependency_links,
entry_points = {
'console_scripts': [
Hi!
I have trouble connecting to the position motor (called large angular motor) in the 6x6 Volvo Technic set (42114). I have followed the example script and was able to connect to the normal large and extra large linear motors with no problems. My problem is connecting to the angular motor.
I tried using a bunch of motors and nothing worked.
Is there something I'm missing? Is it not supported? Has anyone faced this kind of issue before?
Would appreciate any guidance and discussion!
Hi there.
Try connect Lego Move Hub to bricknill using boost_motor_position.py (Windows 10, Python 3.7, Asus BT400 dongle, bleak 0.10.0, bricknil 0.9.3)
When I start programm, i have next stactrace:
My Move Hub must connect automatically, or i must connect via windows bluetooth settings, or some other way?
Thanks.
I'm not able to get a propper connection to my LEGO train hub. As I run the simple example code
from curio import sleep
from bricknil import attach, start
from bricknil.hub import PoweredUpHub
from bricknil.sensor import TrainMotor
from bricknil.process import Process
import logging
@attach(TrainMotor, name='motor')
class Train(PoweredUpHub):
async def run(self):
self.message_info("Running")
for i in range(2):
self.message_info('Increasing speed')
await self.motor.ramp_speed(80,5000)
await sleep(6)
self.message_info('Coming to a stop')
await self.motor.ramp_speed(0,1000)
await sleep(2)
async def system():
train = Train('My train')
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
start(system)
the LEGO device seems to be found and connected (continous LED) but the code stucks and nothing happens. Still if I stop with Strg+C the LEd is on. Please see the log:
started thread for curio
inside curio run loop
INFO:BLE Event Q.0:using bleak
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
Done Awaiting on bleak discover
INFO:BLE Event Q.0:Rescanning for 00001623-1212-efde-1623-785feabcd123 (60 tries left)
Awaiting on bleak discover
Done Awaiting on bleak discover
INFO:BLE Event Q.0:checking manufacturer ID for device named HUB NO.4 for HUB NO.4
INFO:BLE Event Q.0:found device HUB NO.4
This is the "freeze" state. I'm working on a Raspi 4B with the latest 2020-08-20-raspios-buster-armhf-full.img. At the beginnig I had some warnings with the service_identity module but I fixed and installed the missing modue,
:0: UserWarning: You do not have a working installation of the service_identity module: 'No module named 'service_identity''. Please install it from <https://pypi.python.org/pypi/service_identity> and make sure all of its dependencies are satisfied. Without the service_identity module, Twisted can perform only rudimentary TLS client hostname verification. Many valid certificate/hostname mappings may be rejected.
Does anybody knows a solution or could share her/his experiences with controling the PoweredUp trains with the Raspberry 4?
Best regards
Matthias
On my machine (Win10) the UUID is not actually showing, instead a MAC-like address is given. This has made it hard to select a specific device. From inside the main run() method in Train I have added
self.message_info("BLE_ID:"+self.ble_id)
which outputs
INFO:GreenCargoTrain.2:BLE_ID:90:84:2B:0B:DD:BF
I have tried setting the logging to DEBUG, and using all the UUID's that are in there, including the Device advertised UUID, but no luck. For example, without setting a specific UUID it finds the train:
INFO:BLE Event Q.0:checking manufacturer ID for device named Unknown for HUB NO.4
INFO:BLE Event Q.0:found device Unknown
INFO:BLE Event Q.0:Device advertised: {'00002a00-0000-1000-8000-00805f9b34fb': <Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic object at 0x071A27D0>, '00002a01-0000-1000-8000-00805f9b34fb': <Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic object at 0x071A2D50>, '00002a04-0000-1000-8000-00805f9b34fb': <Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic object at 0x071A2D70>, '00002a05-0000-1000-8000-00805f9b34fb': <Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic object at 0x071A2A70>, '00001624-1212-efde-1623-785feabcd123': <Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic object at 0x071A2870>}
INFO:BLE Event Q.0:Connected to device HUB NO.4:90:84:2B:0B:DD:BF
But when putting any of those UUID's in there (the first one in this example) I get:
hub = Train("GreenCargoTrain", ble_id="00002a05-0000-1000-8000-00805f9b34fb")
INFO:BLE Event Q.0:checking manufacturer ID for device named Unknown for HUB NO.4
INFO:BLE Event Q.0:Address 90:84:2B:0B:DD:BF is not a match
A debug log file of a successful connect and execution to the same device looks like this:
PUP_Debug_Success.log
This is on Microsoft Windows [Version 10.0.17763.379], using Python 3.7.3
Thanks for the great piece of work! I have one issue I don't seem able to solve.
Every time when I run a simple piece of code on my Mac communicating with one of my boost sensors it crashes, stating something about an unknown device being attached. This happens with all sensors. Any suggestions what is going wrong?
......
INFO:BLE Event Q.0:Connected to device LEGO Move Hub:c631f6ec-........
INFO:BLE Event Q.0:Waiting for hubs to end
INFO:Test.3:Running
INFO:Test.3:start
INFO:motor_left.2:Setting speed to 10
2020-06-17 21:11:49.597 python[1206:29044] *** Terminating app due to uncaught exception 'OC_PythonException', reason: '<class 'AssertionError'>: Unknown device with id 66 being attached (port 70'
.......
And the code I'm running.
`import logging
from curio import sleep
from bricknil import attach, start
from bricknil.hub import BoostHub
from bricknil.sensor import InternalMotor
@Attach(InternalMotor, name='motor_right', port=InternalMotor.Port.B)
@Attach(InternalMotor, name='motor_left', port=InternalMotor.Port.A)
class Robot(BoostHub):
async def run(self):
self.message_info("Running")
while (True):
self.message_info('start')
await self.motor_left.set_speed(10)
await self.motor_right.set_speed(10)
sleep(3)
self.message_info('stop')
await self.motor_left.set_speed(0)
await self.motor_right.set_speed(0)
async def system():
robot = Robot('Test')
if name == 'main':
logging.basicConfig(level=logging.INFO)
start(system)`
I'm running this on Linux. I can the below error only sometimes while running my program. It seems to immediately occur only once either the PoweredUpHub or PoweredUpRemote is visible to my computer's bluetooth, but other times it just fails immeidately. Most of the time, it works fine, but other times it doesn't.
$ uname -a
Linux lavender-hp 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
inside curio run loopstarted thread for curio
Awaiting on bleak discover
INFO:BLE Event Q.0:using bleak
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Unhandled Error
Traceback (most recent call last):
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/txdbus/protocol.py", line 140, in dataReceived
self.rawDBusMessageReceived(raw_msg)
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/txdbus/protocol.py", line 266, in rawDBusMessageReceived
self.signalReceived(m)
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/txdbus/client.py", line 642, in signalReceived
self.router.routeMessage(msig)
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/txdbus/router.py", line 128, in routeMessage
r.match(m)
--- <exception caught here> ---
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/txdbus/router.py", line 67, in match
self.callback(m)
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/bleak/backends/bluezdbus/discovery.py", line 65, in parse_msg
device_interface = message.body[1].get("org.bluez.Device1", {})
builtins.AttributeError: 'list' object has no attribute 'get'
Traceback (most recent call last):
File "/home/lavender/programming/Python/lego-train-manager/trainmanager/__init__.py", line 17, in <module>
start(system)
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/bricknil/bleak_interface.py", line 65, in asyncio_loop
devices = await bleak.discover(timeout=1, loop=self.loop)
File "/home/lavender/programming/Python/lego-train-manager/.venv/lib/python3.8/site-packages/bleak/backends/bluezdbus/discovery.py", line 161, in discover
properties = await bus.callRemote(
txdbus.error.RemoteError: org.freedesktop.DBus.Error.UnknownObject: Method "GetAll" with signature "s" on interface "org.freedesktop.DBus.Properties" doesn't exist
I tried running my lego passenger train using bricknil on my Windows 10 machine. I followed the following steps.
pip install bircknil
I ran a simple program to control the train and this is the error I got.
My program had the following lines
`from curio import sleep
from bricknil import attach, start
from bricknil.hub import PoweredUpHub
from bricknil.sensor import TrainMotor
from bricknil.process import Process
import logging
@Attach(TrainMotor, name='motor')
class Train(PoweredUpHub):
async def run(self):
self.message_info("Running")
for i in range(2):
self.message_info('Increasing speed')
await self.motor.ramp_speed(80,5000)
await sleep(15)
self.message_info('Coming to a stop')
await self.motor.ramp_speed(20,1000)
await sleep(2)
async def system():
train = Train('My train')
if name == 'main':
logging.basicConfig(level=logging.INFO)
start(system)
`
On running the program, I got the following error.
File "train.py", line 26, in
start(system)
File "C:\Users\axavier\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\bricknil\bricknil.py", line 214, in start
ble.run()
File "C:\Users\axavier\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\bricknil\bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1520.0_x64__qbz5n2kfra8p0\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File "C:\Users\axavier\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\bricknil\bleak_interface.py", line 71, in asyncio_loop
await device.connect()
File "C:\Users\axavier\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\bleak\backends\dotnet\client.py", line 86, in connect
raise BleakError(
bleak.exc.BleakError: Connection to 90:84:2B:15:88:DB was not successful!
Hi!
I think this is a super cool project and I am really happy to see you are working on the new Control Plus hub :-). I noticed a small bug in the sensor readings. If I attach a CPlusMotor using
@attach(CPlusLargeMotor, name='stearing', port=2, capabilities=['sense_pos'])
and then steer it towards negative positions, sense_pos
will return very large numbers. It seems negative numbers are encoded in the format max_value-abs(value), and the following (really dumb) fix to peripheral.py
seems to solve the issue:
async def update_value(self, msg_bytes):
msg = bytearray(msg_bytes)
if len(self.capabilities)==0:
self.value = msg
if len(self.capabilities)==1:
capability = self.capabilities[0]
datasets, bytes_per_dataset = self.datasets[capability][0:2]
for i in range(datasets):
msg_ptr = i*bytes_per_dataset
val = self._convert_bytes(msg[msg_ptr: msg_ptr+bytes_per_dataset], bytes_per_dataset)
# my fix
if msg_bytes[-1] == 255:
b2 = [255 - b for b in msg_bytes]
msg2 = bytearray(b2)
val2 = self._convert_bytes(msg2[msg_ptr: msg_ptr + bytes_per_dataset], bytes_per_dataset)
val = -val2
if datasets==1:
self.value[capability] = val
else:
self.value[capability][i] = val
if val > 10000:
raise Exception("bad position")
if len(self.capabilities) > 1:
await self._parse_combined_sensor_values(msg)
although the proper way is obviously to change _convert_bytes
.
On a related note, I have model 42099 (which I guess from the examples you also got?) and I wonder if you have some input on the following: I have written a small control program for the 42099 model which takes keyboard inputs and try to accelerate and turn the front wheels using .set_pos(...). I change the position in small increments (+/- 15 degrees) based on keyboard inputs. Sometimes, it seems the motor will not fully perform the command, and instead freeze and make a high-pitched whining sound for about 0.5-1 seconds (and in this mode subsequent commands are paused). I have tried to change the max_power
to 100 but this does not seem to fully solve the issue. I have also tried mucking around with the other input parameters to set_pos, including the speed, but to no avail (I confess I do not know what all of them really do).
This behavior is not one I have observed with the lego smartphone app, which seems to respond much more "crisply" to inputs. So my question is fairly high-level: If I wanted to write a control app to control the wheels, and avoid the above behavior (or more specifically, imitate the lego smartphone app), do you know if I should still use .set_pos and is there something obvious I am missing? I am attaching the code just in case it has any interest to anyone.
This is an RFC rather than a report of specific defect.
I'd like to discuss possible simplification of the code.
(i) As of now, the library uses special hacked version of BLEAK library (which I see as maintenance problem).
(ii) It looks that recent BLEAK supports also Windows and MacOS (or soon it will), therefore we can
remove support for other backends in bricknil and depend solely on BLEAK.
(iii) Once we do (i) we can remove dependency on curio and run everything in a single thread using asyncio (which is part of python3)
(iv) Once we do (iii), we can get rid of multiple "tasks" and message-passing through queue in bleak_interface.py
, removing the file altogether.
I prototyped changes for (i) and (iii) and not only it make things (little) simpler but also my 4x4 off-roader is much more responsive (using the original code the reactions are "slow" on my setup)
@virantha, what do you think? Shall it try to push these changes further?
I can't see any way to connect 2 train motors to a hub. There appears to be no way of controlling the A and B port individually. I have train engines that have 2 motors each and the motors point in opposite directions. This means that both motors would need to be controlled individually so that when motorA is set to 50 motorB could then be set to -50 and vise versa.
I have connected a Large motor to port A on a Technic Hub, to power a Lego Loop Coaster. I've been able to control it via Bricknil on my Macbook Pro, but I can't get it to work on a Raspberry Pi. Almost every time I run my program on the Raspberry Pi, I get the following error:
``
INFO:BLE Event Q.0:found device Technic Hub
DEBUG:bleak.backends.bluezdbus.client:Connecting to BLE device @ 90:84:2B:70:74:8C with hci0
DEBUG:bleak.backends.bluezdbus.discovery:Technic Hub, 90:84:2B:70:74:8C (-74 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_70_74_8C
Traceback (most recent call last):
File "/home/tyler/lego1/lib/python3.9/site-packages/bleak/backends/bluezdbus/client.py", line 69, in connect
await self._bus.callRemote(
txdbus.error.RemoteError: org.bluez.Error.Failed: Software caused connection abort
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/tyler/lego1/./bricknil_test.py", line 21, in
start(system)
File "/home/tyler/lego1/lib/python3.9/site-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/tyler/lego1/lib/python3.9/site-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/tyler/lego1/lib/python3.9/site-packages/bricknil/bleak_interface.py", line 71, in asyncio_loop
await device.connect()
File "/home/tyler/lego1/lib/python3.9/site-packages/bleak/backends/bluezdbus/client.py", line 78, in connect
raise BleakError(str(e))
bleak.exc.BleakError: org.bluez.Error.Failed: Software caused connection abort
``
It works every time on the Macbook Pro. It worked once out of maybe 50 attempts on the Raspberry Pi.
Does anyone have a combination of Raspberry Pi OS / Python / Bricknil / Bleak versions that is working well for them?
Steps to reproduce:
Successfully installed attrs-23.1.0 automat-22.10.0 bluebrick-Adafruit-BluefruitLE-0.9.13 bricknil-0.9.3 bricknil-bleak-0.3.1 constantly-15.1.0 curio-1.6 future-0.18.3 hyperlink-21.0.0 idna-3.4 incremental-22.10.0 pyyaml-6.0.1 six-1.16.0 twisted-23.8.0 txdbus-1.1.2 typing-extensions-4.7.1 zope-interface-6.0
Then run the following Python program, based on the technic 4x4 example:
``
#! /usr/bin/env python3
import logging
from curio import sleep
from bricknil import attach, start
from bricknil.hub import CPlusHub
from bricknil.sensor.motor import CPlusLargeMotor
@Attach(CPlusLargeMotor, name='loop_motor', port=0)
class Coaster(CPlusHub):
async def run(self):
self.message_info("Running")
await self.loop_motor.set_speed(50)
await sleep(20)
async def system():
hub = Coaster('loop_hub', True)
if name == 'main':
logging.basicConfig(level=logging.DEBUG)
start(system)
``
If I press the button on the hub immediately before running the Python program, or soon after, I can see that it discovers the hub OK, but fails when it tries to connect.
When connecting to the MoveHub on Raspi 4 it seems that upon first write the MoveHub disconnects (LED starts white blinking after solid blue). Any idea why this could be?
INFO:BLE Event Q.0:Connected to device Idas gitare:00:16:53:B4:DC:8F
INFO:robot.6:Waiting for peripheral motor_r to attach to a port
DEBUG:robot.6:starting peripheral message loop
DEBUG:robot.6:peripheral msg: hub_btn.1 attach
DEBUG:bricknil.sockets:{"hub": "robot", "peripheral_type": "Button", "peripheral_name": "hub_btn", "peripheral_port": 255, "message": "Activate button reports: port 255"}
DEBUG:BLE Event Q.0:Got msg: Activate button reports: port 255 = [0, 1, 2, 2]
DEBUG:BLE Event Q.0:Got msg: req mode info on 255 = [0, 33, 255, 1]
INFO:robot.6:Waiting for peripheral motor_r to attach to a port
DEBUG:bleak.backends.bluezdbus.discovery:dev_00_16_53_B4_DC_8F, 00:16:53:B4:DC:8F (-67 dBm), Object Path: /org/bluez/hci0/dev_00_16_53_B4_DC_8F
Traceback (most recent call last):
File "list_ports_boost_hub.py", line 38, in <module>
start(system)
File "/usr/local/lib/python3.7/dist-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/usr/local/lib/python3.7/dist-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/usr/local/lib/python3.7/dist-packages/bricknil/bleak_interface.py", line 75, in asyncio_loop
await device.write_gatt_char(char_uuid, msg_bytes)
File "/usr/local/lib/python3.7/dist-packages/bleak/backends/bluezdbus/client.py", line 252, in write_gatt_char
self.loop
txdbus.error.RemoteError: org.bluez.Error.Failed: Not connected
INFO:robot.6:Waiting for peripheral motor_r to attach to a port
INFO:robot.6:Waiting for peripheral motor_r to attach to a port
I'm trying to connect to my 4100 excavator from raspberry pi 4, but it gets disconnected right after connection. What I discovered is that connection won't drop until "notify" message is sent to socket, but I can't find out why it happens. No error or other clue appears. I'm starting to think there is race condition because it got connected once and started controlling motors. After I turned off bluetooth on raspberry, turned it on again and restarted my script with no code changes, it doesn't connect again. Here are logs:
DEBUG:vext:zope not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:zope not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:zope not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:zope not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:win32api not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:win32api not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:win32api not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:win32api not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:found module OpenSSL in sitedir or subdirectory [/usr/lib/python3/dist-packages]
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:found module OpenSSL in sitedir or subdirectory [/usr/lib/python3/dist-packages]
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:found module OpenSSL in sitedir or subdirectory [/usr/lib/python3/dist-packages]
DEBUG:asyncio:Using selector: EpollSelector
started thread for curio
inside curio run loop
INFO:BLE Event Q.0:using bleak
DEBUG:truck.2:Decorating class ExcavatorBase with CPlusXLMotor
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
DEBUG:vext:cPickle not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:cPickle not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:cPickle not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:cPickle not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:OpenSSL not found in: /home/pi/dev/lego:/usr/lib/python37.zip:/usr/lib/python3.7:/usr/lib/python3.7/lib-dynload:/home/pi/dev/lego_venv/lib/python3.7/site-packages
DEBUG:vext:found module OpenSSL in sitedir or subdirectory [/usr/lib/python3/dist-packages]
Done Awaiting on bleak discover
INFO:BLE Event Q.0:Rescanning for 00001623-1212-efde-1623-785feabcd123 (60 tries left)
Awaiting on bleak discover
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
Done Awaiting on bleak discover
INFO:BLE Event Q.0:checking manufacturer ID for device named Technic Hub for Control+ Hub
INFO:BLE Event Q.0:found device Technic Hub
DEBUG:bleak.backends.bluezdbus.client:Connecting to BLE device @ 90:84:2B:4E:A1:92 with hci0
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.client:Connection successful.
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.client:Get Services...
DEBUG:bleak.backends.bluezdbus.client:
Primary Service
/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service000c
00001623-1212-efde-1623-785feabcd123
Unknown
DEBUG:bleak.backends.bluezdbus.client:
Characteristic
/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service000c/char000d
00001624-1212-efde-1623-785feabcd123
Unknown
DEBUG:bleak.backends.bluezdbus.client:
Descriptor
/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service000c/char000d/desc000f
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
DEBUG:bleak.backends.bluezdbus.client:
Primary Service
/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service0001
00001801-0000-1000-8000-00805f9b34fb
Generic Attribute Profile
DEBUG:bleak.backends.bluezdbus.client:
Characteristic
/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service0001/char0002
00002a05-0000-1000-8000-00805f9b34fb
Service Changed
DEBUG:bleak.backends.bluezdbus.client:
Descriptor
/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service0001/char0002/desc0004
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
INFO:BLE Event Q.0:Device advertised: {'00001624-1212-efde-1623-785feabcd123': {'UUID': '00001624-1212-efde-1623-785feabcd123', 'Service': '/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service000c', 'Value': [15, 0, 4, 1, 1, 47, 0, 0, 16, 0, 0, 0, 16, 0, 0], 'Notifying': False, 'Flags': ['read', 'write-without-response', 'write', 'notify'], 'WriteAcquired': False, 'NotifyAcquired': False, 'Path': '/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service000c/char000d'}, '00002a05-0000-1000-8000-00805f9b34fb': {'UUID': '00002a05-0000-1000-8000-00805f9b34fb', 'Service': '/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service0001', 'Value': [], 'Notifying': False, 'Flags': ['indicate'], 'Path': '/org/bluez/hci0/dev_90_84_2B_4E_A1_92/service0001/char0002'}}
INFO:BLE Event Q.0:Connected to device Technic Hub:90:84:2B:4E:A1:92
INFO:BLE Event Q.0:Waiting for hubs to end
DEBUG:truck.2:starting peripheral message loop
INFO:truck.2:Running
DEBUG:BLE Event Q.0:Got msg: req mode info on 255 = [0, 33, 255, 1]
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
DEBUG:bleak.backends.bluezdbus.discovery:dev_90_84_2B_4E_A1_92, 90:84:2B:4E:A1:92 (-62 dBm), Object Path: /org/bluez/hci0/dev_90_84_2B_4E_A1_92
Traceback (most recent call last):
File "main.py", line 53, in <module>
start(system)
File "/home/pi/dev/lego/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/pi/dev/lego/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/pi/dev/lego/bricknil/bleak_interface.py", line 75, in asyncio_loop
await device.write_gatt_char(char_uuid, msg_bytes)
File "/home/pi/dev/lego_venv/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 252, in write_gatt_char
self.loop
txdbus.error.RemoteError: org.bluez.Error.Failed: Not connected
If I comment out line line 112 in bricknil.ble_queue
(await self.ble.in_queue.put( ('notify', (device, char_uuid, bleak_received) ))
), it doesn't disconnect, but motors don't move.
Can anyone help?
I want to use this library in a special way, i need your help (i use the control+ hub)
my main file is (main.py):
import curio
import train
if __name__ == '__main__':
curio.run(train.main()) # this works
curio.run(train.move()) # this doesn't
The second file is train.py
from curio import sleep
from bricknil import attach, start
from bricknil.hub import CPlusHub
from bricknil.sensor.motor import CPlusLargeMotor
@attach(CPlusLargeMotor, name='motor_A')
@attach(CPlusLargeMotor, name='motor_B')
class Train(CPlusHub):
async def run(self):
await self.motor_A.set_speed(+100)
await sleep(2)
async def move_forward(self):
await self.motor_A.set_speed(-100)
await self.motor_B.set_speed(-100)
await sleep(2)
async def system():
train = Train('My train')
async def main():
start(system)
async def move():
train = Train('My train')
await train.move_forward()
Hi, I feel liike this might be a bit of an ask, but I was hoping to get this or a similar package working on a Raspberry Pi Pico, and realised a little late that this isn't really for MicroPython.
Does anyone have any information about how I might get that working, if there's an alternative, or any suggestions at all.
Mainly hoping to get my lego train to be able to respond to basic commands from a pico at the "train station"
Hi all, just followed the instructions to install all Prereqs on my Raspberry Pi 3 running the latest Ubuntu mate.
I then ran the example Duplo code and his this error double traceback error:
(FYI if I don't use sudo I get a txdbus error that access is denied and rejects sending messages)
name@name-desktop:~$ sudo python3 legotraintest.py
started thread for curio
inside curio run loop
INFO:BLE Event Q.0:using bleak
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
Unhandled Error
Traceback (most recent call last):
File "/home/name/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 140, in dataReceived
self.rawDBusMessageReceived(raw_msg)
File "/home/name/.local/lib/python3.7/site-packages/txdbus/protocol.py", line 266, in rawDBusMessageReceived
self.signalReceived(m)
File "/home/name/.local/lib/python3.7/site-packages/txdbus/client.py", line 642, in signalReceived
self.router.routeMessage(msig)
File "/home/name/.local/lib/python3.7/site-packages/txdbus/router.py", line 128, in routeMessage
r.match(m)
--- ---
File "/home/name/.local/lib/python3.7/site-packages/txdbus/router.py", line 67, in match
self.callback(m)
File "/home/name/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 65, in parse_msg
device_interface = message.body[1].get("org.bluez.Device1", {})
builtins.AttributeError: 'list' object has no attribute 'get'
Traceback (most recent call last):
File "legotraintest.py", line 70, in
start(system)
File "/home/name/.local/lib/python3.7/site-packages/bricknil/bricknil.py", line 214, in start
ble.run()
File "/home/name/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 52, in run
self.loop.run_until_complete(self.asyncio_loop())
File "/usr/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
return future.result()
File "/home/name/.local/lib/python3.7/site-packages/bricknil/bleak_interface.py", line 65, in asyncio_loop
devices = await bleak.discover(timeout=1, loop=self.loop)
File "/home/name/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/discovery.py", line 167, in discover
returnSignature='a{sv}').asFuture(loop)
txdbus.error.RemoteError: org.freedesktop.DBus.Error.UnknownObject: Method "GetAll" with signature "s" on interface "org.freedesktop.DBus.Properties" doesn't exist
Hi,
at first many thanks for publishing this project.
I have created install scripts (ebuilds) to install bricknil and dependencies on Gentoo Linux.
I tried a first example with the Lego Boost movehub succesfully.
Hopfully I find some time to experiment with the Control+ stuff.
The ebuilds can be found here:
https://github.com/justxi/bricks
Hello,
Thank you for this great project. I have tried your example technic_4x4.py which works well for me. Do you know the ID of the sensors inside the Technic Plus Hub (which also include an IMU)? I would like to get access to the orientation of the hub. Look forward to hearing from you.
Hi, I read on https://www.eurobricks.com/forum/index.php?/forums/topic/170945-bricknil-a-python-async-library-for-poweredupboost/ about a dashboard for this project and an API - is the code for that anywhere?
Hello!
After installing python on Windows 11 and then bricknil, and then patching stuff so it'd actually run (and not error about imports)< I can't seem to get any of the example code working:
> python train-control.py
started thread for curio
DEBUG:asyncio:Using proactor: IocpProactor
inside curio run loop
INFO:BLE Event Q.0:using bleak
DEBUG:train1.2:Decorating class Train with TrainMotor
INFO:BLE Event Q.0:Starting scan for UART 00001623-1212-efde-1623-785feabcd123
INFO:BLE Event Q.0:Looking for first matching hub
Awaiting on bleak discover
Unhandled Exception: System.NotSupportedException: Cannot create uninitialized instances of types requiring managed activation.
at System.Runtime.Serialization.FormatterServices.nativeGetUninitializedObject(RuntimeType type)
at Python.Runtime.ClassObject.tp_new_impl(BorrowedReference tp, BorrowedReference args, BorrowedReference kw)
at Python.Runtime.NativeCall.Call_3(IntPtr fp, BorrowedReference a1, BorrowedReference a2, BorrowedReference a3)
at Python.Runtime.MetaType.tp_call(BorrowedReference tp, BorrowedReference args, BorrowedReference kw)
I get this error even if I try running the python code in an elevated cmd instance.
I'm not sure how to progress; it seems like some .net error, but none of the google hits indicate what the issue is or how to resolve it.
Any thoughts?
Hi, I've recently picked up my first power functions set and I'm looking forward to using bricknil for a bit of automation (Thanks for putting the package together!).
I have a brief documentation clarification question. The docs state that bricknil supports BLE on Windows 10 through bleak and a dotnet bridge. Could I confirm that this means that bleak should support any BLE adapter/dongle that has Windows 10 drivers? If not, do you recommend any particular dongle/adapter to ensure compatibility? (I'd be happy with a general answer, but for my specific case, I'd be very to interested to know if there are issues with any of the following adapter types: CSR 4.0, TP-Link NB407, BLED112, Widcomm).
Either way, it'd be good to add something along these lines in the documentation - If @virantha or @dlech can give a rough outline, I'm happy to draft something up.
Aside: My apologies if this question sounds a bit daft, but I've spend a good deal of the last couple of days going through various python bluetooth pages and many of them state no or limited support for Windows devices (some limited to just the Bluegiga BLED 112). Given this, I figured it was worth asking the question before going ahead and getting an adapter.
Thanks again for the package!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.