v0.9.1 (Build 20250218) (see post #1)
- NEW: Function AdvertiseRaw - Advertise data in raw format as manufacturer_data or service_data (Environmental Sensing service UUID 0x181A).
- NEW: Examples - Home-Assistant Custom Integration BLE Beacon DHT; ESP32 advertised data to 4 entities.
Example Home-Assistant UI
Purpose is integrating an ESP32 (running as BLE Beacon) in
Home-Assistant (HA) as a Custom Integration named
BLE Beacon DHT (device
BLEBEACONDHT).
The ESP32 has a DHT22 sensor connected and advertises in regular intervals temperature (int), humidity (int), temperature state (byte), humidity state (byte).
The Custom Integration
BLE Beacon DHT listens to BLE advertisements, selects the device BLEBEACONDHT, parses the payload and updates 4 entities.
The integration is added using the HA UI and not YAML (except for setting debug logs).
The custom component must be placed in the HA folder
config/custom_components with folder name
ble_beacon_dht.
After copied the files to the custom component folder > restart HA > Add Integration BLE Beacon DHT > Check HA Logs (settings > system > logs).
To debug, add to HA configuration.yaml:
YAML:
logger:
logs:
custom_components.ble_beacon_dht: debug
B4R Code Snippet
[CODE lang="b4x" title="B4R Code Snippet"]Sub Process_Globals
Private VERSION As String = "rBLEBeacon HomeAssistant Example v20250217"
Public Serial1 As Serial
Private BLEBeacon As BLEBeacon
Private DHT As DHTESP
Private DHTPinNumber As UInt = 0x04
Private Temperature As Int
Private TemperatureState As Byte
Private Humidity As Int
Private HumidityState As Byte
Private TimerDataAdvertising As Timer
Private TimerDataAdvertisingInterval As ULong = 20000 'Milliseconds
Private bc As ByteConverter
End Sub
#Region AppStart
Private Sub AppStart
Serial1.Initialize(115200)
Log(CRLF, "[AppStart]", VERSION)
'Init the ble beacon with name and error event
BLEBeacon.Initialize("BLEBEACONDHT", "BLEBeacon_Error")
'Init DHT22
DHT.Setup22(DHTPinNumber)
'Init Timer Data Advertising
TimerDataAdvertising.Initialize("TimerDataAdvertising_Tick", TimerDataAdvertisingInterval)
TimerDataAdvertising.Enabled = True
TimerDataAdvertising_Tick
End Sub
#End Region
#Region Timer
'Read the DHT22 data, set states (magic numbers hardcoded) and advertise.
'[TimerDataAdvertising_Tick] t=1650, h=5330, ts=3 hs=1
'[BLEBeacon_AdvertiseRaw] data=7206D2140301,size=6,serviceinfo=1
'[B4RBLEBeacon::AdvertiseRaw] Advertised data size: 6
'[B4RBLEBeacon::AdvertiseRaw] Advertised data: 7206D2140301
Sub TimerDataAdvertising_Tick
'Update globals
Temperature = DHT.GetTemperature * 100 'Convert float to int 19.30 → 1930
Humidity = DHT.GetHumidity * 100 'Convert float to int 92.40 → 9240
'Set temperature & humidity states
If Temperature < 20 Then
TemperatureState = 1
Else if Temperature > 26 Then
TemperatureState = 3
Else
TemperatureState = 2
End If
If HumidityState < 30 Then
HumidityState = 1
Else if HumidityState > 60 Then
HumidityState = 3
Else
HumidityState = 2
End If
'[TimerDataAdvertising_Tick] t=1720, h=5520, ts=1, hs=2
Log("[TimerDataAdvertising_Tick] t=", NumberFormat(Temperature,0,0),", h=", NumberFormat(Humidity,0,0),", ts=", TemperatureState, " hs=", HumidityState)
'Advertise 6 bytes:
'temperature (Int, 2bytes) + humidity (int, 2bytes) + temperaturestate (byte) + humiditystate (byte)
BLEBeacon_AdvertiseRaw
'BLE advertise as serialized data; marker start 7E, end 7F
'BLEBeacon_AdvertiseSerialized
End Sub
#End Region
'Advertise raw data as service UUID.
'data - Byte array containing data fo the connected client.
Private Sub BLEBeacon_AdvertiseRaw
'Set serviceinfo flag true
Dim serviceinfo As Boolean = True
'Set data 6 bytes little-endian - these are assigned per byte
Dim data(6) As Byte
Dim t(2) As Byte = BytesFromInt(Temperature, True)
Dim h(2) As Byte = BytesFromInt(Humidity, True)
data(0) = t(0)
data(1) = t(1)
data(2) = h(0)
data(3) = h(1)
data(4) = TemperatureState
data(5) = HumidityState
'[BLEBeacon_AdvertiseRaw] data=720618150301,size=6,serviceinfo=1
Log("[BLEBeacon_AdvertiseRaw] data=", bc.HexFromBytes(data), ",size=", data.Length, ",serviceinfo=", serviceinfo )
BLEBeacon.AdvertiseRaw(data, serviceinfo)
End Sub
'Handle BLE Beacon error.
'Log the error to the B4R IDE, but could also use an LED.
Private Sub BLEBeacon_Error(code As Byte)
Log("[BLEBeacon_Error]code=",code)
Select code
Case BLEBeacon.ERROR_ADV_DATA_SIZE_TOO_LARGE
Log("[ERROR][Advertise] Data size exceeds maximum ", BLEBeacon.MAX_ADV_DATA_SIZE, " bytes.")
End Select
End Sub
'Helper
'Get HEX code for a single byte.
'b - Single byte
'Returns HEX code as string
Public Sub HexFromByte(b As Byte) As String
Return bc.HexFromBytes(Array As Byte(b))
End Sub
Public Sub HexFromInt(i As Int) As String
Dim b() As Byte = bc.IntsToBytes(Array As Int(i))
'Log("[HexFromInt]i=", i, ",bytes=",b(0),b(1))
Return bc.HexFromBytes(b)
End Sub
'Get 4 bytes from long.
'Do not use the byteconverter as it converts per default to little endian.
'value - Long value to convert
'littleendian - Flag to set little endian, set to false for big endian
'Returns 4 bytes
Public Sub BytesFromLong(value As Long, littleendian As Boolean) As Byte()
Dim raf As RandomAccessFile
'Set the return byte array size = 4
Dim b(4) As Byte
raf.Initialize(b, littleendian)
raf.WriteULong32(value, 0)
Return b
End Sub
'Get 2 bytes from integer.
'value - Integer value to convert
'littleendian - Flag to set little endian, set to false for big endian
'Returns 2 bytes as uint
Public Sub BytesFromInt(value As Int, littleendian As Boolean) As Byte()
Dim raf As RandomAccessFile
'Set the return byte array size = 2
Dim b(2) As Byte
raf.Initialize(b, littleendian)
raf.WriteUInt16(value, 0)
Return b
End Sub
[/CODE]