BLE Name: YXlinksSPP
Service UUID: 0000ffb0-0000-1000-8000-00805f9b34fb
Tx Cha…racteristic UUID: 0000ffb1-0000-1000-8000-00805f9b34fb
Rx Characteristic UUID: 0000ffb2-0000-1000-8000-00805f9b34fb
Device is a positional belt driven linear actuator:
* 9 oscillation patterns (speed and range controllable)
* Programmable sequences
* On-demand movements
Pattern mode:
* Initialisation: `01 06 00 64 00 00 CRC16`
* On: `01 06 00 65 00 01 CRC16`
* Off: `01 06 00 65 00 00 CRC16`
* Speed up: `01 06 00 66 00 02 CRC16`
* Speed down: `01 06 00 66 00 01 CRC16`
* Range up: `01 06 00 67 00 02 CRC16`
* Range down: `01 06 00 67 00 01 CRC16`
* Pattern select `01 06 00 68 00 0X CRC16` (X 1-9 pattern number)
Free mode:
* Initialisation: `01 06 00 64 00 02 CRC16`
* Move: `01 06 00 A7 XX YY CRC16` (XX YY position 16-bit hex value which seems to max out at 225 but app sends 0-100, like 0x00 0x99 for 99, in decimal, like 0x00 0x99 for 99, which I bet this is a bug in their app)
Program mode:
* Initialisation: `01 06 00 64 00 01 CRC16`
* Play: `01 06 00 69 00 01 CRC16`
* Program: `01 06 00 69 00 00 CRC16`
* Loop: `01 06 00 6a 00 01 CRC16`/ `01 06 00 6a 00 00 CRC16`
* Set phase:
At this point some of the protocol became clearer (or so I though, since the data doesn't match my assertions):
* All messages start 0x01
* The second byte is the message length, until now always 6
* The 3rd/4th bytes are the command or storage location (programs are stored on 6B+3N)
* `01 10 00 6B 00 05 0a [speed out] [speed in] [position in] [position out] [repeat count] CRC16`
Turns out that if you initialise the program with:
* `01 06 00 64 00 01 CRC16`: Set to program mode
* `01 06 00 69 00 00 CRC16`: Set to record state
* `01 10 00 6b 00 05 0a 00 05 00 05 00 00 00 00 00 01 CRC16`: Set the first oscillation pattern to move to 0 and stay
* `01 06 00 69 00 01 CRC16`: Run the program
* `01 06 00 6a 00 01 CRC16`: Enable loop
You can then send follow-up position/speeds by just sending:
* `01 10 00 6b 00 05 0a 00 05 00 05 00 90 00 90 00 01 CRC16`: Move to 144 at speed 5
```javascript
_auchCRCHi = [0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64, 0, 193, 129, 64, 1, 192, 128, 65, 0, 193, 129, 64, 1, 192, 128, 65, 1, 192, 128, 65, 0, 193, 129, 64];
_auchCRCLo = [0, 192, 193, 1, 195, 3, 2, 194, 198, 6, 7, 199, 5, 197, 196, 4, 204, 12, 13, 205, 15, 207, 206, 14, 10, 202, 203, 11, 201, 9, 8, 200, 216, 24, 25, 217, 27, 219, 218, 26, 30, 222, 223, 31, 221, 29, 28, 220, 20, 212, 213, 21, 215, 23, 22, 214, 210, 18, 19, 211, 17, 209, 208, 16, 240, 48, 49, 241, 51, 243, 242, 50, 54, 246, 247, 55, 245, 53, 52, 244, 60, 252, 253, 61, 255, 63, 62, 254, 250, 58, 59, 251, 57, 249, 248, 56, 40, 232, 233, 41, 235, 43, 42, 234, 238, 46, 47, 239, 45, 237, 236, 44, 228, 36, 37, 229, 39, 231, 230, 38, 34, 226, 227, 35, 225, 33, 32, 224, 160, 96, 97, 161, 99, 163, 162, 98, 102, 166, 167, 103, 165, 101, 100, 164, 108, 172, 173, 109, 175, 111, 110, 174, 170, 106, 107, 171, 105, 169, 168, 104, 120, 184, 185, 121, 187, 123, 122, 186, 190, 126, 127, 191, 125, 189, 188, 124, 180, 116, 117, 181, 119, 183, 182, 118, 114, 178, 179, 115, 177, 113, 112, 176, 80, 144, 145, 81, 147, 83, 82, 146, 150, 86, 87, 151, 85, 149, 148, 84, 156, 92, 93, 157, 95, 159, 158, 94, 90, 154, 155, 91, 153, 89, 88, 152, 136, 72, 73, 137, 75, 139, 138, 74, 78, 142, 143, 79, 141, 77, 76, 140, 68, 132, 133, 69, 135, 71, 70, 134, 130, 66, 67, 131, 65, 129, 128, 64];
function padLeft(e, t, n) {
void 0 == n && (n = "0");
for (var o = 0, i = t - e.length; o < i; o++) {
e = n + e;
}
return e;
}
function CRC16(t) {
for (var n = 255, o = 255, i = 0; i < t.length; i++) {
var a = n ^ t[i];
n = o ^ e._auchCRCHi[a];
o = e._auchCRCLo[a]
}
return [n, o];
}
```