Open nodecentral opened 2 years ago
Sorry, but this project is not properly functional (so I'm not using it) - I uploaded it only for reference for others who may want to build on it. The problem I ran into was that I couldn't establish a reliable BLE connection to the lawnmower, but if you can maintain a connection then I'd love to know how! I tried both esp32-ble2mqtt and a USB BLE dongle but neither one was reliable for me. Really annoying as the project is 99% of the way to a MVP.
It does work for a minute or so if you get it set up. It should connect and print out the model / software version number of the lawnmower on start. After it will read the current state of the lawnmower and update the mqtt server once every 60 seconds for as long as it stays connected.
If you want to get it set up anyway knowing that, you'll need to ether set up that project or get a usb ble dongle (needs to be bluetooth 4.2 or above). The password is hardcoded as 1234 (power, calendar, start, home button) which you will need to change.
Still planning to come back to this so adding this here for future reference
Just came across this admitedly-shelved project whilst wondering if I can pull some of the state info via the Bluetooth connection of the mower. I'm therefore not too worried about the MQQT potion (although have a mosquito instance at hand) but more on the BLE portion even-if-unreliable...
- For a BLE dongle you need to change the source code to swap out mqqt_packet_interface with ble_packet_interface. You'll need to pass the connected pygatt.BLEDevice instance into the packet interface.
Python (and BLE) noob here but would appreciate some help in achieving this - not sure how to replace mqtt for ble (and how to handle pygatt) myself...
Not having much luck connecting... any tips?
2023-04-10 09:54:50,697 - __main__ - DEBUG - Configuring packet interface
DEBUG:__main__:Configuring packet interface
2023-04-10 09:54:50,698 - __main__ - DEBUG - Sending connect
DEBUG:__main__:Sending connect
DEBUG:mower.packet_interface:Sending ConnectRequest
DEBUG:mower.mqtt_packet_interface:TX: 02fd160000000000002e1490a1795d000000004d
DEBUG:mower.mqtt_packet_interface:TX: 61696e004c03
DEBUG:mower.packet_interface:Sending ConnectRequest
DEBUG:mower.mqtt_packet_interface:TX: 02fd160000000000002e1490a1795d000000004d
DEBUG:mower.mqtt_packet_interface:TX: 61696e004c03
DEBUG:mower.packet_interface:Sending ConnectRequest
DEBUG:mower.mqtt_packet_interface:TX: 02fd160000000000002e1490a1795d000000004d
DEBUG:mower.mqtt_packet_interface:TX: 61696e004c03
2023-04-10 09:54:59,730 - __main__ - ERROR - Failed connecting
Traceback (most recent call last):
File "C:\Users\lfixt\Downloads\flymo2mqtt-master\flymo2mqtt-master\src\run.py", line 69, in <module>
response = cast(ConnectResponse, interface.send(ConnectRequest(1568252304, 0, "Main")))
File "C:\Users\lfixt\Downloads\flymo2mqtt-master\flymo2mqtt-master\src\mower\mqtt_packet_interface.py", line 49, in send
return self.interface.send(packet)
File "C:\Users\lfixt\Downloads\flymo2mqtt-master\flymo2mqtt-master\src\mower\packet_interface.py", line 41, in send
data = self.receive_queue.get(block=True, timeout=3)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\queue.py", line 179, in get
raise Empty
_queue.Empty
ERROR:__main__:Failed connecting
Traceback (most recent call last):
File "C:\Users\lfixt\Downloads\flymo2mqtt-master\flymo2mqtt-master\src\run.py", line 69, in <module>
response = cast(ConnectResponse, interface.send(ConnectRequest(1568252304, 0, "Main")))
File "C:\Users\lfixt\Downloads\flymo2mqtt-master\flymo2mqtt-master\src\mower\mqtt_packet_interface.py", line 49, in send
return self.interface.send(packet)
File "C:\Users\lfixt\Downloads\flymo2mqtt-master\flymo2mqtt-master\src\mower\packet_interface.py", line 41, in send
data = self.receive_queue.get(block=True, timeout=3)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\queue.py", line 179, in get
raise Empty
_queue.Empty
Not having much luck connecting... any tips?
Blind leading the blind here but I think one has to start outside of the python script and get the Flymo pairing on the OS-side first, I finally got this going with bluetoothctl...
First get the mower's Bluetooth MAC, I picked it up from my phones Bluetooth device connections list, spin up 'bluetoothctl', replace 60:98:66:EF:61:F0 with whatever your device's MAC is.
In bluetoothctl:
agent KeyboardDisplay
pairable on
trust 60:98:66:EF:61:F0
You now need to get your Flymo into pairing mode, you do that (as per the manual) by powering it off and then on again, it will be in a 'pairable' state for 3 minutes, then in bluetoothctl issue:
pair 60:98:66:EF:61:F0
<you will hopefully be prompted for a pin - work it out as per the 1st reply in this Git issue>
connect 60:98:66:EF:61:F0
You should get a affirmative messgae, the bluetoothctl prompt should also change to "[EasiLife GO 500]" or whatever model you have. If not, give a shout as I've reverted to bt-agent which seems to work OK. The info command is also very useful to understand the state:
info 60:98:66:EF:61:F0
Device 60:98:66:EF:61:F0 (public)
Name: EasiLife GO 500
Alias: EasiLife GO 500
Paired: yes
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (98bd0001-0b0e-421a-84e5-ddbf75dc6de4)
Now that I am able to pair I have been able to browse the characteristics like this:
$ gatttool -b 60:98:66:EF:61:F0 --characteristics
handle = 0x0002, char properties = 0x02, char value handle = 0x0003, uuid = 00002a00-0000-1000-8000-00805f9b34fb
handle = 0x0004, char properties = 0x02, char value handle = 0x0005, uuid = 00002a01-0000-1000-8000-00805f9b34fb
handle = 0x0006, char properties = 0x02, char value handle = 0x0007, uuid = 00002a04-0000-1000-8000-00805f9b34fb
handle = 0x000a, char properties = 0x04, char value handle = 0x000b, uuid = 98bd0002-0b0e-421a-84e5-ddbf75dc6de4
handle = 0x000d, char properties = 0x12, char value handle = 0x000e, uuid = 98bd0003-0b0e-421a-84e5-ddbf75dc6de4
handle = 0x0011, char properties = 0x02, char value handle = 0x0012, uuid = 98bd0004-0b0e-421a-84e5-ddbf75dc6de4
However unable to figure out how/what I should pull to translate for example the battery level or mower state, so guidance would be fantastic.
Great, i've managed to get connect via home assistant cli
Name: EasiLife GO 250
Alias: EasiLife GO 250
Paired: no
Trusted: yes
Blocked: no
Connected: no
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (98bd0001-0b0e-421a-84e5-ddbf75dc6de4)
ManufacturerData Key: 0x0426
Next step is to install flymo2mqtt container and have a play
OK I can't connect using gattool, seems my pairing isn't working
Paired: no
Great to see you've made some progress @esticle
The mower communicates by writing to the write characteristic (98BD0002-0B0E-421A-84E5-DDBF75DC6DE4) and reading from the read characteristic (98BD0003-0B0E-421A-84E5-DDBF75DC6DE4). Once you've got a BLE connection you need to unlock the mower before you can read the battery level and state. Take a look at the code for how it's done: https://github.com/tgillbe/flymo2mqtt/blob/ea8e369280b2f5673777512e342e4ad938e0fc51/src/run.py#L68-L81
Basically you send a connect request, setup the protocol version then send the pin. The connection request has a hardcoded parameter 1568252304 in the code which may vary depending on the mower, I'm not sure it'll work for you but it works for me. The pin that needs to be sent is the same as what you press into the mower to unlock it, it's hardcoded as 1234 (power, calendar, start, home button).
If you want to take a look at the protocol messages to see how it works and you've got an android phone, you can use logcat. The official app outputs loads of great logging messages.
@totalitarian you've got to bond to the mower first, @esticle put a great guide up above. Problems with reliability of the bluetooth link was why I shelved the project though!
Great to see you've made some progress @esticle
Thanks for letting us abuse your shelved project's issue list :)
The mower communicates by writing to the write characteristic (98BD0002-0B0E-421A-84E5-DDBF75DC6DE4) and reading from the read characteristic (98BD0003-0B0E-421A-84E5-DDBF75DC6DE4). Once you've got a BLE connection you need to unlock the mower before you can read the battery level and state. Take a look at the code for how it's done:
Basically you send a connect request, setup the protocol version then send the pin. The connection request has a hardcoded parameter 1568252304 in the code which may vary depending on the mower, I'm not sure it'll work for you but it works for me. The pin that needs to be sent is the same as what you press into the mower to unlock it, it's hardcoded as 1234 (power, calendar, start, home button).
I cannot really read Python but figured you must have pulled 1568252304 from somehwere so I was hoping to get gatttoool equivelents of these commands. Similairly so for the '4586' for mower_activity, really appreciate the pointers as it appears I was roughly going in the right direction - but first attempts are failing... (b = write, e = read for me)
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 1568252304
connect to 60:98:66:EF:61:F0: Function not implemented (38)
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 1568252304
Characteristic Write Request failed: Request attribute has encountered an unlikely error
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 1568252304
Characteristic Write Request failed: Request attribute has encountered an unlikely error
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 1568252304
connect to 60:98:66:EF:61:F0: Function not implemented (38)
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 1568252304
connect to 60:98:66:EF:61:F0: Connection timed out (110)
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 1568252304
Characteristic value was written successfully
$ gatttool -b 60:98:66:EF:61:F0 --char-read -a 0x000e
Characteristic value/descriptor:
$ gatttool -b 60:98:66:EF:61:F0 --char-read -a 0x000e
Characteristic value/descriptor:
$ gatttool -b 60:98:66:EF:61:F0 --char-read -a 0x000e
Characteristic value/descriptor:
If you want to take a look at the protocol messages to see how it works and you've got an android phone, you can use logcat. The official app outputs loads of great logging messages.
Thanks for confirming - I was just going to start looking at that and was wondering if it logs the BLE messages, it will be interesting to confirm if I see 1568252304 as well (and I have a different pin which I figured out how to derive from your efforts).
@totalitarian you've got to bond to the mower first, @esticle put a great guide up above.
Yep @totalitarian in bluetootctl issue a 'connect MAC_ADDRESS' at which point it should ask for the PIN (if not, give a shout and we can look at bt-agent) - just make sure your mower is in pairing mode (recently turned on) before attempting this.
Problems with reliability of the bluetooth link was why I shelved the project though!
Yeah, it is very hit and miss even when parked as shown in the gatttool above, however I'm quite ok to get some-state-some-of-the-time, ie. a notification when stuck would be way better than myself currently monitoring power draw and where I have notification if I have NOT seen the mower charging for more than 8 hours :)
Thanks again for the tips, I'll report back on what I see.
So this is what I get after turning the mower on
pi@raspberrypi:~ $ bluetoothctl connect D8:71:4D:6C:E2:B4
Attempting to connect to D8:71:4D:6C:E2:B4
[CHG] Device D8:71:4D:6C:E2:B4 Connected: yes
Failed to connect: org.bluez.Error.Failed
The mower communicates by writing to the write characteristic (98BD0002-0B0E-421A-84E5-DDBF75DC6DE4) and reading from the read characteristic (98BD0003-0B0E-421A-84E5-DDBF75DC6DE4). Once you've got a BLE connection you need to unlock the mower before you can read the battery level and state. Take a look at the code for how it's done: Basically you send a connect request, setup the protocol version then send the pin. The connection request has a hardcoded parameter 1568252304 in the code which may vary depending on the mower, I'm not sure it'll work for you but it works for me. The pin that needs to be sent is the same as what you press into the mower to unlock it, it's hardcoded as 1234 (power, calendar, start, home button).
I cannot really read Python but figured you must have pulled 1568252304 from somehwere so I was hoping to get gatttoool equivelents of these commands. Similairly so for the '4586' for mower_activity, really appreciate the pointers as it appears I was roughly going in the right direction - but first attempts are failing... (b = write, e = read for me)
1568252304 is just a parameter in one of the packets (i.e. link_id, which in hex is 0x5D79A190). You need to send the whole packet to the characteristic - the connect packet looks like this (annotated with what I think each byte does):
0x02, // Start
0xFD, // Header?
0x16, 0x00, // Length
0x00, 0x00, 0x00, 0x00, // Channel ID
0x00, // Flag
0x2E, // Header CRC
0x14, // ConnectRequest.get_head()
0x90, 0xA1, 0x79, 0x5D, // ConnectRequest.link_id
0x00, 0x00, 0x00, 0x00, // ConnectRequest.node_type
0x4D, 0x61, 0x69, 0x6E, 0x00, // ConnectRequest.name
0x4C, // Full CRC
0x03 // End
The packet is split into chunks 20 bytes long. You can see it in the log messages from @totalitarian above:
DEBUG:mower.packet_interface:Sending ConnectRequest DEBUG:mower.mqtt_packet_interface:TX: 02fd160000000000002e1490a1795d000000004d DEBUG:mower.mqtt_packet_interface:TX: 61696e004c03
You could try sending this and see if you get anything back, I'm not certain of gatttool's endianness though:
gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 0x02fd160000000000002e1490a1795d000000004d gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 0x61696e004c03
You should get the following bytes in response:
0x02, // Start
0xFD, // Header?
0x0D, 0x00, // Length
0x00, 0x00, 0x00, 0x00, // Channel ID
0x00, // Flag
0x63, // Header CRC
0x15, // Packet type
0x90, 0xA1, 0x79, 0x5D, // New channel ID
0x30, // Full CRC
0x03 // End
A channel ID is sent in the response which needs to be included in future communications. If you provide an invalid CRC I don't think the lawnmower will respond.
So this is what I get after turning the mower on
Try it a number of times (like 10) - it should either (finally) connect or complain about Auth failing.
So this is what I get after turning the mower on
Try it a number of times (like 10) - it should either (finally) connect or complain about Auth failing.
So i'm confused about the flow here...
1) do I need to press anything on the mower - i.e enter the pin on the mower control panel? 2) Is this the correct sequence?
agent KeyboardDisplay
pairable on
trust D8:71:4D:6C:E2:B4
pair D8:71:4D:6C:E2:B4
**_I never get a prompt here at all_**
connect D8:71:4D:6C:E2:B4
Thanks for the reply!
1568252304 is just a parameter in one of the packets (i.e. link_id, which in hex is 0x5D79A190). You need to send the whole packet to the characteristic - the connect packet looks like this (annotated with what I think each byte does): The packet is split into chunks 20 bytes long. You can see it in the log messages from @totalitarian above:
Yep - so from logcat I see similair packets starting 02 FD - my PIN is 3333 fwiw and I think I lifted the relevant sections of just connecting and loading up the main screen.
04-11 12:48:11.090 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$EnterOperatorPinRequest@9f9e047
04-11 12:48:11.090 3756 3756 D AutomowerLinkedProtocol: Parameter [name=pin, type=uint16, length=0, boolValue=null, intValue=3333, longValue=null, stringValue=null, dataValue=null]
04-11 12:48:11.091 3756 3857 V Sending:: 02 FD 12 00 8C C9 C1 19 01 62 00 AF 38 12 04 00 02 00 05 0D
04-11 12:48:11.092 3756 3773 V Data written:: 02 FD 12 00 8C C9 C1 19 01 62 00 AF 38 12 04 00 02 00 05 0D
04-11 12:48:11.092 3756 3857 V Sending:: 44 03
04-11 12:48:11.093 8148 8982 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:11.093 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:11.093 3756 3773 V Data written:: 44 03
04-11 12:48:12.185 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 38 12 04 00 00 00 00 AB
04-11 12:48:12.185 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$EnterOperatorPinResponse@731c99d
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$IsOperatorLoggedInRequest@80ede12
04-11 12:48:12.186 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 38 12 03 00 00 00 01 03
04-11 12:48:12.187 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.187 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.188 3756 3774 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 38 12 03 00 00 00 01 03
04-11 12:48:12.279 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 12 00 8C C9 C1 19 01 62 01 AF 38 12 03 00 00 01 00 01
04-11 12:48:12.280 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: FF 03
04-11 12:48:12.280 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.280 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$IsOperatorLoggedInResponse@9ea39e3
04-11 12:48:12.280 3756 3756 D AutomowerLinkedProtocol: Parameter [name=operatorLoggedIn, type=bool, length=0, boolValue=true, intValue=null, longValue=null, stringValue=null, dataValue=null]
04-11 12:48:12.282 3756 3858 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.282 3756 3858 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.CalendarCommands$GetTimeRequest@eefffe0
04-11 12:48:12.283 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 52 12 02 00 00 00 82 03
04-11 12:48:12.285 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.286 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.287 3756 3774 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 52 12 02 00 00 00 82 03
04-11 12:48:12.374 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 15 00 8C C9 C1 19 01 D1 01 AF 52 12 02 00 00 04 00 0B
04-11 12:48:12.374 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 57 35 64 70 03
04-11 12:48:12.375 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.375 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.CalendarCommands$GetTimeResponse@3666299
04-11 12:48:12.375 3756 3756 D AutomowerLinkedProtocol: Parameter [name=time, type=tUnixTime, length=0, boolValue=null, intValue=null, longValue=1681217291, stringValue=null, dataValue=null]
04-11 12:48:12.436 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.436 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@10cd059
04-11 12:48:12.436 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.438 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.439 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.440 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.611 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 42 12 02 00 00 00 00 6F
04-11 12:48:12.611 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveResponse@9c21434
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@e02a25d
04-11 12:48:12.614 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.615 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.615 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.616 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.708 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 42 12 02 00 00 00 00 6F
04-11 12:48:12.709 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveResponse@585a7d2
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@176a0a3
04-11 12:48:12.709 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.710 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.711 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:62:B4
04-11 12:48:12.711 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.802 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 42 12 02 00 00 00 00 6F
04-11 12:48:12.802 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.802 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.802 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveResponse@5863fa0
04-11 12:48:12.802 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.802 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@74c0759
04-11 12:48:12.803 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.805 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.807 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.808 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.896 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 42 12 02 00 00 00 00 6F
04-11 12:48:12.896 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.896 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.897 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveResponse@d726f1e
04-11 12:48:12.897 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.897 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@6c8a3ff
04-11 12:48:12.897 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.899 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.899 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.900 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
I cannot however make any heads-or-tails of where the equivelent of 0x5D79A190 factors in here
DEBUG:mower.packet_interface:Sending ConnectRequest DEBUG:mower.mqtt_packet_interface:TX: 02fd160000000000002e1490a1795d000000004d DEBUG:mower.mqtt_packet_interface:TX: 61696e004c03
I've never gotten anything but a 'Failed connecting' even though I have addressed the PIN value appropriately in your code - so maybe there is some uniqueness here.
You could try sending this and see if you get anything back, I'm not certain of gatttool's endianness though:
gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 0x02fd160000000000002e1490a1795d000000004d gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 0x61696e004c03
You should get the following bytes in response:
0x02, // Start 0xFD, // Header? 0x0D, 0x00, // Length 0x00, 0x00, 0x00, 0x00, // Channel ID 0x00, // Flag 0x63, // Header CRC 0x15, // Packet type 0x90, 0xA1, 0x79, 0x5D, // New channel ID 0x30, // Full CRC 0x03 // End
A channel ID is sent in the response which needs to be included in future communications. If you provide an invalid CRC I don't think the lawnmower will respond.
Thanks for this! I was hoping something like this would get me going - sadly:
$ gatttool -b 60:98:66:EF:61:F0 --char-write-req -a 0x000b -n 0x02fd160000000000002e1490a1795d000000004d
Characteristic Write Request failed: Attribute value length is invalid
If gatttool is a no-go and makes the conversion hard Python is probably the way to go although I have no idea of where to begin with replacing yours with ble_packet_interface - darn, more questions than answers now! :)
I can get connected but not paired for some reason
[EasiLife GO 250]# info
Device D8:71:4D:6C:E2:B4 (public)
Name: EasiLife GO 250
Alias: EasiLife GO 250
Paired: no
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (98bd0001-0b0e-421a-84e5-ddbf75dc6de4)
ManufacturerData Key: 0x0426
ManufacturerData Value:
OK maybe I don't need to be paired?
pi@raspberrypi:~ $ gatttool -b D8:71:4D:6C:E2:B4 --characteristics
handle = 0x0002, char properties = 0x02, char value handle = 0x0003, uuid = 00002a00-0000-1000-8000-00805f9b34fb
handle = 0x0004, char properties = 0x02, char value handle = 0x0005, uuid = 00002a01-0000-1000-8000-00805f9b34fb
handle = 0x0006, char properties = 0x02, char value handle = 0x0007, uuid = 00002a04-0000-1000-8000-00805f9b34fb
handle = 0x000a, char properties = 0x04, char value handle = 0x000b, uuid = 98bd0002-0b0e-421a-84e5-ddbf75dc6de4
handle = 0x000d, char properties = 0x12, char value handle = 0x000e, uuid = 98bd0003-0b0e-421a-84e5-ddbf75dc6de4
handle = 0x0011, char properties = 0x02, char value handle = 0x0012, uuid = 98bd0004-0b0e-421a-84e5-ddbf75dc6de4
Try it a number of times (like 10) - it should either (finally) connect or complain about Auth failing.
So i'm confused about the flow here...
- do I need to press anything on the mower - i.e enter the pin on the mower control panel?
Nope, just turn it off and on again, if you enter the 'connect' bit within 3 minutes when it is in 'pair' mode you should be good.
- Is this the correct sequence?
agent KeyboardDisplay pairable on trust D8:71:4D:6C:E2:B4 pair D8:71:4D:6C:E2:B4 **_I never get a prompt here at all_** connect D8:71:4D:6C:E2:B4
I had 'power on' as well, but the above should do. Depending on version of bluetoothctl some people have different outcomes - IF you get AuthFailed as a response you can use bt-agent like this:
$ echo "D8:71:4D:6C:E2:B4 1234" > ~/pincodes
$ bt-agent -d -c KeyboardOnly ~/pincodes
Change your pin from 1234 to whatever yours is depending on the buttons as per @tgillbe 's comments above.
I would not encourage to make the sitsuation 'messy' in doing the above until you confirm you get a failed Auth condition with using 'connect' - especially since tgillbe's code uses the PIN anyway.
Hope that helps!
OK maybe I don't need to be paired?
You can grab the characteristics and you will get some responses but not be able to read (and possibly write) all values when NOT paired.
I'm lost then, nothing I do lets me pair, I don't get any prompt. Can connect all day long though
pi@raspberrypi:~ $ bluetoothctl connect D8:71:4D:6C:E2:B4
Attempting to connect to D8:71:4D:6C:E2:B4
[CHG] Device D8:71:4D:6C:E2:B4 Connected: yes
Connection successful
I'm lost then, nothing I do lets me pair, I don't get any prompt. Can connect all day long though
pi@raspberrypi:~ $ bluetoothctl connect D8:71:4D:6C:E2:B4 Attempting to connect to D8:71:4D:6C:E2:B4 [CHG] Device D8:71:4D:6C:E2:B4 Connected: yes Connection successful
Run 'bluetoothctl' on it's own so it is in interactive mode and run the 'connect' again - once it connects the prompt should change to [Flymo 500] or similair - then issue the 'info D8:71:4D:6C:E2:B4' command - if 'Connected' stays it should say it is paired as well.
Tried that, seems to work but doesn't say paired
pi@raspberrypi:~ $ bluetoothctl
Agent registered
[bluetooth]# connect D8:71:4D:6C:E2:B4
Attempting to connect to D8:71:4D:6C:E2:B4
[CHG] Device D8:71:4D:6C:E2:B4 Connected: yes
Connection successful
[CHG] Device D8:71:4D:6C:E2:B4 ServicesResolved: yes
[EasiLife GO 250]# info
Device D8:71:4D:6C:E2:B4 (public)
Name: EasiLife GO 250
Alias: EasiLife GO 250
Paired: no
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
@esticle
I cannot however make any heads-or-tails of where the equivelent of 0x5D79A190 factors in here
You've snipped off the ConnectRequest from the start of the log! Scroll up a bit. Your log starts at EnterOperatorPinRequest but that gets sent after the connection is initialised. Search for ConnectRequest in the log file. As shown from my code above, the sequence is:
If gatttool is a no-go and makes the conversion hard Python is probably the way to go although I have no idea of where to begin with replacing yours with ble_packet_interface - darn, more questions than answers now! :)
You may be able to use gatttool, but the problem you're going to encounter is that a channel ID is generated by the lawnmower when you connect which needs to be put into future messages to get the lawnmower to respond. This channel ID is included in two CRCs, so you'll need to use some sort of programming to incorporate the channel ID and to calculate the CRCs.
@totalitarian
If I recall correctly, you need to bond within the first 3 minutes of the lawnmower being turned on. Are you restarting the lawnmower before attempting to connect? You should be able to use paired-devices to see the device if you've paired it correctly.
Tried that, seems to work but doesn't say paired
I assume you get the same within bluetoothctl in interactive mode if you do 'pair MAC' followed by 'connect MAC' and then the 'info' ? All within 3 minutes of power-on as mentioned as step 2 in the documentation.
Thanks @tgillbe
You've snipped off the ConnectRequest from the start of the log! Scroll up a bit. Your log starts at EnterOperatorPinRequest but that gets sent after the connection is initialised. Search for ConnectRequest in the log file. As shown from my code above, the sequence is:
Thanks for spelling it out - I think I fished them out from the previous test on Android...
- ConnectRequest
04-11 12:48:10.046 3756 3756 D AutomowerLinkedProtocol: com.husqvarnagroup.dss.amc.blelib.bluetooth.hcp.linkmanagercommands.LinkManagerCommands$ConnectRequest@8a7a1dc
04-11 12:48:10.046 3756 3756 D AutomowerLinkedProtocol: Parameter [name=linkId, type=uint32, length=0, boolValue=null, intValue=null, longValue=432130444, stringValue=null, dataValue=null]
04-11 12:48:10.046 3756 3756 D AutomowerLinkedProtocol: Parameter [name=nodeType, type=uint32, length=0, boolValue=null, intValue=null, longValue=0, stringValue=null, dataValue=null]
04-11 12:48:10.046 3756 3756 D AutomowerLinkedProtocol: Parameter [name=name, type=ascii, length=0, boolValue=null, intValue=null, longValue=null, stringValue=Main, dataValue=null]
04-11 12:48:10.047 3756 3857 V Sending:: 02 FD 16 00 00 00 00 00 00 2E 14 8C C9 C1 19 00 00 00 00 4D
04-11 12:48:10.049 3756 3773 V Data written:: 02 FD 16 00 00 00 00 00 00 2E 14 8C C9 C1 19 00 00 00 00 4D
04-11 12:48:10.049 3756 3857 V Sending:: 61 69 6E 00 15 03
04-11 12:48:10.049 8148 9819 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:10.050 3756 3773 V Data written:: 61 69 6E 00 15 03
04-11 12:48:10.378 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 0D 00 00 00 00 00 00 63 15 8C C9 C1 19 C9 03
04-11 12:48:10.379 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:10.379 3756 3756 D AutomowerLinkedProtocol: com.husqvarnagroup.dss.amc.blelib.bluetooth.hcp.linkmanagercommands.LinkManagerCommands$ConnectResponse@d33d1ba
04-11 12:48:10.379 3756 3756 D AutomowerLinkedProtocol: Parameter [name=responseId, type=uint8, length=0, boolValue=null, intValue=21, longValue=null, stringValue=null, dataValue=null]
04-11 12:48:10.379 3756 3756 D AutomowerLinkedProtocol: Parameter [name=newLinkId, type=uint32, length=0, boolValue=null, intValue=null, longValue=432130444, stringValue=null, dataValue=null]
04-11 12:48:10.379 8148 9819 I BluetoothAdapterService: getActiveDevices: A2dp device: null
04-11 12:48:10.380 3756 3756 D AutomowerLinkedProtocol: Sending
- SetProtocolVersionRequest
04-11 12:48:10.380 3756 3756 D AutomowerLinkedProtocol: com.husqvarnagroup.dss.amc.blelib.bluetooth.hcp.linkmanagercommands.LinkManagerCommands$SetProtocolVersionRequest@8d3286b
04-11 12:48:10.380 3756 3756 D AutomowerLinkedProtocol: Parameter [name=protocol, type=uint8, length=0, boolValue=null, intValue=1, longValue=null, stringValue=null, dataValue=null]
04-11 12:48:10.381 3756 3857 V Sending:: 02 FD 0A 00 8C C9 C1 19 00 36 08 01 28 03
04-11 12:48:10.382 8148 1239 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:10.382 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:10.382 3756 3773 V Data written:: 02 FD 0A 00 8C C9 C1 19 00 36 08 01 28 03
- EnterOperatorPinRequest
04-11 12:48:11.090 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$EnterOperatorPinRequest@9f9e047
04-11 12:48:11.090 3756 3756 D AutomowerLinkedProtocol: Parameter [name=pin, type=uint16, length=0, boolValue=null, intValue=3333, longValue=null, stringValue=null, dataValue=null]
04-11 12:48:11.091 3756 3857 V Sending:: 02 FD 12 00 8C C9 C1 19 01 62 00 AF 38 12 04 00 02 00 05 0D
04-11 12:48:11.092 8148 8982 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:11.092 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:11.092 3756 3773 V Data written:: 02 FD 12 00 8C C9 C1 19 01 62 00 AF 38 12 04 00 02 00 05 0D
04-11 12:48:11.092 3756 3857 V Sending:: 44 03
04-11 12:48:11.093 8148 8982 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:11.093 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:11.093 3756 3773 V Data written:: 44 03
04-11 12:48:12.185 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 38 12 04 00 00 00 00 AB
04-11 12:48:12.185 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$EnterOperatorPinResponse@731c99d
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: Sending
- IsOperatorLoggedInRequest
04-11 12:48:11.090 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$EnterOperatorPinRequest@9f9e047
04-11 12:48:11.090 3756 3756 D AutomowerLinkedProtocol: Parameter [name=pin, type=uint16, length=0, boolValue=null, intValue=3333, longValue=null, stringValue=null, dataValue=null]
04-11 12:48:11.091 3756 3857 V Sending:: 02 FD 12 00 8C C9 C1 19 01 62 00 AF 38 12 04 00 02 00 05 0D
04-11 12:48:11.092 8148 8982 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:11.092 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:11.092 3756 3773 V Data written:: 02 FD 12 00 8C C9 C1 19 01 62 00 AF 38 12 04 00 02 00 05 0D
04-11 12:48:11.092 3756 3857 V Sending:: 44 03
04-11 12:48:11.093 8148 8982 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:11.093 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:11.093 3756 3773 V Data written:: 44 03
04-11 12:48:12.185 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 38 12 04 00 00 00 00 AB
04-11 12:48:12.185 3756 3774 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.AuthenticationCommands$EnterOperatorPinResponse@731c99d
04-11 12:48:12.185 3756 3756 D AutomowerLinkedProtocol: Sending
I then see some others, like KeepAliveRequest:
04-11 12:48:12.436 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.436 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@10cd059
04-11 12:48:12.436 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.438 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.439 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.440 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.611 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 42 12 02 00 00 00 00 6F
04-11 12:48:12.611 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveResponse@9c21434
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.613 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@e02a25d
04-11 12:48:12.614 3756 3857 V Sending:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.615 8148 8161 D BtGatt.GattService: writeCharacteristic() - trying to acquire permit.
04-11 12:48:12.615 8148 8182 D BtGatt.GattService: onWriteCharacteristic() - increasing permit for address=60:98:66:EF:61:F0
04-11 12:48:12.616 3756 3773 V Data written:: 02 FD 10 00 8C C9 C1 19 01 18 00 AF 42 12 02 00 00 00 D9 03
04-11 12:48:12.708 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 02 FD 11 00 8C C9 C1 19 01 25 01 AF 42 12 02 00 00 00 00 6F
04-11 12:48:12.709 3756 3773 V com.husqvarnagroup.dss.amc.blelib.bluetooth.BleDevice@ed922e5 Received:: 03
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: Received OK Response
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveResponse@585a7d2
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: Sending
04-11 12:48:12.709 3756 3756 D AutomowerLinkedProtocol: com.gardena.libraries.bluetooth_mower.bluetooth_mower.mowerconnection.commands.SystemPowerCommands$KeepAliveRequest@176a0a3
GetBatteryLevelRequest and other niceities!
If gatttool is a no-go and makes the conversion hard Python is probably the way to go although I have no idea of where to begin with replacing yours with ble_packet_interface - darn, more questions than answers now! :)
You may be able to use gatttool, but the problem you're going to encounter is that a channel ID is generated by the lawnmower when you connect which needs to be put into future messages to get the lawnmower to respond. This channel ID is included in two CRCs, so you'll need to use some sort of programming to incorporate the channel ID and to calculate the CRCs.
In contrast, I don't mind some bash (would have to for the retry-handling anyhow) - so from your packet structure it appears after the IsOperatorLoggedInRequest section that the channelID above was 8C C9 C1 19 ? Need to figure out how to make it spit that out...
If gatttool is a no-go and makes the conversion hard Python is probably the way to go although I have no idea of where to begin with replacing yours with ble_packet_interface - darn, more questions than answers now! :)
You may be able to use gatttool, but the problem you're going to encounter is that a channel ID is generated by the lawnmower when you connect which needs to be put into future messages to get the lawnmower to respond. This channel ID is included in two CRCs, so you'll need to use some sort of programming to incorporate the channel ID and to calculate the CRCs.
In contrast, I don't mind some bash (would have to for the retry-handling anyhow) - so from your packet structure it appears after the IsOperatorLoggedInRequest section that the channelID above was 8C C9 C1 19 ? Need to figure out how to make it spit that out...
Good progress! Agreed that your link ID seems to be 8C C9 C1 19 (or 432130444), so you'll need to change that too if you try and use my code. No idea where it gets this from - maybe the app creates it and saves it? There is a CreateLinkRequest packet after all, but I've never seen it sent (didn't log the setup process in the app). I haven't observed it changing the link ID so you could try and just hardcode it.
If you can find a setup which reliably keeps a BLE connection (or can be automatically reconnected without touching the mower) then please let me know! It would be great to get this working. I think I had to restart the mower to get the connection back.
Tried that, seems to work but doesn't say paired
I assume you get the same within bluetoothctl in interactive mode if you do 'pair MAC' followed by 'connect MAC' and then the 'info' ? All within 3 minutes of power-on as mentioned as step 2 in the documentation.
Afraid so. Think i'm going to just fit a contact sensor and motion sensor and be done with it. Good luck, hopefully one day i'll be back to congratulate you both on a home assistant addon :)
Thanks @tgillbe
Good progress! Agreed that your link ID seems to be 8C C9 C1 19 (or 432130444), so you'll need to change that too if you try and use my code. No idea where it gets this from - maybe the app creates it and saves it? There is a CreateLinkRequest packet after all, but I've never seen it sent (didn't log the setup process in the app). I haven't observed it changing the link ID so you could try and just hardcode it.
Somewhat confused as I have replaced all instances of 1568252304 to my 432130444 (and of course the PIN) and having no go at all with your run.py.
I've also had a stab at re-playing my Android version of ConnectRequest with bluetoothctl and not having much luck - does not matter what I write to it, it disconnects immediately.
[bluetooth]# connect 60:98:66:EF:61:F0
Attempting to connect to 60:98:66:EF:61:F0
[CHG] Device 60:98:66:EF:61:F0 Connected: yes
Connection successful
[CHG] Device 60:98:66:EF:61:F0 ServicesResolved: yes
[EasiLife GO 500]# menu gatt
[EasiLife GO 500]# select-attribute 98BD0002-0B0E-421A-84E5-DDBF75DC6DE4
[EasiLife GO 500:/service0009/char000a]# attribute-info
Characteristic - Vendor specific
UUID: 98bd0002-0b0e-421a-84e5-ddbf75dc6de4
Service: /org/bluez/hci0/dev_60_98_66_EF_61_F0/service0009
Flags: write-without-response
[EasiLife GO 500:/service0009/char000a]# write "0x02 0xFD 0x16 0x00 0x00 0x00 0x00 0x00 0x00 0x2E 0x14 0x8C 0xC9 0xC1 0x19 0x00 0x00 0x00 0x00 0x4D"
Attempting to write /org/bluez/hci0/dev_60_98_66_EF_61_F0/service0009/char000a
[CHG] Device 60:98:66:EF:61:F0 ServicesResolved: no
[CHG] Device 60:98:66:EF:61:F0 Connected: no
[bluetooth]#
No different with the integer version or if I inject my 8C C9 C1 19 as the channelID, so hoping it's something obvious - however thought your script would give something up now too! :)
If you can find a setup which reliably keeps a BLE connection (or can be automatically reconnected without touching the mower) then please let me know! It would be great to get this working. I think I had to restart the mower to get the connection back.
With bt-agent described above I can (with some retries) get the paired/trusted/connected flags all to 'yes' without touching the mower - it seems to disconnect about ~60 seconds after the 'info' command below so maybe it does that KeepAlive stuff we saw every few seconds in a real connection...
esticle@bluepi:~/flymo2mqtt $ bluetoothctl
Agent registered
[bluetooth]# connect 60:98:66:EF:61:F0
Attempting to connect to 60:98:66:EF:61:F0
Failed to connect: org.bluez.Error.Failed
[bluetooth]# connect 60:98:66:EF:61:F0
Attempting to connect to 60:98:66:EF:61:F0
[CHG] Device 60:98:66:EF:61:F0 Connected: yes
Failed to connect: org.bluez.Error.Failed
[CHG] Device 60:98:66:EF:61:F0 Connected: no
[bluetooth]# connect 60:98:66:EF:61:F0
Attempting to connect to 60:98:66:EF:61:F0
[CHG] Device 60:98:66:EF:61:F0 Connected: yes
Connection successful
[CHG] Device 60:98:66:EF:61:F0 ServicesResolved: yes
[EasiLife GO 500]# info
Device 60:98:66:EF:61:F0 (public)
Name: EasiLife GO 500
Alias: EasiLife GO 500
Paired: yes
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (98bd0001-0b0e-421a-84e5-ddbf75dc6de4)
[bluetooth]#
...1 min later...
[CHG] Device 60:98:66:EF:61:F0 ServicesResolved: no
[CHG] Device 60:98:66:EF:61:F0 Connected: no
[bluetooth]#
How are you calculating the channel id? I think mine is fab8276b
Hi
Thanks so much for posting this, are you still using it yourself, is it working well ? I have a Flymo Easilife Go 150, and would love to get this working, but not exactly sure where to start (a bit of an idiots guide if poss) ?
it looks like I start here.. https://github.com/shmuelzon/esp32-ble2mqtt and get this set up ?