pyscrlink icon indicating copy to clipboard operation
pyscrlink copied to clipboard

Support for Intelino Smart Train

Open zdila opened this issue 2 years ago • 21 comments

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

zdila avatar Dec 24 '21 20:12 zdila

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']}

zdila avatar Dec 25 '21 11:12 zdila

Attaching output of scratch_link -d: debug.log.gz

zdila avatar Dec 25 '21 11:12 zdila

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...

kawasaki avatar Dec 31 '21 06:12 kawasaki

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.

intelino.txt.gz

zdila avatar Dec 31 '21 11:12 zdila

WS dump when using pyscrlink: pyscrlink-ws-dump.json.gz

zdila avatar Dec 31 '21 11:12 zdila

It looks like pyscrlink is not receiving characteristics change (or not sending them via WS). I tried following steps using nRF Connect Android app:

  1. connect to the device
  2. write b7 02 07 0a to service 43dfd9e9-17e5-4860-803d-9df8999b0d7a , characteristic 40c540d0-344c-4d0d-a1da-9cc260b82d43
  3. subscribe to indications on service 4dad4922-5c86-4ba7-a2e1-0f240537bd08 , characteristic a4b80869-a84c-4160-a3e0-72fa58ff480e
  4. send 07 00 to service 43dfd9e9-17e5-4860-803d-9df8999b0d7a , characteristic 40c540d0-344c-4d0d-a1da-9cc260b82d43
  5. send 41 01 01 to service 43dfd9e9-17e5-4860-803d-9df8999b0d7a , characteristic 40c540d0-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

zdila avatar Dec 31 '21 12:12 zdila

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 avatar Jan 01 '22 15:01 zdila

@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.

kawasaki avatar Jan 03 '22 00:01 kawasaki

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.

kawasaki avatar Jan 03 '22 03:01 kawasaki

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.

zdila avatar Jan 03 '22 07:01 zdila

@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.

kawasaki avatar Jan 03 '22 10:01 kawasaki

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.

kawasaki avatar Jan 03 '22 10:01 kawasaki

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.

zdila avatar Jan 03 '22 11:01 zdila

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.

kawasaki avatar Jan 03 '22 11:01 kawasaki

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 avatar Jan 03 '22 12:01 markakis-sch

@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.

zdila avatar Jan 03 '22 13:01 zdila

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.

zdila avatar Jan 03 '22 19:01 zdila

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.

kawasaki avatar Jan 04 '22 09:01 kawasaki

BTW https://github.com/intelino-code/intelino-trainlib-async-py uses https://github.com/hbldh/bleak

zdila avatar Jan 06 '22 09:01 zdila

Oh, then bleak can be another choice, in place of bluepy. Bleak looks newer and more active than bluepy. Will think about it :)

kawasaki avatar Jan 06 '22 23:01 kawasaki

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.

grigorism avatar Jan 07 '22 13:01 grigorism