pyscrlink
pyscrlink copied to clipboard
Support for Intelino Smart Train
Hello,
I have a hard time connecting to Intelino Smart Train.
martin@bono:~$ scratch_link
2021-12-24 21:06:48,682 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/qk78wey4.Default User
2021-12-24 21:06:48,689 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/qk78wey4.Default User
2021-12-24 21:06:48,703 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/qk78wey4.Default User/chrome_debugger_profile
2021-12-24 21:06:48,712 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/qb752b1e.ff75
2021-12-24 21:06:48,719 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/u16lwrru.default
2021-12-24 21:06:48,727 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/fq9mqhp8.Martin
2021-12-24 21:06:48,974 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/no8dwo1j.Default User
2021-12-24 21:06:48,983 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/jmegri7g.p1
2021-12-24 21:06:48,991 Certificate is ready in FireFox NSS DB: /home/martin/.mozilla/firefox/ya14x5g6.temp
2021-12-24 21:06:48,999 Certificate is ready for Chrome
2021-12-24 21:06:49,016 Started scratch-link
2021-12-24 21:06:56,467 Start session for web socket path: /scratch/ble
2021-12-24 21:07:06,878 Can not scan BLE devices. Check BLE controller.
martin@bono:~$ bluetoothctl
Agent registered
[CHG] Controller 40:74:E0:9F:B6:B2 Pairable: yes
[bluetooth]# devices
Device 00:A0:50:B6:45:0E intelino J-1
Device 50:81:D8:01:8A:13 Sony PLAYSTATION(R)3 Controller
Device 98:D3:31:FB:14:F7 HC-06
Device 30:21:03:00:04:85 Creative T100
Device 20:1B:88:14:AD:70 Mi True Wireless EBs Basic 2
Device 34:88:5D:3F:5D:38 Bluetooth Mouse M557
Device 00:1B:FB:C3:8C:64 Sony PLAYSTATION(R)3 Controller
Device 20:01:08:00:A9:32 Escape 220
Device 74:51:BA:ED:0C:A5 Mi Phone
[bluetooth]# connect 00:A0:50:B6:45:0E
Attempting to connect to 00:A0:50:B6:45:0E
[CHG] Device 00:A0:50:B6:45:0E Connected: yes
Connection successful
[NEW] Primary Service (Handle 0x8746)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000a
00001801-0000-1000-8000-00805f9b34fb
Generic Attribute Profile
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000a/char000b
00002a05-0000-1000-8000-00805f9b34fb
Service Changed
[NEW] Descriptor (Handle 0xf360)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000a/char000b/desc000d
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Primary Service (Handle 0x80f0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000e
0000180a-0000-1000-8000-00805f9b34fb
Device Information
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000e/char000f
00002a24-0000-1000-8000-00805f9b34fb
Model Number String
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000e/char0011
00002a25-0000-1000-8000-00805f9b34fb
Serial Number String
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service000e/char0013
00002a26-0000-1000-8000-00805f9b34fb
Firmware Revision String
[NEW] Primary Service (Handle 0x80f0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0015
0000180f-0000-1000-8000-00805f9b34fb
Battery Service
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0015/char0016
00002a19-0000-1000-8000-00805f9b34fb
Battery Level
[NEW] Descriptor (Handle 0x7360)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0015/char0016/desc0018
00002904-0000-1000-8000-00805f9b34fb
Characteristic Format
[NEW] Descriptor (Handle 0x7360)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0015/char0016/desc0019
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Primary Service (Handle 0x80f0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001a
00060000-f8ce-11e4-abf4-0002a5d5c51b
Vendor specific
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001a/char001b
00060001-f8ce-11e4-abf4-0002a5d5c51b
Vendor specific
[NEW] Descriptor (Handle 0x76a0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001a/char001b/desc001d
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Descriptor (Handle 0x76a0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001a/char001b/desc001e
00002901-0000-1000-8000-00805f9b34fb
Characteristic User Description
[NEW] Primary Service (Handle 0x80f0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001f
43dfd9e9-17e5-4860-803d-9df8999b0d7a
Vendor specific
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001f/char0020
40c540d0-344c-4d0d-a1da-9cc260b82d43
Vendor specific
[NEW] Descriptor (Handle 0x77a0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service001f/char0020/desc0022
00002901-0000-1000-8000-00805f9b34fb
Characteristic User Description
[NEW] Primary Service (Handle 0x80f0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0023
4dad4922-5c86-4ba7-a2e1-0f240537bd08
Vendor specific
[NEW] Characteristic (Handle 0x75eb)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0023/char0024
a4b80869-a84c-4160-a3e0-72fa58ff480e
Vendor specific
[NEW] Descriptor (Handle 0x7aa0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0023/char0024/desc0026
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration
[NEW] Descriptor (Handle 0x7aa0)
/org/bluez/hci0/dev_00_A0_50_B6_45_0E/service0023/char0024/desc0027
00002901-0000-1000-8000-00805f9b34fb
Characteristic User Description
[CHG] Device 00:A0:50:B6:45:0E ServicesResolved: yes
Pairing doesn't work. Probably the train is not pairable.
[bluetooth]# pair 00:A0:50:B6:45:0E
Attempting to pair with 00:A0:50:B6:45:0E
[CHG] Device 00:A0:50:B6:45:0E Connected: yes
Failed to pair: org.bluez.Error.AuthenticationFailed
[CHG] Device 00:A0:50:B6:45:0E Connected: no
Using https://scratch.intelino.com/
I can connect to the device
I replaced deviceName = dev.getValueText(0x08)
with deviceName = dev.getValueText(0x09)
and the device was found. Unfortunately the device disconnects shortly after it is connected.
BTW the filter is {'filters': [{'namePrefix': 'intelino'}, {'manufacturerData': {'2333': {'dataPrefix': [0, 1], 'mask': [0, 255]}}}], 'optionalServices': ['43dfd9e9-17e5-4860-803d-9df8999b0d7a', '4dad4922-5c86-4ba7-a2e1-0f240537bd08']}
Attaching output of scratch_link -d
: debug.log.gz
Hi @zdila Thank you for sharing the issues.
It is great that you found that dev.getValueText(0x09) make pyscrlink connect to Intelino Smart Train. I will improve the pyscrlink code to try out both dev.getValueText(0x09) and dev.getValueText(0x08.
Regarding the disconnection, I checked the debug.log. Connection was established, and notification start was requested to the device, and some data write were made to the device. After that It looks like that the Scarch for Intelino Smart Train disconnects the connection to pyscrlink. Here I quote a part of debug.log. The line "scratch closed session" means that something is happening in the scratch side.
2021-12-25 12:17:27,618 start to notify
2021-12-25 12:17:27,618 in handle loop
2021-12-25 12:17:27,618 start recv_request
2021-12-25 12:17:27,618 scratch closed session
2021-12-25 12:17:27,618 received 1005 (no status code [internal]); then sent 1005 (no status code [internal])
2021-12-25 12:17:27,618 BLE session disconnected
2021-12-25 12:17:27,618 BLE session connected=0
2021-12-25 12:17:27,618 all BLE sessions disconnected
2021-12-25 12:17:27,618 disconnect from the BLE peripheral: intelino J-1
In the log, I did not find any notification message from the device. So my mere guess is that scratch for Intelino Smart Train timed out to wait for notifications from the device.
At this moment, I can not think of further way to investigate this issue. I wanted to take a look in the code of scratch for Intelino Smart Train, but I can not find it on the net...
Thanks for your reply. I've managed to create a dump of websocket communication from working scratch-link on MacOS. Will it help? It contains all messages from connecting to the train till manual disconnection. When connected, train sends many messages (probably its status, like current speed or what color did it just scan.
WS dump when using pyscrlink: pyscrlink-ws-dump.json.gz
It looks like pyscrlink is not receiving characteristics change (or not sending them via WS). I tried following steps using nRF Connect Android app:
- connect to the device
- write
b7 02 07 0a
to service43dfd9e9-17e5-4860-803d-9df8999b0d7a
, characteristic40c540d0-344c-4d0d-a1da-9cc260b82d43
- subscribe to indications on service
4dad4922-5c86-4ba7-a2e1-0f240537bd08
, characteristica4b80869-a84c-4160-a3e0-72fa58ff480e
- send
07 00
to service43dfd9e9-17e5-4860-803d-9df8999b0d7a
, characteristic40c540d0-344c-4d0d-a1da-9cc260b82d43
- send
41 01 01
to service43dfd9e9-17e5-4860-803d-9df8999b0d7a
, characteristic40c540d0-344c-4d0d-a1da-9cc260b82d43
then I started recording and saw many notifications on characteristic a4b80869-a84c-4160-a3e0-72fa58ff480e
with bytes b7 12 03 00 00 ff 01 00 00 00 00 01 03 00 00 06 10 42 00 00
. This part is missing in pyscrlink WS communication and could be the cause of disconenction
Meanwhile I've written Scratch Link for Linux and Intelino smart train in nodejs: https://github.com/zdila/intelino-smart-train-scratch-link-linux
@zdila It's great that your wrote nodejs version of scratch-link :) I'm interested in your node js code. Is it working good for your device? If so, that's a good step forward.
Thank you for sharing the wireshark and nRF Connect logs. They helped me to have the wider view. From the pyscrlink logs, pyscrlink received the write and the notification subscribe requests from Scratch and handled them. However, there is no notification from the device. My current guess is that notification subscribe handling by pyscrlink is not correct (there could be a possibility that layers below pyscrlink is not working correctly, but if your nodejs version is working good, this is not the case).
Still I need some more time to think about the notification subscription handling.
I have spent some time about BLE Characteristic and notification. And learned that CCCD (Client Characteristic Configuration Descriptor) is the key to enable notification. Current pyscrlink assumes that CCCD comes just after the Characteristic Value declaration, but the spec warns that we should not assumes such an order. If this assumption in pyscrlink is wrong for the Intelino Smart Train, it could be the cause of the no notification from the device.
I made a commit 2d489321d07a to dev branch to avoid the assumption in pyscrlink. Now pyscrlink looks up the CCCD to enable notification. I wish this fix the issue with Intelino Smart Train.
@zdila If you have time to afford, please try the dev branch tip.
I tried the dev
branch with your commit but unfortunatley the problem is still there.
Yes, my Node.js version works fine with my Intelino train.
@zdlia Thank you for the quick update. It is my sorrow the problem is still there. At this moment, I have no further idea about the trouble cause. I will remove Intelino statements from the README of pyscrlink. Anyway, it is good that your node.js version is available for other Intelino users.
Just a comment after looking into your node.js implementation. Oh, it uses DBus interface to communicate with bluetooth side. It's simple and looks stable. Hmm, that could be an option for pyscrlink future improvement.
Yes. There are other Node.js bluetooth alternatives like https://github.com/noble/noble (seems to be multiplatform but I got errors installing it as it failed compiling some native code) or https://github.com/chrvadala/node-ble (also uses D-Bus but it hides for example API for setting BT scanning filter), but using D-Bus directly (https://github.com/dbusjs/node-dbus-next library) it wasn't difficult to utilize BLE on my own :-).
BTW my scratch-link is also faster in finding a device for some reason (it finds it immediately if it is powered on, whereas for pyscrlink it takes couple of seconds). Also pyscrlink is using some loop for getting events which east CPU (in my case it eats 100% of a single core if it fails to connect). I think it is a problem of PyBluez design.
Thank you. The bluetooth libraries situation in Node.js sounds similar as that in Python. There are multiple bluetooth and BLE support libraries. Some of them are old, and not so stable. I has been thinking which bluetooth/BLE library could be the better, but that D-Bus approach sounds the best, at this moment.
Also thank you for sharing your experience on the device finding speed and CPU consumption. Unfortunately (or fortunately), I have not yet observed them. Will keep them in my mind.
Hello, i'm using pyscrlink on Linux (Ubuntu 20.04) to connect WeDo 2.0 and EV3 devices. Is it possible to try the Node.js version?
@markakis-sch I think it would be more suitable to discuss it at https://github.com/zdila/intelino-smart-train-scratch-link-linux/issues. Node.js version currently ignores bluetooth filter and is hardcoded with intelino
string, but it is east to try it with different hardcoded name. Also it doesn't support getServices
or getCharacteristics
methods as intelino doesn't use them. But I can try to imlement them and you could try (I don't have the hardware). Or maybe your device doesn't use those methods as well.
I have made https://github.com/zdila/scratch-link-ble-linux/ ready for other BLE devices, but had no chance to test it with anything but Intelino smart train.
Yep it would be good to create an issue in scratch-link-ble-linux for the discussion. My two cents on WeDo and EV3: WeDo is a BLE device, then it's worth trying with scratch-link-ble-linux. On the other hand, Lego EV3 is not a BLE device, but a BT device. Scratch-link-ble-linux looks dedicated to BLE devices at this moment, so EV3 will not work. To support EV3, some more work will be required for scratch-link-ble-linux to support BT Peripheral Protocol.
BTW https://github.com/intelino-code/intelino-trainlib-async-py uses https://github.com/hbldh/bleak
Oh, then bleak can be another choice, in place of bluepy. Bleak looks newer and more active than bluepy. Will think about it :)
BTW my scratch-link is also faster in finding a device for some reason (it finds it immediately if it is powered on, whereas for pyscrlink it takes couple of seconds). Also pyscrlink is using some loop for getting events which east CPU (in my case it eats 100% of a single core if it fails to connect). I think it is a problem of PyBluez design.
I confirm that finding a device (i used a WeDo 2.0) is much slower with pyscrlink than with scratch-link-ble-linux.