Skip to content

Commit

Permalink
Merge pull request #46 from Sensirion/add-device-name-support
Browse files Browse the repository at this point in the history
Add device name support
  • Loading branch information
psachs authored Nov 19, 2024
2 parents 165d9d4 + d05d61e commit d6831d7
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "Sensirion_Gadget_BLE.h"
#include <string>

NimBLELibraryWrapper lib;
DataProvider provider(lib, DataType::T_RH_CO2_ALT, false, true);

uint16_t t = 0;
uint16_t rh = 0;
uint16_t co2 = 0;
uint16_t batteryLevel = 100;

static int64_t lastMeasurementTimeMs = 0;
static int measurementIntervalMs = 1000;

static int64_t lastBatteryLevelUpdateMs = 0;
static int batteryLevelUpdateIntervalMs = 60000;

std::string altDeviceName = "Mock Device";

void setup() {
Serial.begin(115200);
delay(1000); // Wait for Serial monitor to start

// Enable alternative device name feature.
// Must be enabled before calling begin().
provider.enableAltDeviceName();
// Initialize the GadgetBle Library
provider.begin();
// Set alternative device name that will be used
// by MyAmbience instead of the local device name.
provider.setAltDeviceName(altDeviceName);

Serial.print("Sensirion GadgetBle Lib initialized with deviceId = ");
Serial.println(provider.getDeviceIdString());

// Set initial battery level
provider.setBatteryLevel(batteryLevel);
}

void loop() {
if (millis() - lastMeasurementTimeMs >= measurementIntervalMs) {
Serial.println("Measurement");
provider.writeValueToCurrentSample(++t % 50, SignalType::TEMPERATURE_DEGREES_CELSIUS);
provider.writeValueToCurrentSample(++rh % 100, SignalType::RELATIVE_HUMIDITY_PERCENTAGE);
provider.writeValueToCurrentSample(++co2 % 1000, SignalType::CO2_PARTS_PER_MILLION);
provider.commitSample();
lastMeasurementTimeMs = millis();
// Provide the sensor values for Tools -> Serial Monitor or Serial Plotter
Serial.print("mockCO2[ppm]:");
Serial.print(co2);
Serial.print("\t");
Serial.print("mockTemperature[℃]:");
Serial.print(t);
Serial.print("\t");
Serial.print("mockHumidity[%]:");
Serial.println(rh);
}
if (millis() - lastBatteryLevelUpdateMs >= batteryLevelUpdateIntervalMs) {
lastBatteryLevelUpdateMs = millis();
provider.setBatteryLevel(--batteryLevel);
Serial.print("Battery Level Update:");
Serial.println(batteryLevel);
if (batteryLevel == 0) {
batteryLevel = 100;
}
}

provider.handleDownload();
delay(3);
}
28 changes: 28 additions & 0 deletions examples/Example14_Alternative_Device_Name/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
src_dir = .

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
upload_port = /dev/ttyUSB*
monitor_speed = 115200
lib_ldf_mode=deep

lib_deps =
Sensirion_Unified_Prototyping_Toolkit_Core
h2zero/NimBLE-Arduino@^1.4.0

lib_extra_dirs =
${PROJECT_DIR}/../../

3 changes: 2 additions & 1 deletion src/AdvertisementHeader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ void AdvertisementHeader::writeSampleType(uint8_t sampleType) {
_writeByte(sampleType, 3);
}

