Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ibbq-thermometer-protocol

Example devices

  • Inkbird IBT-2X
  • Inkbird IBT-4XS
  • EasyBBQ FCCID: FCC ID 2AI4MPRO3 (SHENZHEN HYPERSYNES CO.,LTD Smart Wireless Thermometer PRO3)

Properties

  • @ConnectTimeout: 60 seconds
  • @BatteryPollingInterval: 5 minutes

The iBBQ is a Bluetooth LE Gatt Device

@DeviceName: iBBQ

Standard Descriptor:

  • @ClientCharacteristicConfigurationDescriptor: @uuid16{0x2902}

Its main service at @uuid16{0xfff0} contains the following characteristics:

  • @SettingsResult: @uuid16{0xfff1} @notify returns results from control messages
  • @AccountAndVerify: @uuid16{0xfff2} @write deals with the pairing process
  • @HistoryData: @uuid16{0xfff3} @notify is not yet properly documented
  • @RealtimeData: @uuid16{0xfff4} @notify returns the results from probes
  • @SettingsData: @uuid16{0xfff5} @write is where control messages are sent

Some messages

Here are some hardcoded messages:

  • @CredentialsMessage: (:byte[]) { 0x21, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xb8, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00}
  • @RealtimeDataEnableMessage: (:byte[]) { 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00}
  • @UnitsFahrenheitMessage: (:byte[]) { 0x02, 0x01, 0x00, 0x00, 0x00, 0x00}
  • @UnitsCelsiusMessage: (:byte[]) { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}
  • @RequestBatteryLevelMessage: (:byte[]) { 0x08, 0x24, 0x00, 0x00, 0x00, 0x00 }

A message exists to set target temperatures (low and high, the closest of which will be displayed on the screen)

  • @SetTargetTempMessage: (:byte[]) { 0x01, probe-nr, low[0:7bits], low[8:15bits], high[0:7bits], high[8:15bits] }
    • probe-nr is the probe to select, from 0 onwwards
    • low is a int16 signed integer for the lower temperature, in 10^-1 Celsius
    • high is a int16 signed integer for the higher temperature, in 10^-1 Celsius
initiate-login :: 
  write @CredentialsMessage to characteristic @AccountAndVerify
enable-realtime-data ::
  enable notifications on @ClientCharacteristicConfigurationDescriptor
  write @RealtimeDataEnableMessage to characteristic @SettingsData
set-unit :: Fahrenheit or Celsius
  when Fahrenheit write @UnitsFahrenheitMessage to characteristic @SettingsData
  when Celsius    write @UnitsCelsiusMessage to characteristic @SettingsData
request-battery-level ::
  write @RequestBatteryLevelMessage to characteristic @SettingsData
set-target-temp ::
  write @SetTargetTempMessage to characteristic @SettingsData

When settings are written to @SettingsData, results are received on @SettingsResult

When request-battery-level has been sent, @SettingsResult will receive data which can be parsed as:

struct BatteryLevels {
  header: uint8 = data[0], // header == 0x24
  currentVoltage: uint16 = data[1] | data[2] << 8, // up to maxVoltage
  maxVoltage: uint16 = data[3] | data[4] << 8, // if 0 maxVoltage is 6550
}

When enable-realtime-data has been sent, @RealtimeData will receive data which can be parsed as:

  num_probes = sizeof(data)/sizeof(uint16)
  probes: uint16[num_probes]
  with 0 < i < num_probes:  
    probes[i] : uint16 = data[2*i] | data[2*i + 1] << 8

There's an history data end-point, but the format is unknown.

Alarm
  • Device: IBT-4XS
  • @SilenceAlarmMessage: (:byte[]) { 0x04, 0xff, 0x00, 0x00, 0x00, 0x00 }

Device alarm can be silenced by sending @SilenceAlarmMessage to the @SettingsData characteristic.

When an alarm is silenced by the user pressing the device's button, @SilenceAlarmMessage is received on @SettingsResult

@pmn1966

This comment has been minimized.

Copy link

@pmn1966 pmn1966 commented Jun 9, 2020

Is there anything special to do to receive data on FFF0/FFF4 and FFF0/FFF1 ?
I dont receive any data on these two. All others are working fine. eg. 1800/2A00.

I can change from °C to °F, but i cant read any responce for e.g. Barttery on FFF0/FFF1 and probe data on FFF0/FFF4.

(by the way im using Labview BLE toolkit)

Br

@uucidl

This comment has been minimized.

Copy link
Owner Author

@uucidl uucidl commented Jun 9, 2020

The device is very strict, you need to follow the procedure of sending initiate-login and then enable-realtime-data

