I was trying to create a custom BLE sensor but it is too complicated for me.
So I am trying to emulate a xiaomi lywsd02 sensor based in this library.
I think that ESP BLE caracterization could be something like this.
lywsd02 data:
UUID_SERVICE = 0x2902 or “00002902-0000-1000-8000-00805f9b34fb”
this descriptor has the following properties
<Descriptor xsi:noNamespaceSchemaLocation="http://schemas.bluetooth.org/Documents/descriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="org.bluetooth.descriptor.gatt.client_characteristic_configuration" uuid="2902" name="Client Characteristic Configuration">
<InformativeText>
<Abstract>
The Client Characteristic Configuration descriptor defines how the characteristic may be configured by a specific client.
</Abstract>
<InformativeDisclaimer/>
<Summary>
This descriptor shall be persistent across connections for bonded devices.
The Client Characteristic Configuration descriptor is unique for each client. A client may read and write this descriptor to determine and set the configuration for that client.
Authentication and authorization may be required by the server to write this descriptor.
The default value for the Client Characteristic Configuration descriptor is 0x00. Upon connection of non-binded clients, this descriptor is set to the default value.
</Summary>
</InformativeText>
<Value>
<Field name="Properties">
<Requirement>Mandatory</Requirement>
<Format>16bit</Format>
<Minimum>0</Minimum>
<Maximum>3</Maximum>
<BitField>
<Bit index="0" size="1">
<Enumerations>
<Enumeration key="0" value="Notifications disabled" />
<Enumeration key="1" value="Notifications enabled" />
</Enumerations>
</Bit>
<Bit index="1" size="1">
<Enumerations>
<Enumeration key="0" value="Indications disabled" />
<Enumeration key="1" value="Indications enabled" />
</Enumerations>
</Bit>
<ReservedForFutureUse index="2" size="1" />
<ReservedForFutureUse index="3" size="1" />
<ReservedForFutureUse index="4" size="1" />
<ReservedForFutureUse index="5" size="1" />
<ReservedForFutureUse index="6" size="1" />
<ReservedForFutureUse index="7" size="1" />
<ReservedForFutureUse index="8" size="1" />
<ReservedForFutureUse index="9" size="1" />
<ReservedForFutureUse index="10" size="1" />
<ReservedForFutureUse index="11" size="1" />
<ReservedForFutureUse index="12" size="1" />
<ReservedForFutureUse index="13" size="1" />
<ReservedForFutureUse index="14" size="1" />
<ReservedForFutureUse index="15" size="1" />
</BitField>
</Field>
</Value>
</Descriptor>
UUID that the sensor uses extracted from python library:
#define SERVICE_UUID [UUID GENERATOR](https://www.uuidgenerator.net/)
#define UUID_DATA "EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_UNITS = "EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_HISTORY = "EBE0CCBC-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_TIME = "EBE0CCB7-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_DATA = "EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_BATTERY = "EBE0CCC4-7A0A-4B0C-8A1A-6FF2997DA3A6"
ESP code would be something like this:
I added sniffed payloadthat maybe esphome could understand from here.
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#define SERVICE_UUID "01e45e2a-dad1-43d0-9e3a-4fb0db7a2efa"
#define UUID_DATA "EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_UNITS "EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_HISTORY "EBE0CCBC-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_TIME "EBE0CCB7-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_DATA "EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6"
#define UUID_BATTERY "EBE0CCC4-7A0A-4B0C-8A1A-6FF2997DA3A6"
bool _BLEClientConnected = false;
int16_t aValue1=0;
int16_t aValue2=0;
BLEDescriptor data(UUID_DATA);
BLEDescriptor des_data(BLEUUID((uint16_t)0x2902));
BLECharacteristic char_data(BLEUUID(UUID_DATA), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
BLEDescriptor des_nits(BLEUUID((uint16_t)0x2902));
BLECharacteristic char_units(UUID_DATA, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
BLEDescriptor des_history(BLEUUID((uint16_t)0x2902));
BLECharacteristic char_history(UUID_HISTORY, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor des_time(BLEUUID((uint16_t)0x2902));
BLECharacteristic char_time(UUID_TIME, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
BLEDescriptor des_attery(BLEUUID((uint16_t)0x2902));
BLECharacteristic char_battery(UUID_BATTERY, BLECharacteristic::PROPERTY_READ);
// creación de servicio con sus propiedades; propiedades disponibles:
// static const uint32_t PROPERTY_READ = 1<<0;
// static const uint32_t PROPERTY_WRITE = 1<<1;
// static const uint32_t PROPERTY_NOTIFY = 1<<2;
// static const uint32_t PROPERTY_BROADCAST = 1<<3;
// static const uint32_t PROPERTY_INDICATE = 1<<4;
// static const uint32_t PROPERTY_WRITE_NR = 1<<5;
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
_BLEClientConnected = true;
};
void onDisconnect(BLEServer* pServer) {
_BLEClientConnected = false;
}
};
void InitBLE() {
BLEDevice::init("Lywsd02");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(BLEUUID((uint16_t)0x03));
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
char_data.addDescriptor(new BLE2902());
char_units.addDescriptor(new BLE2902());
char_history.addDescriptor(new BLE2902());
char_time.addDescriptor(new BLE2902());
char_battery.addDescriptor(new BLE2902());
pService->addCharacteristic(&char_data);
pService->addCharacteristic(&char_units);
pService->addCharacteristic(&char_history);
pService->addCharacteristic(&char_time);
pService->addCharacteristic(&char_battery);
pService->start();
// Start advertising
pServer->getAdvertising()->start();
}
void setup() {
Serial.begin(115200);
InitBLE();
char_units.setValue("xff");
char_units.setValue("0x36");
}
void loop() {
if (_BLEClientConnected) {
//chamamos o método "read" do sensor para realizar a leitura da temperatura
//read retornará 1 caso consiga realizar a leitura, ou 0 caso contrário
aValue1 = map(analogRead(34), 0, 4095, 0, 100);
if (aValue1 != aValue2)
{
Serial.println(aValue1);
char_data.setValue("04 3E 2B 02 01 03 01 20 AF 16 2D C1 2E 1F 1E FF 06 00 01 09 20 02 BE C7 A9 2E B4 17 E3 07 73 B4 62 81 C9 1F 5B 17 73 F8 3A F3 03 F7 75 DF");
aValue1 = aValue2;
}
}
delay(1000);
}
This article help me a lot.
I am not sure which is the BLE data with the sensor lectures to test it.
Also if you see some incongruences in the code you can help me to get it work.
At the moment compiles and I am trying differents payload values.
Meanwhile I am also working in simple custom component to send a simple payload to ble_tracker and catch the value.