void AdvertisementHeader::writeDeviceId(uint8_t deviceIDHigh, uint8_t deviceIDLow) {
void AdvertisementHeader::writeDeviceId(uint8_t deviceIDHigh,
uint8_t deviceIDLow) {
_writeByte(deviceIDHigh, 4);
_writeByte(deviceIDLow, 5);
}
52 changes: 40 additions & 12 deletions src/DataProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ void DataProvider::begin() {
// Use part of MAC address as device id
std::string macAddress = _BLELibrary.getDeviceAddress();
_advertisementHeader.writeDeviceId(
static_cast<uint8_t>(strtol(macAddress.substr(12, 14).c_str(), NULL, 16)),
static_cast<uint8_t>(strtol(macAddress.substr(15, 17).c_str(), NULL, 16))
);
static_cast<uint8_t>(
strtol(macAddress.substr(12, 14).c_str(), NULL, 16)),
static_cast<uint8_t>(
strtol(macAddress.substr(15, 17).c_str(), NULL, 16)));

_BLELibrary.setAdvertisingData(_buildAdvertisementData());
_BLELibrary.startAdvertising();
Expand All @@ -29,8 +30,8 @@ void DataProvider::writeValueToCurrentSample(float value,
}

// Check for correct signal type
if (_sampleConfig.sampleSlots.count(signalType) ==
0) { // implies signal type is not part of sample
if (_sampleConfig.sampleSlots.count(signalType) == 0) {
// implies signal type is not part of sample
return;
}

Expand Down Expand Up @@ -86,10 +87,12 @@ void DataProvider::handleDownload() {

// Start Download
if (_downloadState == START) {
if(_nrOfSamplesRequested > 0 && _nrOfSamplesRequested < _sampleHistory.numberOfSamplesInHistory()) {
if (_nrOfSamplesRequested > 0 &&
_nrOfSamplesRequested < _sampleHistory.numberOfSamplesInHistory()) {
_numberOfSamplesToDownload = _nrOfSamplesRequested;
} else {
_numberOfSamplesToDownload = _sampleHistory.numberOfSamplesInHistory();
_numberOfSamplesToDownload =
_sampleHistory.numberOfSamplesInHistory();
}
_numberOfSamplePacketsToDownload =
_numberOfPacketsRequired(_numberOfSamplesToDownload);
Expand Down Expand Up @@ -132,6 +135,26 @@ bool DataProvider::isDownloading() const {
return (_downloadState != DownloadState::INACTIVE);
}

void DataProvider::enableAltDeviceName() {
_enableAltDeviceName = true;
}

std::string DataProvider::getAltDeviceName() {
return _altDeviceName;
}

void DataProvider::setAltDeviceName(std::string altDeviceName) {
_altDeviceName = altDeviceName;
_BLELibrary.characteristicSetValue(
ALT_DEVICE_NAME_UUID,
reinterpret_cast<const uint8_t*>(_altDeviceName.c_str()),
_altDeviceName.length());
}

void DataProvider::onAltDeviceNameChange(std::string altDeviceName) {
setAltDeviceName(altDeviceName);
}

std::string DataProvider::_buildAdvertisementData() {
_advertisementHeader.writeSampleType(_sampleConfig.sampleType);
std::string data = _advertisementHeader.getDataString();
Expand Down Expand Up @@ -182,7 +205,7 @@ void DataProvider::_setupBLEInfrastructure() {
NUMBER_OF_SAMPLES_UUID,
Permission::READ_PERMISSION);
_BLELibrary.characteristicSetValue(NUMBER_OF_SAMPLES_UUID, 0);
_BLELibrary.createCharacteristic(DOWNLOAD_SERVICE_UUID,
_BLELibrary.createCharacteristic(DOWNLOAD_SERVICE_UUID,
REQUESTED_SAMPLES_UUID,
Permission::WRITE_PERMISSION);
_BLELibrary.createCharacteristic(DOWNLOAD_SERVICE_UUID,
Expand All @@ -194,12 +217,11 @@ void DataProvider::_setupBLEInfrastructure() {
_BLELibrary.startService(DOWNLOAD_SERVICE_UUID);

// Settings Service
_BLELibrary.createService(SETTINGS_SERVICE_UUID);
if (_enableWifiSettings) {
_BLELibrary.createService(SETTINGS_SERVICE_UUID);
_BLELibrary.createCharacteristic(SETTINGS_SERVICE_UUID, WIFI_SSID_UUID,
Permission::READWRITE_PERMISSION);
const char* ssid = "ssid";
Serial.println(strlen(ssid));
_BLELibrary.characteristicSetValue(
WIFI_SSID_UUID, reinterpret_cast<const uint8_t*>(ssid),
strlen(ssid));
Expand All @@ -208,8 +230,14 @@ void DataProvider::_setupBLEInfrastructure() {
const char* pwd = "password";
_BLELibrary.characteristicSetValue(
WIFI_PWD_UUID, reinterpret_cast<const uint8_t*>(pwd), strlen(pwd));
_BLELibrary.startService(SETTINGS_SERVICE_UUID);
}
if (_enableAltDeviceName) {
_BLELibrary.createCharacteristic(SETTINGS_SERVICE_UUID,
ALT_DEVICE_NAME_UUID,
Permission::READWRITE_PERMISSION);
setAltDeviceName(_altDeviceName);
}
_BLELibrary.startService(SETTINGS_SERVICE_UUID);

// Battery Service
if (_enableBatteryService) {
Expand All @@ -221,7 +249,7 @@ void DataProvider::_setupBLEInfrastructure() {
_BLELibrary.startService(BATTERY_SERVICE_UUID);
}
// SCD FRC Service
if (_enalbeFRCService) {
if (_enableFRCService) {
_BLELibrary.createService(SCD_SERVICE_UUID);
_BLELibrary.createCharacteristic(SCD_SERVICE_UUID, SCD_FRC_REQUEST_UUID,
Permission::WRITE_PERMISSION);
Expand Down
17 changes: 15 additions & 2 deletions src/DataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "IWifiLibraryWrapper.h"
#include "SampleHistoryRingBuffer.h"
#include "Sensirion_UPT_Core.h"
#include <string>

class DataProvider: public IProviderCallbacks {
public:
Expand All @@ -49,7 +50,7 @@ class DataProvider: public IProviderCallbacks {
IWifiLibraryWrapper* pWifiLibrary = nullptr)
: _BLELibrary(libraryWrapper), _enableWifiSettings(enableWifiSettings),
_enableBatteryService(enableBatteryService),
_enalbeFRCService(enableFRCService),
_enableFRCService(enableFRCService), _enableAltDeviceName(false),
_sampleConfig(sampleConfigSelector.at(dataType)),
_pWifiLibaray(pWifiLibrary){};
~DataProvider(){};
Expand All @@ -64,6 +65,15 @@ class DataProvider: public IProviderCallbacks {
bool isFRCRequested() const;
uint32_t getReferenceCO2Level() const;
void completeFRCRequest();
/*
* enableAltDeviceName must be called before begin() to ensure
* the characteristic is created.
* Initially the alternative device name is empty.
* Use setAltDeviceName to change the device name.
*/
void enableAltDeviceName();
std::string getAltDeviceName();
void setAltDeviceName(std::string altDeviceName);

private:
std::string _buildAdvertisementData();
Expand All @@ -82,10 +92,12 @@ class DataProvider: public IProviderCallbacks {
int _numberOfSamplePacketsToDownload = 0;
bool _frc_requested = false;
uint32_t _reference_co2_level = 0;
std::string _altDeviceName = "";

bool _enableWifiSettings;
bool _enableBatteryService;
bool _enalbeFRCService;
bool _enableFRCService;
bool _enableAltDeviceName;

SampleConfig _sampleConfig;
uint64_t _historyIntervalMilliSeconds = 600000; // = 10 minutes
Expand All @@ -101,6 +113,7 @@ class DataProvider: public IProviderCallbacks {
void onWifiPasswordChange(std::string pwd) override;
void onFRCRequest(uint16_t reference_co2_level) override;
void onNrOfSamplesRequest(int nr_of_samples) override;
void onAltDeviceNameChange(std::string altDeviceName) override;
};

#endif /* _DATA_PROVIDER_H_ */
7 changes: 4 additions & 3 deletions src/IBLELibraryWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
const char* const GADGET_NAME = "S";

// when adding a new characteristic, make sure to
// write numbers in lower case and to increlase
// write numbers in lower case and to increase
// the constants MAX_NUMBER_OF_xxx

static const char* const DOWNLOAD_SERVICE_UUID =
Expand All @@ -56,7 +56,8 @@ static const char* const SETTINGS_SERVICE_UUID =
static const char* const WIFI_SSID_UUID =
"00008171-b38d-4985-720e-0f993a68ee41";
static const char* const WIFI_PWD_UUID = "00008172-b38d-4985-720e-0f993a68ee41";

static const char* const ALT_DEVICE_NAME_UUID =
"00008120-b38d-4985-720e-0f993a68ee41";
static const char* const BATTERY_SERVICE_UUID =
"0000180f-0000-1000-8000-00805f9b34fb";
static const char* const BATTERY_LEVEL_UUID =
Expand All @@ -68,7 +69,7 @@ static const char* const SCD_FRC_REQUEST_UUID =
"00007004-b38d-4985-720e-0f993a68ee41";

static const unsigned int MAX_NUMBER_OF_SERVICES = 4;
static const unsigned int MAX_NUMBER_OF_CHARACTERISTICS = 11;
static const unsigned int MAX_NUMBER_OF_CHARACTERISTICS = 12;

enum Permission {
READWRITE_PERMISSION,
Expand Down
1 change: 1 addition & 0 deletions src/IProviderCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class IProviderCallbacks {
virtual void onWifiPasswordChange(std::string pwd) = 0;
virtual void onFRCRequest(uint16_t reference_co2_level) = 0;
virtual void onNrOfSamplesRequest(int nr_of_samples) = 0;
virtual void onAltDeviceNameChange(std::string altDeviceName) = 0;
};

#endif /* _PROVIDER_CALLBACKS_H_ */
9 changes: 7 additions & 2 deletions src/NimBLELibraryWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void WrapperPrivateData::onWrite(BLECharacteristic* characteristic) {
if (providerCallbacks == nullptr) {
return;
}

if (characteristic->getUUID().toString().compare(
SAMPLE_HISTORY_INTERVAL_UUID) == 0) {
std::string value = characteristic->getValue();
Expand All @@ -68,14 +69,18 @@ void WrapperPrivateData::onWrite(BLECharacteristic* characteristic) {
SCD_FRC_REQUEST_UUID) == 0) {
std::string value = characteristic->getValue();
// co2 level is encoded in lower two bytes, little endian
// the first two bytes are obfusation and can be ignored
// the first two bytes are obfuscation and can be ignored
uint16_t referenceCO2Level = value[2] | (value[3] << 8);
providerCallbacks->onFRCRequest(referenceCO2Level);
} else if (characteristic->getUUID().toString().compare(
REQUESTED_SAMPLES_UUID) == 0) {
std::string value = characteristic->getValue();
uint32_t nr_of_samples = value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
uint32_t nr_of_samples =
value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
providerCallbacks->onNrOfSamplesRequest(nr_of_samples);
} else if (characteristic->getUUID().toString().compare(
ALT_DEVICE_NAME_UUID) == 0) {
providerCallbacks->onAltDeviceNameChange(characteristic->getValue());
}
}

Expand Down

0 comments on commit d6831d7

Please sign in to comment.