I have a working Android App that tracks temperature but the android API is really bad and hard to use as reference. It's not on github for that reason.

However I remember there's a go project that exists out there which is very easy to read:

https://github.com/sworisbreathing/go-ibbq/blob/master/ibbq.go

@p1ng0o

This comment has been minimized.

Copy link

@p1ng0o p1ng0o commented Jun 24, 2020

Same here, sending initiate login seems to keep the connexion open, but I didn't receive realtime data at all.
I have a 6 channel device.

@pmn1966

This comment has been minimized.

Copy link

@pmn1966 pmn1966 commented Jun 24, 2020

@p1ng0o

I found the solution:

You need to subscribe to the probe data by sending x0001 to FFF0/FFF4
To unsubscribe send x0000 to FFF0/FFF4

For Control Message e.g. Battery level subscribe by sending x0001 to FFF0/FFF1
To unsubscribe send x0000 to FFF0/FFF1

Let me know if you manage to figure it out.
I made a Labview program that show the probe temperatures and the Battery level :-)
Capture

@p1ng0o

This comment has been minimized.

Copy link

@p1ng0o p1ng0o commented Jun 24, 2020

Ok, fixed.

the client caracteristics configuration descriptior has to be configured in order to read the data.

Writing 0x0100 in 0x2902 let me received notifications.

Thanks

@uucidl

This comment has been minimized.

Copy link
Owner Author

@uucidl uucidl commented Jun 27, 2020

Yes indeed, I did not document that because I understood this as standard bluetooth le!

@non-programmer

This comment has been minimized.

Copy link

@non-programmer non-programmer commented Jul 20, 2020

I would like to ask you for help with the iBBQ thermometer.
I'm trying to use HM-10 BLE 4.0 serial module to connect to the iBBQ and read temperature.
What is the actual code sent when you say "writing 0x0100 in 0x2902" or
"CredentialsMessage: (:byte[]) { 0x21, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xb8, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00}
to AccountAndVerify: @uuid16{0xfff2}"
I don't use Arduino, I don't know C-language. I need to see the actual HEX numbers sent in the order they are sent including any hidden commands sent by compiler.
I'm a non programmer. My programming comes down to copy and paste or monkey see monkey do.

@non-programmer

This comment has been minimized.

Copy link

@non-programmer non-programmer commented Jul 21, 2020

My question may not be as clear as I think. I can connect to BBQ thermometer from HM-10 BLE 4.0
After the OK+CONN message I need to send the verification and notification characteristics and that's the part I can't figure out.
In simple term I need to specify I want to send data 0x100 to address 0x2902.
I would like to see the byte stream that has to be sent. Can you help? Thanks.

@july1206

This comment has been minimized.

Copy link

@july1206 july1206 commented Sep 13, 2020

Hi.
Evry time I try to start I receive this error:
pls little bit of help?
Tnx!

sudo LOGXI=main=INF ./datalogger
14:09:45.913929 FTL main Error creating iBBQ
err: can't init hci: no devices available: (hci0: can't down device: device or resource busy)
goroutine 1 [running]:
runtime..z2fdebug.Stack
../../../src/libgo/go/runtime/debug/stack.go:24
github.com..z2fmgutz..z2flogxi..z2fv1.HappyDevFormatter.getLevelContext
/home/io/go/pkg/mod/github.com/mgutz/logxi@v0.0.0-20161027140823-aebf8a7d67ab/v1/happyDevFormatter.go:223
github.com..z2fmgutz..z2flogxi..z2fv1.HappyDevFormatter.Format
/home/io/go/pkg/mod/github.com/mgutz/logxi@v0.0.0-20161027140823-aebf8a7d67ab/v1/happyDevFormatter.go:307
github.com..z2fmgutz..z2flogxi..z2fv1.DefaultLogger.Log
/home/io/go/pkg/mod/github.com/mgutz/logxi@v0.0.0-20161027140823-aebf8a7d67ab/v1/defaultLogger.go:117
github.com..z2fmgutz..z2flogxi..z2fv1.DefaultLogger.extractLogError
/home/io/go/pkg/mod/github.com/mgutz/logxi@v0.0.0-20161027140823-aebf8a7d67ab/v1/defaultLogger.go:98
github.com..z2fmgutz..z2flogxi..z2fv1.DefaultLogger.Fatal
/home/io/go/pkg/mod/github.com/mgutz/logxi@v0.0.0-20161027140823-aebf8a7d67ab/v1/defaultLogger.go:107
main.main
/home/io/Downloads/go-ibbq-master/examples/datalogger/main.go:64

panic: Exit due to fatal error:

