Created
September 24, 2023 18:56
-
-
Save sivar2311/83236e4a8992cfbab62f3de1a69ccaf5 to your computer and use it in GitHub Desktop.
SinricPro BLE Device Counter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _BLEDEVICECOUNTER_H_ | |
#define _BLEDEVICECOUNTER_H_ | |
#include <SinricProDevice.h> | |
#include <Capabilities/RangeController.h> | |
class BLEDeviceCounter | |
: public SinricProDevice | |
, public RangeController<BLEDeviceCounter> { | |
friend class RangeController<BLEDeviceCounter>; | |
public: | |
BLEDeviceCounter(const String &deviceId) : SinricProDevice(deviceId, "BLEDeviceCounter") {}; | |
}; | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "BLEDeviceCounter", | |
"description": "BLEDeviceCounter", | |
"deviceTypeId": "600d11ec94acbe29a9ce23e9", | |
"capabilities": [ | |
{ | |
"id": "5ff0b45f994fd31b7d5e89c2", | |
"range": { | |
"instanceId": "counter", | |
"locale": "en-US", | |
"rangeName": "counter", | |
"minimumValue": 0, | |
"maximumValue": 99999, | |
"precision": 1, | |
"unitOfMeasure": "600e7d6aa7a09c3f3230f998", | |
"presets": [], | |
"nonControllable": true | |
} | |
} | |
] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include <WiFi.h> | |
#include <SinricPro.h> | |
#include "BLEDeviceCounter.h" | |
#include <map> | |
#include "NimBLEDevice.h" | |
const char* wifiSSID = ""; | |
const char* wifiPass = ""; | |
const char* deviceId = ""; | |
const char* appKey = ""; | |
const char* appSecret = ""; | |
const unsigned long removeThresholdInMs = 60000; | |
NimBLEScan* pBLEScan; | |
std::map<String, unsigned long> deviceList; | |
void addDeviceToList(const String& address, unsigned long timeStamp) { | |
deviceList[address] = timeStamp; | |
Serial.printf("Currently there are %d ble devices in the list\r\n", deviceList.size()); | |
} | |
void removeDeviceFromList(const String& address) { | |
auto it = deviceList.find(address); | |
deviceList.erase(it); | |
} | |
void cleanUpBLEDeviceList(unsigned long ms) { | |
unsigned long currentMillis = millis(); | |
std::vector<String> removeList; | |
for (auto device : deviceList) { | |
unsigned long lastHeard = device.second; | |
String address = device.first; | |
if (currentMillis - lastHeard > ms) removeList.push_back(address); | |
} | |
size_t deviceCountBeforeCleanUp = deviceList.size(); | |
for (auto& address : removeList) { | |
removeDeviceFromList(address); | |
} | |
size_t removedDeviceCount = deviceCountBeforeCleanUp - deviceList.size(); | |
if (removedDeviceCount) { | |
Serial.printf("Cleanup removed %d devices\r\n", removedDeviceCount); | |
Serial.printf("Currently there are %d devices in the list\r\n", deviceList.size()); | |
} | |
} | |
class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks { | |
void onResult(NimBLEAdvertisedDevice* advertisedDevice) { | |
String address = advertisedDevice->getAddress().toString().c_str(); | |
addDeviceToList(address, millis()); | |
} | |
}; | |
void setupBLE() { | |
NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE); | |
NimBLEDevice::setScanDuplicateCacheSize(200); | |
NimBLEDevice::init(""); | |
} | |
void startBLEScan() { | |
pBLEScan = NimBLEDevice::getScan(); // create new scan | |
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false); | |
pBLEScan->setActiveScan(false); // Set active scanning, this will get more data from the advertiser. | |
pBLEScan->setInterval(97); // How often the scan occurs / switches channels; in milliseconds, | |
pBLEScan->setWindow(37); // How long to scan during the interval; in milliseconds. | |
pBLEScan->setMaxResults(0); // do not store the scan results, use callback only. | |
pBLEScan->start(0, nullptr, false); | |
} | |
void setupWiFi() { | |
WiFi.begin(wifiSSID, wifiPass); | |
while (WiFi.status() != WL_CONNECTED) { | |
Serial.print('.'); | |
delay(250); | |
} | |
Serial.println("connected!"); | |
} | |
void setupSinricPro() { | |
BLEDeviceCounter& bleDeviceCounter = SinricPro[deviceId]; | |
SinricPro.onConnected([](){ Serial.println("SinricPro connected!");}); | |
SinricPro.begin(appKey, appSecret); | |
} | |
void reportBLEDeviceCount() { | |
cleanUpBLEDeviceList(removeThresholdInMs); | |
if (!SinricPro.isConnected()) return; | |
unsigned long currentMillis = millis(); | |
static unsigned long lastReportTime; | |
static size_t lastReportDeviceCount; | |
if (lastReportTime && currentMillis - lastReportTime < 60000) return; | |
int devicesInList = deviceList.size(); | |
if (lastReportDeviceCount == devicesInList) return; | |
lastReportDeviceCount = devicesInList; | |
lastReportTime = currentMillis; | |
Serial.printf("Reporting %d ble devices to SinricPro\r\n", devicesInList); | |
BLEDeviceCounter& bleDeviceCounter = SinricPro[deviceId]; | |
bleDeviceCounter.sendRangeValueEvent("counter", devicesInList); | |
} | |
void setup() { | |
Serial.begin(115200); | |
setupWiFi(); | |
setupBLE(); | |
startBLEScan(); | |
setupSinricPro(); | |
} | |
void loop() { | |
SinricPro.handle(); | |
reportBLEDeviceCount(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment