The Tilt Hydrometer is a submersible bluetooth thermometer and hydrometer for monitoring fermentation. This post details how to get raw iBeacon messages on linux and analyses the Tilt Hydrometer message format.
Bluetooth support on linux is provided via bluez. Two bluez tools hcitool
and hcidump
are used to get bluetooth data for processing. hcitool lescan
initiates a scan for bluetooth LE devices, and hcidump
run simultaneously will give you detail on the messages being exhanged. hcidump -R
will dump raw bluetooth data as octets to stdout.
Before proceeding further, it’s probably a good idea to run sudo hcitool lescan
and see if your Tilt Hydrometer (named ‘Tilt’) shows up. If you can’t see it you may need to enable experimental mode in bluez to turn on bluetooth LE. Edit /lib/systemd/system/bluetooth.service
and append --experimental
to the ExecStart
line. Then run sudo systemctl daemon-reload
and sudo systemctl restart bluetooth
. See [2] for more info.
If you want to run hcitool
and hcidump
as a normal user, grant the appropriate capabilites to the executables. Note this may have security implications [3].
sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hcitool`
sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hciconfig`
The Tilt Hydrometer is a Bluetooth LE device that reports data via the iBeacon protocol. As far as I can tell, the tilt transmits two data messages. The first type is in response to a scan initiated by a device, and doesn’t contain any sensor data. The second type is a message containing temperature and specific gravity.
Example tilt hydrometer sensor data message from hcidump -R
:
> 04 3E 27 02 01 00 00 5A 09 9B 16 A3 04 1B 1A FF 4C 00 02 15
A4 95 BB 10 C5 B1 4B 44 B5 12 13 70 F0 2D 74 DE 00 44 03 F8
C5 C7
Explanation (with help from the bluetooth core spec and stackoverflow [4] [5] [6]):
04: HCI Packet Type HCI Event
3E: LE Meta event
27: Parameter total length (39 octets)
02: LE Advertising report sub-event
01: Number of reports (1)
00: Event type connectable and scannable undirected advertising
00: Public address type
5A: address
09: address
9B: address
16: address
A3: address
04: address
1B: length of data field (27 octets)
1A: length of first advertising data (AD) structure (26)
FF: type of first AD structure - manufacturer specific data
4C: manufacturer ID - Apple iBeacon
00: manufacturer ID - Apple iBeacon
02: type (constant, defined by iBeacon spec)
15: length (constant, defined by iBeacon spec)
A4: device UUID
95: device UUID
BB: device UUID
10: device UUID
C5: device UUID
B1: device UUID
4B: device UUID
44: device UUID
B5: device UUID
12: device UUID
13: device UUID
70: device UUID
F0: device UUID
2D: device UUID
74: device UUID
DE: device UUID
00: major - temperature (in degrees fahrenheit)
44: major - temperature (in degress fahrenheit)
03: minor - specific gravity (x1000)
F8: minor - specific gravity (x1000)
C5: TX power in dBm
C7: RSSI in dBm
The UUID of the Tilt Hydrometer is shared between devices of that colour. The list is as follows [7]:
Red: A495BB10C5B14B44B5121370F02D74DE
Green: A495BB20C5B14B44B5121370F02D74DE
Black: A495BB30C5B14B44B5121370F02D74DE
Purple: A495BB40C5B14B44B5121370F02D74DE
Orange: A495BB50C5B14B44B5121370F02D74DE
Blue: A495BB60C5B14B44B5121370F02D74DE
Yellow: A495BB70C5B14B44B5121370F02D74DE
Pink: A495BB80C5B14B44B5121370F02D74DE
The temperature in degrees fahrenheit (‘major’ field of iBeacon data) is a 16 bit unsigned integer, most significant bits first (big endian). For the message above the temperature is 68ºF.
The specific gravity x 1000 (‘minor’ field of iBeacon data) is a 16 bit unsigned integer, most significant bits first (big endian). Divide by 1000 to get the specific gravity. For the message above the gravity is 1.016.
The TX power in dBm is a signed 8 bit integer. (-59dBm above)