goroutine 1 [running]:
github.com..z2fmgutz..z2flogxi..z2fv1.DefaultLogger.Fatal
/home/io/go/pkg/mod/github.com/mgutz/logxi@v0.0.0-20161027140823-aebf8a7d67ab/v1/defaultLogger.go:109
main.main
/home/io/Downloads/go-ibbq-master/examples/datalogger/main.go:64

@uucidl

This comment has been minimized.

Copy link
Owner Author

@uucidl uucidl commented Sep 13, 2020

Hi.
Evry time I try to start I receive this error:
pls little bit of help?
Tnx!

sudo LOGXI=main=INF ./datalogger
14:09:45.913929 FTL main Error creating iBBQ
err: can't init hci: no devices available: (hci0: can't down device: device or resource busy)
goroutine 1 [running]:

Hi. Your question should be directed at the source project, not here. See https://github.com/sworisbreathing/go-ibbq

@p1ng0o

This comment has been minimized.

Copy link

@p1ng0o p1ng0o commented Nov 7, 2020

Hi, is someone have more informations regarding SetTargetTempMessage ?
I would like to:

  • Reset the target temp
  • Set only a target to reach, not a zone
@SerpikoIT

This comment has been minimized.

Copy link

@SerpikoIT SerpikoIT commented Dec 3, 2020

hi I also have an Inkbird IBT-2X and I would like to read the temperatures online from a site or app from my mobile, is it possible ???

@qwandor

This comment has been minimized.

Copy link

@qwandor qwandor commented Jan 9, 2021

Has anyone had any luck figuring out how SetTargetTemp works? It doesn't seem to work for me if I pass a value higher than 360 (36°) for the second temperature, and I haven't figured out how the first one works.

@qwandor

This comment has been minimized.

Copy link

@qwandor qwandor commented Jan 10, 2021

Okay, answering my own question:

The second byte of the SetTargetTemp message is the probe number, counting from 0.

Bytes 3-4 are the lower end of the target temperature range, as a little-endian signed integer of the temperature in degrees Celcius multiplied by 10. If just a single target temperature is desired then -3000 is passed (i.e. -300°C).
Bytes 5-6 are the top end of the target temperature range, encoded in the same way.
The screen of the device will display whichever end of the range is closest to the current temperature, hence my earlier confusion.

@uucidl

This comment has been minimized.

Copy link
Owner Author

@uucidl uucidl commented Jan 10, 2021

Okay, answering my own question:

The second byte of the SetTargetTemp message is the probe number, counting from 0.

Bytes 3-4 are the lower end of the target temperature range, as a little-endian signed integer of the temperature in degrees Celcius multiplied by 10. If just a single target temperature is desired then -3000 is passed (i.e. -300°C).
Bytes 5-6 are the top end of the target temperature range, encoded in the same way.
The screen of the device will display whichever end of the range is closest to the current temperature, hence my earlier confusion.

Thanks, this made me realize that the gist had bad syntax, the second byte was documented as the probe number but it wasn't showing up because I typed it as <probe-nr> and it wasn't showing on github. Fixed it. I've added your note about the units being in decacelsius decicelsius.

@p1ng0o

This comment has been minimized.

Copy link

@p1ng0o p1ng0o commented Jan 10, 2021

Here what is working for me:

    async def ack_alarm(self):
        await self.__write(self.settings_handle, b'\x04\xff\x00\x00\x00\x00')

    async def write_target(self, channel, high = None, low = None):
        if low:
            low = low*10
        else:
            low = 0xf448

        if high:
            high = high*10
        else:
            high = 0xbcc

        m = bytes([1, channel, low & 0xFF, low >> 8, high & 0xFF, high >> 8])
        await self.__write(self.settings_handle, m)

There is a magic trick regarding these numbers.

write_target can ether clean the target temp, set only a temp target (meat), setup a min/max space (pit watcher).

@lukepighetti

This comment has been minimized.

Copy link

@lukepighetti lukepighetti commented Feb 7, 2021

Would love to know if anyone has the history dump working.

@kernel610

This comment has been minimized.

Copy link

@kernel610 kernel610 commented Mar 10, 2021

I have set the measurement unit using @UnitsFahrenheitMessage which sets the monitoring device appropriately; however the temp reported back is still in Celsius. Is this expected?

@atessmer

This comment has been minimized.

Copy link

@atessmer atessmer commented Apr 14, 2021

Device: IBT-4XS

Device alarm can be silenced by sending @SilenceAlarmMessage: (:byte[]) { 0x04, 0xff, 0x00, 0x00, 0x00, 0x00 } to the @SettingsData characteristic.

Similarly, when an alarm is silenced by pressing the button on the device, it sends the same @SilenceAlarmMessage to the client via the @SettingsResult characteristic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment