Open EduAndrade87 opened 9 months ago
Hi @EduAndrade87
This can be achieved by creating a custom device type (device template)
Drang and drop a Range
Click Configure
Click Save
Create a new device, select "Counter" as type
Download the code, and update the secrets. Use the sendEvent to update the count value on the server.
Then, Alexa, what is the [range name] of [device name]
When I put the library on Bluetooth the device does not connect to SinricPRO Can I use the Bluetooth library?
#include <WiFi.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <SinricPro.h>
#include "Contador.h"
#define APP_KEY "*******************************"
#define APP_SECRET "*****************************"
#define DEVICE_ID "********************************"
#define SSID "LIVE TIM_RFC9_2G"
#define PASS "**********************"
#define BAUD_RATE 115200
Contador &contador = SinricPro[DEVICE_ID];
BLEScan* pBLEScan; // Declarar um ponteiro para a varredura BLE
int scanTime = 5; // Tempo de varredura BLE em segundos
// RangeController
std::map<String, int> globalRangeValues;
// RangeController
bool onRangeValue(const String &deviceId, const String& instance, int &rangeValue) {
Serial.printf("[Device: %s]: Value for \"%s\" changed to %d\r\n", deviceId.c_str(), instance.c_str(), rangeValue);
globalRangeValues[instance] = rangeValue;
return true;
}
bool onAdjustRangeValue(const String &deviceId, const String& instance, int &valueDelta) {
globalRangeValues[instance] += valueDelta;
Serial.printf("[Device: %s]: Value for \"%s\" changed about %d to %d\r\n", deviceId.c_str(), instance.c_str(), valueDelta, globalRangeValues[instance]);
globalRangeValues[instance] = valueDelta;
return true;
}
// RangeController
void updateRangeValue(String instance, int value) {
contador.sendRangeValueEvent(instance, value);
}
void setupSinricPro() {
// RangeController
contador.onRangeValue("projeto", onRangeValue);
contador.onAdjustRangeValue("projeto", onAdjustRangeValue);
SinricPro.onConnected([]{ Serial.printf("[SinricPro]: Connected\r\n"); });
SinricPro.onDisconnected([]{ Serial.printf("[SinricPro]: Disconnected\r\n"); });
SinricPro.begin(APP_KEY, APP_SECRET);
};
void setupWiFi() {
WiFi.begin(SSID, PASS);
Serial.printf("[WiFi]: Connectando a: %s", SSID);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Conectado à rede Wi-Fi");
Serial.println(SSID);
Serial.println("Endereço IP: " + WiFi.localIP().toString());
}
void setup() {
Serial.begin(BAUD_RATE);
Serial.println("Contagem de dispositivos Bluetooth iniciada...");
// Inicializar a conexão Wi-Fi
setupWiFi();
// Configurar a biblioteca SinricPro
setupSinricPro();
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); // Inicializar a varredura BLE
pBLEScan->setActiveScan(true);
pBLEScan->start(1000, false); // Iniciar a varredura por 1s
delay(1000); // Aguardar a varredura ser concluída
}
int Dispositivos = 0; // Variável para armazenar o número de dispositivos detectados
void loop() {
SinricPro.handle();
// Iniciar a varredura BLE por um período de tempo e obter os resultados
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Número de dispositivos Bluetooth na sala: ");
int Dispositivos = foundDevices.getCount();
Serial.println(Dispositivos);
updateRangeValue("projeto", Dispositivos);
}
void loop() {
SinricPro.handle();
// Iniciar a varredura BLE por um período de tempo e obter os resultados
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Número de dispositivos Bluetooth na sala: ");
int Dispositivos = foundDevices.getCount();
Serial.println(Dispositivos);
updateRangeValue("projeto", Dispositivos);
}
Could be related to ESP not having enough memory or doing too much work in the main thread which blocks everything. Check troubleshooting tips at https://help.sinric.pro/pages/troubleshooting on how to enable SDK and ESP logs to get more details.
void loop() {
SinricPro.handle();
.... updateRangeValue("projeto", Dispositivos); }
The above code may send too many events in a short period of time. Depending on the interval the server may throttle the connection and block any messages from processing.
1. Check the count against the previously sent value (``Dispositivos``)
2. Send the count once every minute or so.
3. You have a bottleneck. antenna is being shared between WiFi and BLE. You may need to slow down on the scanning to keep the WiFi connection alive
I made some changes to the code with your @kakopappa. I'm having trouble getting a response from Alexa. When I ask Alexa the question her answer is "I'm not sure". When I just say the name of the device "projeto" it also doesn't recognize the device Do I have to communicate in English or can I also communicate in Portuguese (BR)?
#include <WiFi.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <SinricPro.h>
#include "Contador.h"
#define APP_KEY "*******************"
#define APP_SECRET "****************************"
#define DEVICE_ID "********************************"
#define SSID "********************"
#define PASS "****************"
#define BAUD_RATE 115200
Contador &contador = SinricPro[DEVICE_ID];
BLEScan* pBLEScan; // Declarar um ponteiro para a varredura BLE
int scanTime = 5; // Tempo de varredura BLE em segundos
bool wifiConnected = false;
// RangeController
std::map<String, int> globalRangeValues;
// Classe de retorno de chamada para dispositivos BLE detectados
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
//Serial.printf("Dispositivo encontrado: %s\n", advertisedDevice.toString().c_str());
}
};
// RangeController
bool onRangeValue(const String &deviceId, const String& instance, int &rangeValue) {
Serial.printf("[Device: %s]: Value for \"%s\" changed to %d\r\n", deviceId.c_str(), instance.c_str(), rangeValue);
globalRangeValues[instance] = rangeValue;
return true;
}
bool onAdjustRangeValue(const String &deviceId, const String& instance, int &valueDelta) {
globalRangeValues[instance] += valueDelta;
Serial.printf("[Device: %s]: Value for \"%s\" changed about %d to %d\r\n", deviceId.c_str(), instance.c_str(), valueDelta, globalRangeValues[instance]);
globalRangeValues[instance] = valueDelta;
return true;
}
void updateRangeValue(const String& instance, int value) {
contador.sendRangeValueEvent(instance, value);
}
void setupSinricPro() {
// RangeController
contador.onRangeValue("projeto", onRangeValue);
contador.onAdjustRangeValue("projeto", onAdjustRangeValue);
SinricPro.onConnected([]{
Serial.printf("[SinricPro]: Connected\r\n");
wifiConnected = true; // Indica que a conexão WiFi está estabelecida
});
SinricPro.onDisconnected([]{
Serial.printf("[SinricPro]: Disconnected\r\n");
wifiConnected = false; // Indica que a conexão WiFi foi perdida
});
SinricPro.begin(APP_KEY, APP_SECRET);
}
void setupWiFi() {
WiFi.begin(SSID, PASS);
Serial.printf("[WiFi]: Conectando a: %s", SSID);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Conectado à rede Wi-Fi");
Serial.println(SSID);
Serial.println("Endereço IP: " + WiFi.localIP().toString());
wifiConnected = true; // Indica que a conexão WiFi está estabelecida
}
void setupBLE() {
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); // Active scan usa mais energia, mas obtém resultados mais rápido
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // Menor ou igual ao valor de setInterval
}
void setup() {
Serial.begin(BAUD_RATE);
Serial.println("Contagem de dispositivos Bluetooth iniciada...");
// Inicializar a conexão Wi-Fi
setupWiFi();
// Configurar a biblioteca SinricPro
setupSinricPro();
setupBLE();
}
void loop() {
SinricPro.handle();
// Iniciar a varredura BLE apenas se a conexão WiFi estiver estabelecida
if (wifiConnected) {
// Iniciar a varredura BLE por um período de tempo e obter os resultados
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Número de dispositivos Bluetooth na sala: ");
Serial.println(foundDevices.getCount());
delay(5000); // Aguarde antes de realizar a próxima varredura
Serial.println("numero enviado");
// Enviar o número de dispositivos detectados para SinricPro
updateRangeValue("projeto", foundDevices.getCount());
}
}
What an interesting project!
I made it work: SinricPro BLE DeviceCounter
The NimBLE-Arduino Library is used because it requires little RAM and Flash.
The Sketch performs the BLE scan in continuous mode.
Each time a device is scanned, the address of the device is pushed to a std::map
with the address as key and the current timestamp (millis) as value.
This avoids multiple entries for the same addresses.
The timestamp is used to delete devices from the list that have not been heard for a long period of time.
This time is defined in the constant removeThresholdInMs
.
A report is sent to SinricPro every minute if the number of devices has changed since the last report.
You can use the BLEDeviceCounter.json to import the custom device template.
Result:
@sivar2311 Thanks for the help with your code, it's more complete than mine. In my code I am not able to interact with Alexa. I ask but she can't give the answer to the number of devices that is showing on the sirinpro panel
Hi @EduAndrade87 !
I have only implemented the sketch and written it so that BLE and SinricPro work together.
I have not tested the voice commands - that is always a bit tricky.
Check that you have set the correct locale:
I want to create with esp32 wrover. a code that counts nearby Bluetooth devices and sends the count to Alexa
example: Alexa, what is the Bluetooth device count?
Example output:
Alexa: Bluetooth device count is 3.