Hello guys
My name is Jose, from Spain, I’m new to the forum.
I stumbled upon this thread, a few days ago, searching for a way to hack read Blue Connect device measurements via Bluetooth LE on demand. I bought a Blue Connect Go, that measures Temperature, PH and ORP.
I found a couple of posts in this thread crucial for reaching my goal:
- vampcp - Oct 18,2021 - Some example for RAW data and corresponding values from the cloud:
23ab093207ab0a7800240e
"salinity":4.9,"conductivity":8742,"temperature":24.8,"ph":7.93,"orp":685
[...]
2 more samples
- vampcp - Oct 28,2021 - This is how I managed to get the raw values from the device
blueClient.enableNotifications(blue_device, BLUE_TAKE_MEASURE_SERVICE)
blueClient.setNotificationCallback(myNotificationCallback)
blueClient.**requestMeasurements**(BLUE_REQUEST_SENSOR_DATA)
Plus a third hint:
- This GitHub page, more concise about triggering a measurement:
https://githubhelp.com/myhomeiot/esphome-components/issues/8
UUID F3300002-FOA2-9B06-0C59-1BC4763B5C00 is the one that I write TRUE / 0x01 to and then I get the answer notified on F3300003-F0A2-9B06-0C59-1BC4763B5C00
Ok, so I first tried to decode myself the samples provided by vampcp, for example this one:
Cloud value set 1:
"salinity":4.9,"conductivity":8742,"temperature":24.8,"ph":7.93,"orp":685
23 ab 09 32 07 ab 0a 78 00 24 0e
^^-^^---------------------------- TEMP 0x09ab = 2475 / 100 = 24.75 ºC <-- OK
^^-^^---------------------- PH 0x0732 = 1842 / 7.93 = K 232.28
^^-^^---------------- ORP 0x0aab = 2731 / 4 = 682.75 mV <-- MOSTLY OK
For the TEMPerature, as mentioned earlier in this thread, the hex values [ab 09], represent the integer number 0x09ab = 2475 (little-endian, actually, first byte = least significant byte). Divide it by 100 and you get the temperature in degrees celsius with 0.01 ºC resolution. The App shows this with just 1 decimal place.
For the ORP, I found a similar approach. Just divide the raw value by 4 and you get the actual ORP with 0.25 mV resolution. The App shows this discarding the decimal part.
The PH was tricky, though. At first I thought there was also a linear direct relationship. With the given 3 samples, one could think of a value like K = 232.28 which was great to PH = 0x0732 / 232.28 = 7.93. As soon as I tried to use that constant with my samples around PH 7, it was a big NOK:
BLE Scanner: 23 a9 0b ff 07 aa 08 01 00 25 0e -- App: "29.8 ºC", "7.0", "554 mV"
23 a9 0b ff 07 aa 08 01 00 25 0e
^^-^^---------------------------- TEMP 0x0ba9 = 2985 / 100 = 29.85 ºC <-- OK
^^-^^---------------------- PH 0x07ff = 2047 / K 232 = 8.82 <-- *** NOK ***
^^-^^---------------- ORP 0x08aa = 2218 / 4 = 554.50 mV <-- OK
Uhmmm! K=232 seems a twisted value. I would have expected something like K=200 or K=256.
Then I noticed what seemed to be a negative linear relationship between the PH raw and cooked values. See vampcp’s readings, sorted by PH:
23ab093407980a7b00240e - 0x0734 -> "ph":7.92
23ab093207ab0a7800240e - 0x0732 -> "ph":7.93
23a6093007b70a78001e0e - 0x0730 -> "ph":7.94
Here, an increase of 0x0002 gives you a decrease of 0.01 in the cooked value, so there must be some negative 1/200 -ish constant in the formula. As we’ll see later on, I got values very close to 0x0800 for PH 7.0 (neutral PH, center value of the 0-14 PH scale). What if we then just needed to apply the proper K value? Let’s find out, please keep reading!
I’ve been taking samples during the last couple of days, several times during the day. I used both BLE Scanner on my iPhone to get the raw values and the BlueConnect App to get the cooked values.
Note: for this, I take a sample with BLE Scanner, giving me the raw value (take a screenshot), disconnect and then take a new sample with the BlueConnect App, giving me the cooked values (take another screenshot). So, there’s a slight delay between samples and their values may vary slightly
Note 2: Alternatively, you can use the ‘gatttool’ tool that comes with Linux’ bluetooth package. I happen to have a Raspberry Pi near the pool that I can use for that. A reading can be taken as follows:
$ gatttool -b 00:A0:50:XX:XX:XX --char-write-req --handle=0x0014 --value=0100 --char-write-req --handle=0x0012 --value=01 --listen
Characteristic value was written successfully
[...takes about 8 seconds]
Notification handle = 0x0014 value: 23 77 0b fc 07 48 08 01 00 1f 0e
…and we get the raw values.
(you can prepend ‘timeout 60’ to the ‘gattool’ command to let it not wait for notifications forever)
(here handle 0x0012 corresponds to characteristic ‘F3300002’ and handle 0x0014 to ‘F3300003’. First we enable notifications on the second one, then we send the ‘start measurement’ command to the first one)
With the BLE Scanner, you write the value 01 to the characteristic ‘F3300002’ and after 8 seconds, the raw measurement value will be notified to the characteristic ‘F3300003’:
So, here go some values for PH ranging from 7.0 to 8.1:
BLE Scanner: 23 a9 0b ff 07 aa 08 01 00 25 0e -- App: "29.8 ºC", "7.0", "554 mV"
23 a9 0b ff 07 aa 08 01 00 25 0e
^^-^^---------------------------- TEMP 0x0ba9 = 2985 / 100 = 29.85 ºC <-- OK
^^-^^---------------------- PH 0x07ff
BLE Scanner: 23 18 0b 7f 07 0d 0a 00 00 2b 0e -- App: "28.4 ºC", "7.6", "645 mV"
23 18 0b 7f 07 0d 0a 00 00 2b 0e
^^-^^---------------------------- TEMP 0x0b18 = 2840 / 100 = 28.40 ºC <-- OK
^^-^^---------------------- PH 0x077f
BLE Scanner: 23 91 0a 13 07 44 09 01 00 27 0e -- App: "27.0 ºC", "8.0", "592 mV"
23 91 0a 13 07 44 09 01 00 27 0e
^^-^^---------------------------- TEMP 0x0a91 = 2705 / 100 = 27.05 ºC <-- OK
^^-^^---------------------- PH 0x0713
BLE Scanner: 23 04 0b 01 07 e7 09 00 00 26 0e -- App: "28.2 ºC", "8.1", "632 mV"
23 04 0b 01 07 e7 09 00 00 26 0e
^^-^^---------------------------- TEMP 0x0b04 = 2820 / 100 = 28.20 ºC <-- OK
^^-^^---------------------- PH 0x0701
As I suspected, 0x07ff (or 0x0800, for the case) seems to correspond to PH 7.0, going down to 0x0713 for PH 8.0, so we could assume the slope constant may be something like:
K = (0x0800 - 0x0713) / (7.0 - 8.0) = -237
Playing a bit with the several PH values around 7.0 and 8.0, and several values of K, I find K = 232 gets me the ‘most rated OK’ results for all my tested cases:
BLE Scanner: 23 a9 0b ff 07 aa 08 01 00 25 0e -- App: "29.8 ºC", "7.0", "554 mV"
23 a9 0b ff 07 aa 08 01 00 25 0e
^^-^^---------------------------- TEMP 0x0ba9 = 2985 / 100 = 29.85 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x07ff) / 224 + 7 = 7.0045 <-- OK *
^^-^^---------------------- PH (0x0800 - 0x07ff) / 232 + 7 = 7.0043 <-- OK **
^^-^^---------------------- PH (0x0800 - 0x07ff) / 240 + 7 = 7.0042 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x07ff) / 248 + 7 = 7.0040 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x07ff) / 256 + 7 = 7.0039 <-- OK *****
BLE Scanner: 23 72 0b fd 07 3f 08 01 00 1f 0e -- App: "29.3 ºC", "7.0", "523 mV"
23 72 0b fd 07 3f 08 01 00 1f 0e
^^-^^---------------------------- TEMP 0x0b72 = 2930 / 100 = 29.30 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x07fd) / 224 + 7 = 7.0134 <-- OK *
^^-^^---------------------- PH (0x0800 - 0x07fd) / 232 + 7 = 7.0129 <-- OK **
^^-^^---------------------- PH (0x0800 - 0x07fd) / 240 + 7 = 7.0125 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x07fd) / 248 + 7 = 7.0121 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x07fd) / 256 + 7 = 7.0117 <-- OK *****
BLE Scanner: 23 18 0b 7f 07 0d 0a 00 00 2b 0e -- App: "28.4 ºC", "7.6", "645 mV"
23 18 0b 7f 07 0d 0a 00 00 2b 0e
^^-^^---------------------------- TEMP 0x0b18 = 2840 / 100 = 28.40 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x077f) / 224 + 7 = 7.5759 <-- OK *****
^^-^^---------------------- PH (0x0800 - 0x077f) / 232 + 7 = 7.5560 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x077f) / 240 + 7 = 7.5375 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x077f) / 248 + 7 = 7.5202 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x077f) / 256 + 7 = 7.5039 <-- NOK
BLE Scanner: 23 dc 0a 7e 07 fa 0a 01 00 1f 0e -- App: "27.8 ºC", "7.6", "701 mV"
23 dc 0a 7e 07 fa 0a 01 00 1f 0e
^^-^^---------------------------- TEMP 0x0adc = 2780 / 100 = 27.80 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x077e) / 224 + 7 = 7.5804 <-- OK *****
^^-^^---------------------- PH (0x0800 - 0x077e) / 232 + 7 = 7.5603 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x077e) / 240 + 7 = 7.5417 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x077e) / 248 + 7 = 7.5242 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x077e) / 256 + 7 = 7.5078 <-- NOK
BLE Scanner: 23 4f 0b 58 07 58 09 00 00 2d 0e -- App: "28.9 ºC", "7.7", "601 mV"
23 4f 0b 58 07 58 09 00 00 2d 0e
^^-^^---------------------------- TEMP 0x0b4f = 2895 / 100 = 28.95 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x0758) / 224 + 7 = 7.7500 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x0758) / 232 + 7 = 7.7241 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x0758) / 240 + 7 = 7.7000 <-- OK ***** nailed it
^^-^^---------------------- PH (0x0800 - 0x0758) / 248 + 7 = 7.6774 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x0758) / 256 + 7 = 7.6563 <-- OK **
BLE Scanner: 23 d7 0a 26 07 a4 09 00 00 27 0e -- App: "27.7 ºC", "7.9", "617 mV"
23 d7 0a 26 07 a4 09 00 00 27 0e
^^-^^---------------------------- TEMP 0x0ad7 = 2775 / 100 = 27.75 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x0726) / 224 + 7 = 7.9732 <-- OK *
^^-^^---------------------- PH (0x0800 - 0x0726) / 232 + 7 = 7.9397 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x0726) / 240 + 7 = 7.9083 <-- OK *****
^^-^^---------------------- PH (0x0800 - 0x0726) / 248 + 7 = 7.8790 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x0726) / 256 + 7 = 7.8516 <-- OK **
BLE Scanner: 23 a5 0a 1e 07 4c 09 00 00 26 0e -- App: "27.2 ºC", "8.0", "594 mV"
23 a5 0a 1e 07 4c 09 00 00 26 0e
^^-^^---------------------------- TEMP 0x0aa5 = 2725 / 100 = 27.25 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x071e) / 224 + 7 = 8.0089 <-- OK *****
^^-^^---------------------- PH (0x0800 - 0x071e) / 232 + 7 = 7.9741 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x071e) / 240 + 7 = 7.9417 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x071e) / 248 + 7 = 7.9113 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x071e) / 256 + 7 = 7.8828 <-- NOK
BLE Scanner: 23 91 0a 13 07 44 09 01 00 27 0e -- App: "27.0 ºC", "8.0", "592 mV"
23 91 0a 13 07 44 09 01 00 27 0e
^^-^^---------------------------- TEMP 0x0a91 = 2705 / 100 = 27.05 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x0713) / 224 + 7 = 8.0580 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x0713) / 232 + 7 = 8.0216 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x0713) / 240 + 7 = 7.9875 <-- OK *****
^^-^^---------------------- PH (0x0800 - 0x0713) / 248 + 7 = 7.9556 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x0713) / 256 + 7 = 7.9258 <-- NOK
BLE Scanner: 23 04 0b 01 07 e7 09 00 00 26 0e -- App: "28.2 ºC", "8.1", "632 mV"
23 04 0b 01 07 e7 09 00 00 26 0e
^^-^^---------------------------- TEMP 0x0b04 = 2820 / 100 = 28.20 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x0701) / 224 + 7 = 8.1384 <-- OK ***
^^-^^---------------------- PH (0x0800 - 0x0701) / 232 + 7 = 8.0991 <-- OK *****
^^-^^---------------------- PH (0x0800 - 0x0701) / 240 + 7 = 8.0625 <-- OK ****
^^-^^---------------------- PH (0x0800 - 0x0701) / 248 + 7 = 8.0282 <-- NOK
^^-^^---------------------- PH (0x0800 - 0x0701) / 256 + 7 = 7.9961 <-- NOK
This calculation may not be the real one they use on their servers and App, but it’s accurate enough for me for values between 7.0 and 8.1, perhaps extrapolable down to 6.0 but no lower. I would need to take a few measurements using the PH 4.0 calibration solution to get raw/cooked values at that point and redo the calculations. Maybe the same constant is still valid down to 4.0, maybe I meed a different constant for the acidic range (7…0), maybe a slightly different constant works for the 4…8 range, who knows.
To end the post, these would be my final dissections:
BLE Scanner: 23 dc 0a 7e 07 fa 0a 01 00 1f 0e -- App: "27.8 ºC", "7.6", "701 mV"
23 dc 0a 7e 07 fa 0a 01 00 1f 0e
^^-^^---------------------------- TEMP 0x0adc = 2780 / 100 = 27.80 ºC <-- OK
^^-^^---------------------- PH (0x0800 - 0x077e) / 232 + 7 = 7.5603 <-- OK, rounds up to 7.6
^^-^^---------------- ORP 0x0afa = 2810 / 4 = 702.50 mV <-- OK, just a millivolt off
^^-^^---------- SAL 0x0001 -- my device does not support it, the App does not show it
^^-^^---- COND 0x0e1f -- same as above
Sorry for the long post, I just wanted to share with you my ramblings and excitement trying to decode the raw data for this device. Hope it has been interesting and useful.
I’m planning on writing a small python script to automate the reading and decoding of the data from the device via BLE, in order to take 1 measurement per hour from a Raspberry Pi that I have near the pool running Raspbian Linux.
Regards
Jose