Loads of improvements (#372)
* Disable unused ble functions to free up some memory * Added Count of devices present in room * Added known macs * Reorg settings * Improvements to ignoring (trailing spaces matched everything) * Add battery percent to ATC sensors * Remove sprite usage to clean up memory usage * Initial support for samsung smart tag (may not actually work) (#351) * DHT Sensor temp related changes (#385) * Add interval, fix rounding * Add batt for MACCHINA_A0 * Add running to macchina * Add Garmin watch (Fenix 6) id * Updgrade ArduinoJson Co-authored-by: tr-v-r <83373608+tr-v-r@users.noreply.github.com>
This commit is contained in:
parent
e8699f0279
commit
54721b03be
|
@ -4,10 +4,9 @@ import time
|
|||
|
||||
#this list contains array of esp32 clients,
|
||||
# and each client contains mDNS name and the path to .bin file
|
||||
#I only have 1 ESP so I duplicate mDNS entry for testing
|
||||
esps = [
|
||||
#mDNS name of ESP #path to ".bin" file
|
||||
['192.168.128.114', 'macchina-a0'],
|
||||
['192.168.128.112', 'macchina-a0'],
|
||||
['192.168.128.124', 'm5stickc'],
|
||||
['192.168.128.64', 'm5atom-matrix'],
|
||||
['192.168.128.84', 'm5atom-matrix']
|
||||
|
|
|
@ -4,23 +4,15 @@
|
|||
#include "strings.h"
|
||||
#include "util.h"
|
||||
|
||||
bool prefixExists(const String& prefixes, const String& id)
|
||||
class ClientCallbacks : public BLEClientCallbacks
|
||||
{
|
||||
unsigned int start = 0;
|
||||
unsigned int space = 0;
|
||||
|
||||
while ((space = prefixes.indexOf(" ", start)) != -1)
|
||||
bool onConnParamsUpdateRequest(NimBLEClient *pClient, const ble_gap_upd_params *params)
|
||||
{
|
||||
if (space > start)
|
||||
{
|
||||
auto sub = prefixes.substring(start, space);
|
||||
if (sub == "*" || id.indexOf(sub) != -1) return true;
|
||||
}
|
||||
start = space + 1;
|
||||
}
|
||||
auto sub = prefixes.substring(start);
|
||||
return (sub == "*" || id.indexOf(sub) != -1);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
static ClientCallbacks clientCB;
|
||||
|
||||
bool BleFingerprint::shouldHide(const String& s)
|
||||
{
|
||||
|
@ -30,13 +22,14 @@ bool BleFingerprint::shouldHide(const String& s)
|
|||
|
||||
bool BleFingerprint::setId(const String& newId, short newIdType, const String& newName)
|
||||
{
|
||||
if (newIdType < idType) return false;
|
||||
if (newIdType < idType && idType > 0) return false;
|
||||
|
||||
hidden = shouldHide(newId);
|
||||
ignore = newIdType < 0;
|
||||
|
||||
if (!allowQuery)
|
||||
if (!allowQuery && !ignore)
|
||||
{
|
||||
if (BleFingerprintCollection::query.length() > 0 && prefixExists(BleFingerprintCollection::query, newId))
|
||||
if (!BleFingerprintCollection::query.isEmpty() && prefixExists(BleFingerprintCollection::query, newId))
|
||||
{
|
||||
allowQuery = true;
|
||||
qryAttempts = 0;
|
||||
|
@ -48,6 +41,7 @@ bool BleFingerprint::setId(const String& newId, short newIdType, const String& n
|
|||
}
|
||||
}
|
||||
|
||||
countable = !ignore && !BleFingerprintCollection::countIds.isEmpty() && prefixExists(BleFingerprintCollection::countIds, newId);
|
||||
id = newId;
|
||||
idType = newIdType;
|
||||
if (!newName.isEmpty()) name = newName;
|
||||
|
@ -66,9 +60,25 @@ BleFingerprint::BleFingerprint(const BleFingerprintCollection *parent, BLEAdvert
|
|||
{
|
||||
firstSeenMillis = millis();
|
||||
address = NimBLEAddress(advertisedDevice->getAddress());
|
||||
macPublic = advertisedDevice->getAddressType() == BLE_ADDR_PUBLIC;
|
||||
newest = recent = oldest = rssi = advertisedDevice->getRSSI();
|
||||
seenCount = 1;
|
||||
|
||||
auto mac = getMac();
|
||||
if (!BleFingerprintCollection::knownMacs.isEmpty() && prefixExists(BleFingerprintCollection::knownMacs, mac))
|
||||
setId("known:" + mac, ID_TYPE_KNOWN_MAC);
|
||||
else
|
||||
{
|
||||
switch (advertisedDevice->getAddressType())
|
||||
{
|
||||
case BLE_ADDR_PUBLIC:
|
||||
case BLE_ADDR_PUBLIC_ID:
|
||||
setId(mac, ID_TYPE_PUBLIC_MAC);
|
||||
break;
|
||||
default:
|
||||
setId(mac, ID_TYPE_MAC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BleFingerprint::fingerprint(NimBLEAdvertisedDevice *advertisedDevice)
|
||||
|
@ -81,13 +91,15 @@ void BleFingerprint::fingerprint(NimBLEAdvertisedDevice *advertisedDevice)
|
|||
|
||||
size_t serviceAdvCount = advertisedDevice->getServiceUUIDCount();
|
||||
size_t serviceDataCount = advertisedDevice->getServiceDataCount();
|
||||
bool haveTxPower = advertisedDevice->haveTXPower();
|
||||
int8_t txPower = advertisedDevice->getTXPower();
|
||||
|
||||
if (serviceAdvCount > 0) fingerprintServiceAdvertisements(advertisedDevice, serviceAdvCount);
|
||||
if (serviceDataCount > 0) fingerprintServiceData(advertisedDevice, serviceDataCount);
|
||||
if (advertisedDevice->haveManufacturerData()) fingerprintManufactureData(advertisedDevice);
|
||||
if (serviceAdvCount > 0) fingerprintServiceAdvertisements(advertisedDevice, serviceAdvCount, haveTxPower, txPower);
|
||||
if (serviceDataCount > 0) fingerprintServiceData(advertisedDevice, serviceDataCount, haveTxPower, txPower);
|
||||
if (advertisedDevice->haveManufacturerData()) fingerprintManufactureData(advertisedDevice, haveTxPower, txPower);
|
||||
}
|
||||
|
||||
void BleFingerprint::fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceAdvCount)
|
||||
void BleFingerprint::fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceAdvCount, bool haveTxPower, int8_t txPower)
|
||||
{
|
||||
for (size_t i = 0; i < serviceAdvCount; i++)
|
||||
{
|
||||
|
@ -118,135 +130,142 @@ void BleFingerprint::fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *ad
|
|||
}
|
||||
else if (uuid == sonosUUID)
|
||||
{
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("sonos:" + getMac(), ID_TYPE_SONOS);
|
||||
return;
|
||||
}
|
||||
else if (uuid == itagUUID)
|
||||
{
|
||||
asRssi = BleFingerprintCollection::refRssi + (advertisedDevice->haveTXPower() ? advertisedDevice->getTXPower() : ITAG_TX);
|
||||
asRssi = BleFingerprintCollection::refRssi + (haveTxPower ? txPower : ITAG_TX);
|
||||
setId("itag:" + getMac(), ID_TYPE_ITAG);
|
||||
return;
|
||||
}
|
||||
else if (uuid == trackrUUID)
|
||||
{
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("trackr:" + getMac(), ID_TYPE_TRACKR);
|
||||
return;
|
||||
}
|
||||
else if (uuid == vanmoofUUID)
|
||||
{
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("vanmoof:" + getMac(), ID_TYPE_VANMOOF);
|
||||
return;
|
||||
}
|
||||
else if (uuid == (meaterService))
|
||||
{
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("meater:" + getMac(), ID_TYPE_MEATER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String fingerprint = "ad:";
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
for (int i = 0; i < serviceAdvCount; i++)
|
||||
{
|
||||
std::string sid = advertisedDevice->getServiceUUID(i).toString();
|
||||
fingerprint = fingerprint + sid.c_str();
|
||||
}
|
||||
if (advertisedDevice->haveTXPower()) fingerprint = fingerprint + String(-advertisedDevice->getTXPower());
|
||||
if (haveTxPower) fingerprint = fingerprint + String(-txPower);
|
||||
setId(fingerprint, ID_TYPE_AD);
|
||||
}
|
||||
|
||||
void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceDataCount)
|
||||
void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceDataCount, bool haveTxPower, int8_t txPower)
|
||||
{
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
String fingerprint = "sd:";
|
||||
for (int i = 0; i < serviceDataCount; i++)
|
||||
{
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
String fingerprint = "sd:";
|
||||
for (int i = 0; i < serviceDataCount; i++)
|
||||
{
|
||||
BLEUUID uuid = advertisedDevice->getServiceDataUUID(i);
|
||||
std::string strServiceData = advertisedDevice->getServiceData(i);
|
||||
BLEUUID uuid = advertisedDevice->getServiceDataUUID(i);
|
||||
std::string strServiceData = advertisedDevice->getServiceData(i);
|
||||
#ifdef VERBOSE
|
||||
Serial.printf("Verbose | %-58sSD: %s/%s\n", getId().c_str(), uuid.toString().c_str(), hexStr(strServiceData).c_str());
|
||||
Serial.printf("Verbose | %-58sSD: %s/%s\n", getId().c_str(), uuid.toString().c_str(), hexStr(strServiceData).c_str());
|
||||
#endif
|
||||
|
||||
if (uuid == exposureUUID)
|
||||
{ // found COVID-19 exposure tracker
|
||||
calRssi = BleFingerprintCollection::refRssi + EXPOSURE_TX;
|
||||
setId("exp:" + String(strServiceData.length()), ID_TYPE_EXPOSURE);
|
||||
disc = hexStr(strServiceData).c_str();
|
||||
}
|
||||
else if (uuid == miThermUUID)
|
||||
{
|
||||
asRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
if (strServiceData.length() == 15)
|
||||
{ // custom format
|
||||
auto serviceData = strServiceData.c_str();
|
||||
temp = float(*(int16_t *)(serviceData + 6)) / 100.0f;
|
||||
humidity = float(*(uint16_t *)(serviceData + 8)) / 100.0f;
|
||||
mv = *(uint16_t *)(serviceData + 10);
|
||||
#ifdef VERBOSE
|
||||
Serial.printf("Temp: %.2f°, Humidity: %.2f%%, Vbatt: %d, Battery: %d%%, flg: 0x%02x, cout: %d\n", temp, humidity, mv, serviceData[12], serviceData[14], serviceData[13]);
|
||||
#endif
|
||||
setId("miTherm:" + getMac(), ID_TYPE_MITHERM);
|
||||
}
|
||||
else if (strServiceData.length() == 13)
|
||||
{ // format atc1441
|
||||
auto serviceData = strServiceData.c_str();
|
||||
int16_t x = (serviceData[6] << 8) | serviceData[7];
|
||||
temp = float(x) / 10.0f;
|
||||
mv = x = (serviceData[10] << 8) | serviceData[11];
|
||||
#ifdef VERBOSE
|
||||
Serial.printf("Temp: %.1f°, Humidity: %d%%, Vbatt: %d, Battery: %d%%, cout: %d\n", temp, serviceData[8], mv, serviceData[9], serviceData[12]);
|
||||
#endif
|
||||
setId("miTherm:" + getMac(), ID_TYPE_MITHERM);
|
||||
}
|
||||
}
|
||||
else if (uuid == eddystoneUUID && strServiceData.length() > 0)
|
||||
{
|
||||
if (strServiceData[0] == EDDYSTONE_URL_FRAME_TYPE && strServiceData.length() <= 18)
|
||||
{
|
||||
BLEEddystoneURL oBeacon = BLEEddystoneURL();
|
||||
oBeacon.setData(strServiceData);
|
||||
calRssi = EDDYSTONE_ADD_1M + oBeacon.getPower();
|
||||
}
|
||||
else if (strServiceData[0] == EDDYSTONE_TLM_FRAME_TYPE)
|
||||
{
|
||||
BLEEddystoneTLM oBeacon = BLEEddystoneTLM();
|
||||
oBeacon.setData(strServiceData);
|
||||
temp = oBeacon.getTemp();
|
||||
mv = oBeacon.getVolt();
|
||||
#ifdef VERBOSE
|
||||
Serial.println(oBeacon.toString().c_str());
|
||||
#endif
|
||||
}
|
||||
else if (strServiceData[0] == 0x00)
|
||||
{
|
||||
auto serviceData = strServiceData.c_str();
|
||||
int8_t rss0m = *(int8_t *)(serviceData + 1);
|
||||
calRssi = EDDYSTONE_ADD_1M + rss0m;
|
||||
setId(Sprintf("eddy:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
strServiceData[2], strServiceData[3], strServiceData[4], strServiceData[5], strServiceData[6],
|
||||
strServiceData[6], strServiceData[7], strServiceData[8], strServiceData[9], strServiceData[10],
|
||||
strServiceData[11], strServiceData[12], strServiceData[13], strServiceData[14], strServiceData[15],
|
||||
strServiceData[16], strServiceData[17]),
|
||||
ID_TYPE_EBEACON);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fingerprint = fingerprint + uuid.toString().c_str();
|
||||
}
|
||||
}
|
||||
if (advertisedDevice->haveTXPower())
|
||||
fingerprint = fingerprint + String(-advertisedDevice->getTXPower());
|
||||
setId(fingerprint, ID_TYPE_SD);
|
||||
if (uuid == exposureUUID)
|
||||
{ // found COVID-19 exposure tracker
|
||||
calRssi = BleFingerprintCollection::refRssi + EXPOSURE_TX;
|
||||
setId("exp:" + String(strServiceData.length()), ID_TYPE_EXPOSURE);
|
||||
disc = hexStr(strServiceData).c_str();
|
||||
}
|
||||
else if (uuid == smartTagUUID)
|
||||
{ // found Samsung smart tag
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId(String("smarttag:") + hexStr(strServiceData).c_str(), ID_TYPE_SMARTTAG);
|
||||
}
|
||||
else if (uuid == miThermUUID)
|
||||
{
|
||||
asRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
if (strServiceData.length() == 15)
|
||||
{ // custom format
|
||||
auto serviceData = strServiceData.c_str();
|
||||
temp = float(*(int16_t *)(serviceData + 6)) / 100.0f;
|
||||
humidity = float(*(uint16_t *)(serviceData + 8)) / 100.0f;
|
||||
mv = *(uint16_t *)(serviceData + 10);
|
||||
battery = serviceData[12];
|
||||
#ifdef VERBOSE
|
||||
Serial.printf("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, flg: 0x%02hhx, cout: %hhu\n", temp, humidity, mv, battery, serviceData[14], serviceData[13]);
|
||||
#endif
|
||||
setId("miTherm:" + getMac(), ID_TYPE_MITHERM);
|
||||
}
|
||||
else if (strServiceData.length() == 13)
|
||||
{ // format atc1441
|
||||
auto serviceData = strServiceData.c_str();
|
||||
int16_t x = (serviceData[6] << 8) | serviceData[7];
|
||||
temp = float(x) / 10.0f;
|
||||
humidity = serviceData[8];
|
||||
mv = x = (serviceData[10] << 8) | serviceData[11];
|
||||
battery = serviceData[9];
|
||||
|
||||
#ifdef VERBOSE
|
||||
Serial.printf("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, cout: %hhu\n", temp, humidity, mv, battery, serviceData[12]);
|
||||
#endif
|
||||
setId("miTherm:" + getMac(), ID_TYPE_MITHERM);
|
||||
}
|
||||
}
|
||||
else if (uuid == eddystoneUUID && strServiceData.length() > 0)
|
||||
{
|
||||
if (strServiceData[0] == EDDYSTONE_URL_FRAME_TYPE && strServiceData.length() <= 18)
|
||||
{
|
||||
BLEEddystoneURL oBeacon = BLEEddystoneURL();
|
||||
oBeacon.setData(strServiceData);
|
||||
calRssi = EDDYSTONE_ADD_1M + oBeacon.getPower();
|
||||
}
|
||||
else if (strServiceData[0] == EDDYSTONE_TLM_FRAME_TYPE)
|
||||
{
|
||||
BLEEddystoneTLM oBeacon = BLEEddystoneTLM();
|
||||
oBeacon.setData(strServiceData);
|
||||
temp = oBeacon.getTemp();
|
||||
mv = oBeacon.getVolt();
|
||||
#ifdef VERBOSE
|
||||
Serial.println(oBeacon.toString().c_str());
|
||||
#endif
|
||||
}
|
||||
else if (strServiceData[0] == 0x00)
|
||||
{
|
||||
auto serviceData = strServiceData.c_str();
|
||||
int8_t rss0m = *(int8_t *)(serviceData + 1);
|
||||
calRssi = EDDYSTONE_ADD_1M + rss0m;
|
||||
setId(Sprintf("eddy:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
strServiceData[2], strServiceData[3], strServiceData[4], strServiceData[5], strServiceData[6],
|
||||
strServiceData[6], strServiceData[7], strServiceData[8], strServiceData[9], strServiceData[10],
|
||||
strServiceData[11], strServiceData[12], strServiceData[13], strServiceData[14], strServiceData[15],
|
||||
strServiceData[16], strServiceData[17]),
|
||||
ID_TYPE_EBEACON);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fingerprint = fingerprint + uuid.toString().c_str();
|
||||
}
|
||||
}
|
||||
if (haveTxPower)
|
||||
fingerprint = fingerprint + String(-txPower);
|
||||
setId(fingerprint, ID_TYPE_SD);
|
||||
}
|
||||
|
||||
void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice)
|
||||
void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice, bool haveTxPower, int8_t txPower)
|
||||
{
|
||||
std::string strManufacturerData = advertisedDevice->getManufacturerData();
|
||||
#ifdef VERBOSE
|
||||
|
@ -262,46 +281,43 @@ void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertis
|
|||
{
|
||||
BLEBeacon oBeacon = BLEBeacon();
|
||||
oBeacon.setData(strManufacturerData);
|
||||
setId(Sprintf("iBeacon:%s-%d-%d", std::string(oBeacon.getProximityUUID()).c_str(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor())), ID_TYPE_IBEACON);
|
||||
setId(Sprintf("iBeacon:%s-%u-%u", std::string(oBeacon.getProximityUUID()).c_str(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor())), ID_TYPE_IBEACON);
|
||||
calRssi = oBeacon.getSignalPower();
|
||||
}
|
||||
else if (strManufacturerData.length() >= 4 && strManufacturerData[2] == 0x10)
|
||||
{
|
||||
ignore = false;
|
||||
{
|
||||
String pid;
|
||||
if (advertisedDevice->haveTXPower())
|
||||
pid = Sprintf("apple:%02x%02x:%d%d", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length(), -advertisedDevice->getTXPower());
|
||||
else
|
||||
pid = Sprintf("apple:%02x%02x:%d", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length());
|
||||
setId(pid, ID_TYPE_APPLE_NEARBY);
|
||||
}
|
||||
String pid = Sprintf("apple:%02x%02x:%zu", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length());
|
||||
if (haveTxPower) pid += -txPower;
|
||||
setId(pid, ID_TYPE_APPLE_NEARBY);
|
||||
disc = hexStr(strManufacturerData.substr(4)).c_str();
|
||||
mdRssi = BleFingerprintCollection::refRssi + APPLE_TX;
|
||||
}
|
||||
else
|
||||
else if (strManufacturerData.length() >= 4)
|
||||
{
|
||||
if (advertisedDevice->haveTXPower())
|
||||
setId(Sprintf("apple:%02x%02x:%d%d", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length(), -advertisedDevice->getTXPower()), ID_TYPE_MISC_APPLE + ID_TYPE_TX_POW);
|
||||
else
|
||||
setId(Sprintf("apple:%02x%02x:%d", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length()), ID_TYPE_MISC_APPLE);
|
||||
String pid = Sprintf("apple:%02x%02x:%zu", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length());
|
||||
if (haveTxPower) pid += -txPower;
|
||||
setId(pid, ID_TYPE_MISC_APPLE);
|
||||
mdRssi = BleFingerprintCollection::refRssi + APPLE_TX;
|
||||
ignore = true;
|
||||
}
|
||||
}
|
||||
else if (manuf == "05a7") // Sonos
|
||||
{
|
||||
mdRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
mdRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("sonos:" + getMac(), ID_TYPE_SONOS);
|
||||
}
|
||||
else if (manuf == "0087") // Garmin
|
||||
{
|
||||
mdRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("garmin:" + getMac(), ID_TYPE_GARMIN);
|
||||
}
|
||||
else if (manuf == "0157") // Mi-fit
|
||||
{
|
||||
mdRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
mdRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("mifit:" + getMac(), ID_TYPE_MIFIT);
|
||||
}
|
||||
else if (manuf == "0006" && strManufacturerData.length() == 29) // microsoft
|
||||
{
|
||||
mdRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
mdRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId(Sprintf("msft:cdp:%02x%02x", strManufacturerData[3], strManufacturerData[5]), ID_TYPE_MSFT);
|
||||
disc = Sprintf("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
strManufacturerData[6], strManufacturerData[7], strManufacturerData[8], strManufacturerData[9], strManufacturerData[10],
|
||||
|
@ -311,22 +327,21 @@ void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertis
|
|||
}
|
||||
else if (manuf == "0075") // samsung
|
||||
{
|
||||
mdRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
mdRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
setId("samsung:" + getMac(), ID_TYPE_MISC);
|
||||
}
|
||||
else if (strManufacturerData.length() == 26 && strManufacturerData[2] == 0xBE && strManufacturerData[3] == 0xAC)
|
||||
else if (manuf == "beac" && strManufacturerData.length() == 26)
|
||||
{
|
||||
BLEBeacon oBeacon = BLEBeacon();
|
||||
oBeacon.setData(strManufacturerData.substr(0, 25));
|
||||
setId(Sprintf("altBeacon:%s-%d-%d", std::string(oBeacon.getProximityUUID()).c_str(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor())), ID_TYPE_ABEACON);
|
||||
setId(Sprintf("altBeacon:%s-%u-%u", std::string(oBeacon.getProximityUUID()).c_str(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor())), ID_TYPE_ABEACON);
|
||||
calRssi = oBeacon.getSignalPower();
|
||||
}
|
||||
else if (manuf != "0000")
|
||||
{
|
||||
mdRssi = advertisedDevice->haveTXPower() ? BleFingerprintCollection::refRssi + advertisedDevice->getTXPower() : NO_RSSI;
|
||||
String fingerprint = Sprintf("md:%s:%d", manuf.c_str(), strManufacturerData.length());
|
||||
if (advertisedDevice->haveTXPower())
|
||||
fingerprint = fingerprint + String(-advertisedDevice->getTXPower());
|
||||
mdRssi = haveTxPower ? BleFingerprintCollection::refRssi + txPower : NO_RSSI;
|
||||
String fingerprint = Sprintf("md:%s:%zu", manuf.c_str(), strManufacturerData.length());
|
||||
if (haveTxPower) fingerprint = fingerprint + String(-txPower);
|
||||
setId(fingerprint, ID_TYPE_MD);
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +407,7 @@ void BleFingerprint::setInitial(int initalRssi, float initalDistance)
|
|||
|
||||
bool BleFingerprint::report(JsonDocument *doc)
|
||||
{
|
||||
if (ignore || (idType == 0 && !macPublic) || hidden)
|
||||
if (ignore || idType == 0 || hidden)
|
||||
return false;
|
||||
|
||||
if (reported || !hasValue)
|
||||
|
@ -410,7 +425,7 @@ bool BleFingerprint::report(JsonDocument *doc)
|
|||
lastReported = output.value.position;
|
||||
reported = true;
|
||||
|
||||
(*doc)[F("id")] = getId();
|
||||
(*doc)[F("id")] = id;
|
||||
if (!name.isEmpty()) (*doc)[F("name")] = name;
|
||||
if (!disc.isEmpty()) (*doc)[F("disc")] = disc;
|
||||
if (idType) (*doc)[F("idType")] = idType;
|
||||
|
@ -423,9 +438,12 @@ bool BleFingerprint::report(JsonDocument *doc)
|
|||
(*doc)[F("speed")] = round(output.value.speed * 1e5f) / 100.0f;
|
||||
(*doc)[F("mac")] = SMacf(address);
|
||||
|
||||
(*doc)[F("interval")] = (now - firstSeenMillis) / seenCount;
|
||||
|
||||
if (mv) (*doc)[F("mV")] = mv;
|
||||
if (temp) (*doc)[F("temp")] = temp;
|
||||
if (humidity) (*doc)[F("rh")] = humidity;
|
||||
if (battery != 0xFF) (*doc)[F("batt")] = battery;
|
||||
if (temp) (*doc)[F("temp")] = round(temp*10)/10;
|
||||
if (humidity) (*doc)[F("rh")] = round(humidity*10)/10;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -436,7 +454,7 @@ bool BleFingerprint::query()
|
|||
if (rssi < -90) return false;
|
||||
auto now = millis();
|
||||
|
||||
if (now - lastSeenMillis > 5) return false;
|
||||
if (now - lastSeenMillis > 10) return false;
|
||||
|
||||
if (now - lastQryMillis < qryDelayMillis) return false;
|
||||
didQuery = true;
|
||||
|
@ -444,14 +462,18 @@ bool BleFingerprint::query()
|
|||
|
||||
bool success = false;
|
||||
|
||||
Serial.printf("%d Query | MAC: %s, ID: %-60s rssi %d\n", xPortGetCoreID(), getMac().c_str(), getId().c_str(), rssi);
|
||||
Serial.printf("%u Query | MAC: %s, ID: %-60s %lums\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), now - lastSeenMillis);
|
||||
|
||||
NimBLEClient *pClient = NimBLEDevice::getClientListSize() ? NimBLEDevice::getClientByPeerAddress(address) : nullptr;
|
||||
if (!pClient) pClient = NimBLEDevice::getDisconnectedClient();
|
||||
if (!pClient) pClient = NimBLEDevice::createClient();
|
||||
pClient->setClientCallbacks(&clientCB, false);
|
||||
pClient->setConnectionParams(12, 12, 0, 200);
|
||||
pClient->setConnectTimeout(5);
|
||||
NimBLEDevice::getScan()->stop();
|
||||
if (pClient->connect(address))
|
||||
{
|
||||
delay(100);
|
||||
bool iphone = true;
|
||||
if (allowQuery)
|
||||
{
|
||||
|
@ -461,14 +483,18 @@ bool BleFingerprint::query()
|
|||
if (!sName.empty() && sMdl.find(sName) == std::string::npos && sName != "Apple Watch")
|
||||
{
|
||||
if (setId(String("name:") + kebabify(sName).c_str(), ID_TYPE_QUERY_NAME, String(sName.c_str())))
|
||||
Serial.printf("\u001b[38;5;104m%d Name | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), getMac().c_str(), getId().c_str(), sName.c_str());
|
||||
{
|
||||
Serial.printf("\u001b[38;5;104m%u Name | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), sName.c_str());
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
|
||||
if (!sMdl.empty())
|
||||
{
|
||||
if (setId(String("apple:") + kebabify(sMdl).c_str(), ID_TYPE_QUERY_MODEL, String(sMdl.c_str())))
|
||||
Serial.printf("\u001b[38;5;136m%d Model | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), getMac().c_str(), getId().c_str(), sMdl.c_str());
|
||||
{
|
||||
Serial.printf("\u001b[38;5;136m%u Model | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), sMdl.c_str());
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +505,9 @@ bool BleFingerprint::query()
|
|||
if (!sRmAst.empty())
|
||||
{
|
||||
if (setId(String("roomAssistant:") + kebabify(sRmAst).c_str(), ID_TYPE_RM_ASST))
|
||||
Serial.printf("\u001b[38;5;129m%d RmAst | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), getMac().c_str(), getId().c_str(), sRmAst.c_str());
|
||||
{
|
||||
Serial.printf("\u001b[38;5;129m%u RmAst | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), sRmAst.c_str());
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
@ -490,7 +518,7 @@ bool BleFingerprint::query()
|
|||
if (success) return true;
|
||||
|
||||
qryAttempts++;
|
||||
Serial.printf("%d QryErr| MAC: %s, ID: %-60s rssi %d, try %d, retry after %dms\n", xPortGetCoreID(), getMac().c_str(), getId().c_str(), rssi, qryAttempts, qryDelayMillis);
|
||||
Serial.printf("%u QryErr| MAC: %s, ID: %-60s rssi %d, try %d, retry after %dms\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, qryAttempts, qryDelayMillis);
|
||||
|
||||
if (qryDelayMillis < 30000)
|
||||
qryDelayMillis += (1000 * qryAttempts * qryAttempts);
|
||||
|
@ -500,3 +528,23 @@ bool BleFingerprint::query()
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleFingerprint::shouldCount()
|
||||
{
|
||||
bool prevCounting = counting;
|
||||
if (ignore || !countable)
|
||||
counting = false;
|
||||
else if (getMsSinceFirstSeen() <= BleFingerprintCollection::countMs || getMsSinceLastSeen() > BleFingerprintCollection::countMs)
|
||||
counting = false;
|
||||
else if (counting && output.value.position > BleFingerprintCollection::countExit)
|
||||
counting = false;
|
||||
else if (!counting && output.value.position <= BleFingerprintCollection::countEnter)
|
||||
counting = true;
|
||||
|
||||
if (prevCounting != counting)
|
||||
{
|
||||
counting ? GUI::plusOne(this) : GUI::minusOne(this);
|
||||
}
|
||||
|
||||
return counting;
|
||||
}
|
||||
|
|
|
@ -15,17 +15,18 @@
|
|||
#define NO_RSSI (-32768)
|
||||
|
||||
#define ID_TYPE_TX_POW short(1)
|
||||
#define ID_TYPE_MISC_APPLE short(-5)
|
||||
|
||||
#define ID_TYPE_MAC short(0)
|
||||
#define ID_TYPE_AD short(10)
|
||||
#define ID_TYPE_SD short(15)
|
||||
#define ID_TYPE_MD short(20)
|
||||
#define ID_TYPE_MISC_APPLE short(25)
|
||||
#define ID_TYPE_MISC short(30)
|
||||
#define ID_TYPE_NAME short(35)
|
||||
#define ID_TYPE_PUBLIC_MAC short(50)
|
||||
#define ID_TYPE_MSFT short(100)
|
||||
#define ID_TYPE_SONOS short(105)
|
||||
#define ID_TYPE_GARMIN short(107)
|
||||
#define ID_TYPE_MITHERM short(110)
|
||||
#define ID_TYPE_MIFIT short(115)
|
||||
#define ID_TYPE_EXPOSURE short(120)
|
||||
|
@ -34,6 +35,7 @@
|
|||
#define ID_TYPE_TILE short( 135)
|
||||
#define ID_TYPE_MEATER short(140)
|
||||
#define ID_TYPE_VANMOOF short(145)
|
||||
#define ID_TYPE_SMARTTAG short(146)
|
||||
#define ID_TYPE_APPLE_NEARBY short(150)
|
||||
#define ID_TYPE_QUERY_MODEL short(155)
|
||||
#define ID_TYPE_QUERY_NAME short(160)
|
||||
|
@ -41,6 +43,7 @@
|
|||
#define ID_TYPE_ABEACON short(170)
|
||||
#define ID_TYPE_IBEACON short(175)
|
||||
#define ID_TYPE_RM_ASST short(180)
|
||||
#define ID_TYPE_KNOWN_MAC short(185)
|
||||
|
||||
class BleFingerprintCollection;
|
||||
|
||||
|
@ -56,13 +59,7 @@ public:
|
|||
|
||||
bool query();
|
||||
|
||||
String getId()
|
||||
{
|
||||
if (!id.isEmpty() && idType > 10) return id;
|
||||
if (macPublic) return getMac();
|
||||
if (!id.isEmpty()) return id;
|
||||
return getMac();
|
||||
}
|
||||
String getId() { return id; }
|
||||
|
||||
bool setId(const String &newId, short int newIdType, const String &newName = "");
|
||||
|
||||
|
@ -82,7 +79,9 @@ public:
|
|||
|
||||
NimBLEAddress const getAddress() { return address; }
|
||||
|
||||
long getAge() const { return millis() - lastSeenMillis; };
|
||||
unsigned long getMsSinceLastSeen() const { return millis() - lastSeenMillis; };
|
||||
|
||||
unsigned long getMsSinceFirstSeen() const { return millis() - firstSeenMillis; };
|
||||
|
||||
bool getAdded() const { return added; };
|
||||
|
||||
|
@ -92,26 +91,30 @@ public:
|
|||
|
||||
bool getRmAsst() const { return rmAsst; };
|
||||
|
||||
int getSeenCount()
|
||||
unsigned int getSeenCount()
|
||||
{
|
||||
auto sc = seenCount;
|
||||
seenCount = 0;
|
||||
auto sc = seenCount - lastSeenCount;
|
||||
lastSeenCount = seenCount;
|
||||
return sc;
|
||||
}
|
||||
|
||||
bool shouldCount();
|
||||
|
||||
private:
|
||||
|
||||
static bool shouldHide(const String &s);
|
||||
|
||||
bool hasValue = false, added = false, close = false, reported = false, macPublic = false, ignore = false, allowQuery = false, didQuery = false, rmAsst = false, hidden = false, connectable = false;
|
||||
bool hasValue = false, added = false, close = false, reported = false, ignore = false, allowQuery = false, didQuery = false, rmAsst = false, hidden = false, connectable = false, countable = false, counting = false;
|
||||
NimBLEAddress address;
|
||||
String id, name, disc;
|
||||
short int idType = 0;
|
||||
int rssi = -100, calRssi = NO_RSSI, mdRssi = NO_RSSI, asRssi = NO_RSSI, newest = NO_RSSI, recent = NO_RSSI, oldest = NO_RSSI;
|
||||
int qryAttempts = 0, seenCount = 1, qryDelayMillis = 0;
|
||||
unsigned int qryAttempts = 0, qryDelayMillis = 0;
|
||||
float raw = 0, lastReported = 0, temp = 0, humidity = 0;
|
||||
unsigned long firstSeenMillis, lastSeenMillis = 0, lastReportedMillis = 0, lastQryMillis = 0;
|
||||
unsigned long seenCount = 1, lastSeenCount = 0;
|
||||
uint16_t mv = 0;
|
||||
uint8_t battery = 0xFF;
|
||||
|
||||
Reading<Differential<float>> output;
|
||||
|
||||
|
@ -122,11 +125,11 @@ private:
|
|||
|
||||
void fingerprint(NimBLEAdvertisedDevice *advertisedDevice);
|
||||
|
||||
void fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceAdvCount);
|
||||
void fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceAdvCount, bool haveTxPower, int8_t txPower);
|
||||
|
||||
void fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceDataCount);
|
||||
void fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDevice, size_t serviceDataCount, bool haveTxPower, int8_t txPower);
|
||||
|
||||
void fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice);
|
||||
void fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice, bool haveTxPower, int8_t txPower);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,7 @@ void BleFingerprintCollection::cleanupOldFingerprints()
|
|||
auto it = fingerprints.begin();
|
||||
while (it != fingerprints.end())
|
||||
{
|
||||
long age = (*it)->getAge();
|
||||
auto age = (*it)->getMsSinceLastSeen();
|
||||
if (age > forgetMs)
|
||||
{
|
||||
GUI::removed((*it));
|
||||
|
@ -54,7 +54,7 @@ BleFingerprint *BleFingerprintCollection::getFingerprint(BLEAdvertisedDevice *ad
|
|||
return f;
|
||||
}
|
||||
|
||||
std::list<BleFingerprint *> BleFingerprintCollection::getCopy()
|
||||
const std::list<BleFingerprint *> BleFingerprintCollection::getCopy()
|
||||
{
|
||||
if (xSemaphoreTake(fingerprintSemaphore, 1000) != pdTRUE)
|
||||
log_e("Couldn't take semaphore!");
|
||||
|
@ -62,8 +62,13 @@ std::list<BleFingerprint *> BleFingerprintCollection::getCopy()
|
|||
std::list<BleFingerprint *> copy(fingerprints);
|
||||
if (xSemaphoreGive(fingerprintSemaphore) != pdTRUE)
|
||||
log_e("Couldn't give semaphore!");
|
||||
return copy;
|
||||
return std::move(copy);
|
||||
}
|
||||
String BleFingerprintCollection::include{}, BleFingerprintCollection::exclude{}, BleFingerprintCollection::query{}, BleFingerprintCollection::knownMacs{}, BleFingerprintCollection::countIds{};
|
||||
float BleFingerprintCollection::skipDistance = 0.0f, BleFingerprintCollection::maxDistance = 0.0f, BleFingerprintCollection::absorption = 3.5f, BleFingerprintCollection::countEnter = 2, BleFingerprintCollection::countExit = 4;
|
||||
int BleFingerprintCollection::refRssi = 0, BleFingerprintCollection::forgetMs = 0, BleFingerprintCollection::skipMs = 0, BleFingerprintCollection::countMs = 10000;
|
||||
|
||||
const std::list<BleFingerprint *>* const BleFingerprintCollection::getNative()
|
||||
{
|
||||
return &fingerprints;
|
||||
}
|
||||
String BleFingerprintCollection::include{}, BleFingerprintCollection::exclude{}, BleFingerprintCollection::query{};
|
||||
float BleFingerprintCollection::skipDistance = 0.0f, BleFingerprintCollection::maxDistance = 0.0f, BleFingerprintCollection::absorption = 3.5f;
|
||||
int BleFingerprintCollection::refRssi = 0, BleFingerprintCollection::forgetMs = 0, BleFingerprintCollection::skipMs = 0;
|
||||
|
|
|
@ -18,12 +18,15 @@ public:
|
|||
}
|
||||
BleFingerprint *getFingerprint(BLEAdvertisedDevice *advertisedDevice);
|
||||
void cleanupOldFingerprints();
|
||||
std::list<BleFingerprint *> getCopy();
|
||||
const std::list<BleFingerprint *>* const getNative();
|
||||
const std::list<BleFingerprint *> getCopy();
|
||||
void setDisable(bool disable) { _disable = disable; }
|
||||
|
||||
static String include, exclude, query;
|
||||
static String knownMacs, include, exclude, query;
|
||||
static float skipDistance, maxDistance, absorption;
|
||||
static int refRssi, forgetMs, skipMs;
|
||||
static String countIds;
|
||||
static float countEnter, countExit;
|
||||
static int countMs;
|
||||
|
||||
private:
|
||||
bool _disable = false;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "GUI.h"
|
||||
#ifdef M5STICK
|
||||
#include "tb_display.h"
|
||||
#endif
|
||||
|
||||
#if defined M5STICK
|
||||
|
||||
|
@ -57,8 +60,6 @@ void GUI::erased()
|
|||
|
||||
void GUI::connecting()
|
||||
{
|
||||
status("Connecting...");
|
||||
connected(false, false);
|
||||
#ifdef LED_BUILTIN
|
||||
if (GUI::statusLed) digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
||||
#endif
|
||||
|
@ -85,26 +86,36 @@ void GUI::connected(bool wifi = false, bool mqtt = false)
|
|||
void GUI::added(BleFingerprint *f)
|
||||
{
|
||||
if (f->getIgnore()) return;
|
||||
Serial.printf("%d New %s | MAC: %s, ID: %-60s %s\n", xPortGetCoreID(), f->getRmAsst() ? "R" : (f->getAllowQuery() ? "Q" : " "), f->getMac().c_str(), f->getId().c_str(), f->getDiscriminator().c_str());
|
||||
Serial.printf("%u New %s | MAC: %s, ID: %-60s %s\n", xPortGetCoreID(), f->getRmAsst() ? "R" : (f->getAllowQuery() ? "Q" : " "), f->getMac().c_str(), f->getId().c_str(), f->getDiscriminator().c_str());
|
||||
}
|
||||
|
||||
void GUI::removed(BleFingerprint *f)
|
||||
{
|
||||
if (f->getIgnore() || !f->getAdded()) return;
|
||||
Serial.printf("\u001b[38;5;236m%d Del | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDiscriminator().c_str());
|
||||
Serial.printf("\u001b[38;5;236m%u Del | MAC: %s, ID: %-60s %s\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDiscriminator().c_str());
|
||||
}
|
||||
|
||||
void GUI::plusOne(BleFingerprint *f)
|
||||
{
|
||||
Serial.printf("\u001b[36m%u C# +1 | MAC: %s, ID: %-60s (%.2fm) %lums\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDistance(), f->getMsSinceLastSeen());
|
||||
}
|
||||
|
||||
void GUI::minusOne(BleFingerprint *f)
|
||||
{
|
||||
Serial.printf("\u001b[35m%u C# -1 | MAC: %s, ID: %-60s (%.2fm) %lums\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDistance(), f->getMsSinceLastSeen());
|
||||
}
|
||||
|
||||
void GUI::close(BleFingerprint *f)
|
||||
{
|
||||
if (f->getIgnore()) return;
|
||||
Serial.printf("\u001b[32m%d Close | MAC: %s, ID: %-60s (%.2fm) %ddBm\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDistance(), f->getNewestRssi());
|
||||
Serial.printf("\u001b[32m%u Close | MAC: %s, ID: %-60s (%.2fm) %ddBm\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDistance(), f->getNewestRssi());
|
||||
status("C: %s", f->getId().c_str());
|
||||
}
|
||||
|
||||
void GUI::left(BleFingerprint *f)
|
||||
{
|
||||
if (f->getIgnore()) return;
|
||||
Serial.printf("\u001b[33m%d Left | MAC: %s, ID: %-60s (%.2fm) %ddBm\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDistance(), f->getNewestRssi());
|
||||
Serial.printf("\u001b[33m%u Left | MAC: %s, ID: %-60s (%.2fm) %ddBm\u001b[0m\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getDistance(), f->getNewestRssi());
|
||||
status("L: %s", f->getId().c_str());
|
||||
}
|
||||
|
||||
|
@ -112,18 +123,18 @@ void GUI::added(BleFingerprint *f)
|
|||
{
|
||||
begin();
|
||||
#ifdef M5STICK
|
||||
sprite.fillSprite(TFT_BLACK);
|
||||
sprite.setTextDatum(MC_DATUM);
|
||||
|
||||
char *message;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vasprintf(&message, format, args);
|
||||
va_end(args);
|
||||
tb_display_print_String(message);
|
||||
tb_display_print_String("\n");
|
||||
#ifdef PLUS
|
||||
sprite.drawString(message, sprite.width() / 2, sprite.height() / 2, 4);
|
||||
//drawString(message, sprite.width() / 2, sprite.height() / 2, 4);
|
||||
#else
|
||||
sprite.drawString(message, sprite.width() / 2, sprite.height() / 2, 1);
|
||||
|
||||
//sprite.drawString(message, sprite.width() / 2, sprite.height() / 2, 1);
|
||||
#endif
|
||||
free(message);
|
||||
dirty = true;
|
||||
|
@ -143,29 +154,15 @@ void GUI::added(BleFingerprint *f)
|
|||
{
|
||||
#ifdef M5STICK
|
||||
M5.begin(true, true, false);
|
||||
M5.Lcd.setRotation(3);
|
||||
sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());
|
||||
sprite.setSwapBytes(true);
|
||||
M5.Axp.ScreenBreath(12);
|
||||
tb_display_init(3);
|
||||
#elif defined M5ATOM
|
||||
M5.begin(false, false, true);
|
||||
M5.dis.drawpix(0, CRGB(64, 0, 0));
|
||||
#endif
|
||||
GUI::init = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::blit()
|
||||
{
|
||||
begin();
|
||||
#ifdef M5STICK
|
||||
if (dirty)
|
||||
{
|
||||
sprite.pushSprite(0, 0);
|
||||
M5.Axp.ScreenBreath(12);
|
||||
dirty = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUI::updateStart()
|
||||
{
|
||||
|
@ -193,5 +190,4 @@ bool GUI::statusLed=false;
|
|||
|
||||
#ifdef M5STICK
|
||||
bool GUI::dirty = false;
|
||||
TFT_eSprite GUI::sprite(&M5.Lcd);
|
||||
#endif
|
||||
|
|
|
@ -40,10 +40,12 @@ public:
|
|||
static void connected(bool wifi, bool mqtt);
|
||||
|
||||
static void status(const char *message, ...);
|
||||
static void blit();
|
||||
|
||||
static bool statusLed;
|
||||
|
||||
static void plusOne(BleFingerprint *f);
|
||||
static void minusOne(BleFingerprint *f);
|
||||
|
||||
private:
|
||||
static void begin();
|
||||
|
||||
|
|
|
@ -74,3 +74,49 @@ std::string hexStr(const std::string& s)
|
|||
{
|
||||
return hexStr(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
std::string hexStr(const uint8_t *&s, unsigned int len)
|
||||
{
|
||||
return hexStr(reinterpret_cast<const char *>(s), len);
|
||||
}
|
||||
|
||||
std::string hexStrRev(const char *data, unsigned int len)
|
||||
{
|
||||
constexpr char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
std::string s(len * 2, ' ');
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
s[len - (2 * i + 1)] = hexmap[(data[i] & 0xF0) >> 4];
|
||||
s[len - (2 * i + 2)] = hexmap[data[i] & 0x0F];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string hexStrRev(const uint8_t *&s, unsigned int len)
|
||||
{
|
||||
return hexStrRev(reinterpret_cast<const char *>(s), len);
|
||||
}
|
||||
|
||||
std::string hexStrRev(const std::string &s)
|
||||
{
|
||||
return hexStrRev(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
bool prefixExists(const String& prefixes, const String& s)
|
||||
{
|
||||
unsigned int start = 0;
|
||||
unsigned int space;
|
||||
|
||||
while ((space = prefixes.indexOf(" ", start)) != -1)
|
||||
{
|
||||
if (space > start)
|
||||
{
|
||||
auto sub = prefixes.substring(start, space);
|
||||
if (s.indexOf(sub) != -1) return true;
|
||||
}
|
||||
start = space + 1;
|
||||
}
|
||||
auto sub = prefixes.substring(start);
|
||||
return !sub.isEmpty() && s.indexOf(sub) != -1;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@ std::string slugify(const std::string& text);
|
|||
String slugify(const String& text);
|
||||
std::string kebabify(const std::string& text);
|
||||
String kebabify(const String& text);
|
||||
std::string hexStr(const uint8_t *data, int len);
|
||||
std::string hexStr(const char *data, int len);
|
||||
std::string hexStr(const std::string& s);
|
||||
std::string hexStrRev(const uint8_t *data, int len);
|
||||
std::string hexStrRev(const char *data, int len);
|
||||
std::string hexStrRev(const std::string &s);
|
||||
bool prefixExists(const String& prefixes, const String& s);
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
static BLEUUID eddystoneUUID((uint16_t)0xFEAA);
|
||||
static BLEUUID tileUUID((uint16_t)0xFEED);
|
||||
static BLEUUID exposureUUID((uint16_t)0xFD6F);
|
||||
static BLEUUID smartTagUUID((uint16_t)0xFD5A);
|
||||
static BLEUUID sonosUUID((uint16_t)0xFE07);
|
||||
static BLEUUID itagUUID((uint16_t)0xffe0);
|
||||
static BLEUUID miThermUUID(uint16_t(0x181A));
|
||||
|
|
|
@ -14,19 +14,23 @@ default_envs = esp32
|
|||
[common]
|
||||
debug_build_flags = -O0 -ggdb3 -g3 -DDEBUG_TLS_MEM
|
||||
build_flags =
|
||||
-D MQTT_MAX_PACKET_SIZE=1024
|
||||
-D MQTT_MIN_FREE_MEMORY=8128
|
||||
-D SECURE_CLIENT=SECURE_CLIENT_BEARSSL
|
||||
-D BEARSSL_SSL_BASIC
|
||||
-D CONFIG_BT_NIMBLE_PINNED_TO_CORE=1
|
||||
-D CONFIG_BT_NIMBLE_MAX_BONDS=0
|
||||
-D CONFIG_BT_NIMBLE_MAX_CCCDS=0
|
||||
-D CONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED
|
||||
-D CONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED
|
||||
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
||||
platform = espressif32@3.2
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
haimoz/SoftFilters@^0.1.0
|
||||
marvinroger/AsyncMqttClient@^0.9.0
|
||||
bblanchon/ArduinoJson@^6.17.3
|
||||
bblanchon/ArduinoJson@^6.19.3
|
||||
https://github.com/ESPresense/ESP-WiFiSettings.git
|
||||
https://github.com/h2zero/NimBLE-Arduino.git#1.3.3
|
||||
https://github.com/ESPresense/NimBLE-Arduino.git
|
||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||
bbx10/DNSServer@^1.1.0
|
||||
|
||||
|
@ -50,7 +54,7 @@ lib_deps = ${common.lib_deps}
|
|||
board_build.partitions = partitions_singleapp.csv
|
||||
monitor_port = /dev/cu.usbserial-*1
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder
|
||||
monitor_filters = esp32_exception_decoder, time
|
||||
debug_build_flags = ${common.debug_build_flags}
|
||||
build_flags = ${common.build_flags}
|
||||
|
||||
|
@ -101,6 +105,7 @@ framework = ${common.framework}
|
|||
board = m5stick-c
|
||||
lib_deps =
|
||||
m5stack/M5StickC@^0.2.0
|
||||
https://github.com/ESPresense/M5StickC-TB_Display.git
|
||||
${common.lib_deps}
|
||||
board_build.partitions = partitions_singleapp.csv
|
||||
monitor_speed = 115200
|
||||
|
@ -116,6 +121,7 @@ framework = ${common.framework}
|
|||
board = m5stick-c
|
||||
lib_deps =
|
||||
m5stack/M5StickCPlus@^0.0.2
|
||||
https://github.com/ESPresense/M5StickC-TB_Display.git
|
||||
${common.lib_deps}
|
||||
board_build.partitions = partitions_singleapp.csv
|
||||
monitor_speed = 115200
|
||||
|
@ -211,6 +217,7 @@ framework = ${common.framework}
|
|||
board = m5stick-c
|
||||
lib_deps =
|
||||
m5stack/M5StickC@^0.2.0
|
||||
https://github.com/ESPresense/M5StickC-TB_Display.git
|
||||
${common.lib_deps}
|
||||
${common_sensors.lib_deps}
|
||||
board_build.partitions = partitions_singleapp.csv
|
||||
|
@ -228,6 +235,7 @@ framework = ${common.framework}
|
|||
board = m5stick-c
|
||||
lib_deps =
|
||||
m5stack/M5StickCPlus@^0.0.2
|
||||
https://github.com/ESPresense/M5StickC-TB_Display.git
|
||||
${common.lib_deps}
|
||||
${common_sensors.lib_deps}
|
||||
board_build.partitions = partitions_singleapp.csv
|
||||
|
|
|
@ -1,31 +1,27 @@
|
|||
#ifdef VERBOSE
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#endif
|
||||
|
||||
//Replace with your MQTT Broker address
|
||||
// Replace with your MQTT Broker address
|
||||
#define DEFAULT_MQTT_HOST "mqtt.z13.org"
|
||||
|
||||
//Replace with your MQTT Broker port
|
||||
// Replace with your MQTT Broker port
|
||||
#define DEFAULT_MQTT_PORT 1883
|
||||
|
||||
//Replace with your MQTT Broker user
|
||||
// Replace with your MQTT Broker user
|
||||
#define DEFAULT_MQTT_USER ""
|
||||
|
||||
//Replace with your MQTT Broker password
|
||||
// Replace with your MQTT Broker password
|
||||
#define DEFAULT_MQTT_PASSWORD ""
|
||||
|
||||
// Maximum distance (in meters) to report. Devices that are calculated to be further than this distance in meters will not be reported
|
||||
#define DEFAULT_MAX_DISTANCE 16
|
||||
|
||||
//Define the base topic for room detection. Usually "espresense"
|
||||
// Define the base topic for room detection. Usually "espresense"
|
||||
#define CHANNEL String("espresense")
|
||||
|
||||
#define DEFAULT_QUERY ""
|
||||
#define DEFAULT_INCLUDE ""
|
||||
#define DEFAULT_EXCLUDE ""
|
||||
|
||||
#define BLE_SCAN_INTERVAL 40 // Used to determine antenna sharing between Bluetooth and Wi-Fi. Do not modify unless you are confident you know what you're doing
|
||||
#define BLE_SCAN_WINDOW 30 // Used to determine antenna sharing between Bluetooth and Wi-Fi. Do not modify unless you are confident you know what you're doing
|
||||
#define BLE_SCAN_INTERVAL 0x80
|
||||
#define BLE_SCAN_WINDOW 0x80
|
||||
|
||||
#define DEFAULT_REF_RSSI (-65)
|
||||
#define DEFAULT_ABSORPTION (3.5)
|
||||
|
@ -48,8 +44,8 @@
|
|||
|
||||
#ifdef VERSION
|
||||
#define DEFAULT_AUTO_UPDATE true
|
||||
#define DEFAULT_OTA_UPDATE false
|
||||
#define DEFAULT_ARDUINO_OTA false
|
||||
#else
|
||||
#define DEFAULT_AUTO_UPDATE false
|
||||
#define DEFAULT_OTA_UPDATE true
|
||||
#define DEFAULT_ARDUINO_OTA true
|
||||
#endif
|
||||
|
|
229
src/main.cpp
229
src/main.cpp
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "MotionSensors.h"
|
||||
|
||||
bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int totalFpReported)
|
||||
bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int totalFpReported, int count)
|
||||
{
|
||||
if (!online)
|
||||
{
|
||||
|
@ -19,7 +19,11 @@ bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int total
|
|||
|
||||
if (discovery && !sentDiscovery)
|
||||
{
|
||||
if (sendDiscoveryConnectivity() && sendDiscoveryUptime() && sendDiscoveryFreeMem() && sendButtonDiscovery("Restart", "diagnostic") && sendSwitchDiscovery("Status LED", "config") && sendNumberDiscovery("Max Distance", "config") && sendNumberDiscovery("Absorption", "config") && sendSwitchDiscovery("Active Scan", "config") && sendSwitchDiscovery("Auto Update", "config") && sendSwitchDiscovery("OTA Update", "config") && sendSwitchDiscovery("Prerelease", "config") && sendDeleteDiscovery("switch", "Query") && Motion::SendDiscovery(doc)
|
||||
if (sendDiscoveryConnectivity() && sendTeleSensorDiscovery("Uptime", EC_DIAGNOSTIC, "{{ value_json.uptime }}", "s") && sendTeleSensorDiscovery("Free Mem", EC_DIAGNOSTIC, "{{ value_json.freeHeap }}", "bytes") && (BleFingerprintCollection::countIds.isEmpty() ? sendDeleteDiscovery("sensor", "Count") : sendTeleSensorDiscovery("Count", "", "{{ value_json.count }}", "")) && sendButtonDiscovery("Restart", EC_DIAGNOSTIC) && sendSwitchDiscovery("Status LED", EC_CONFIG) && sendNumberDiscovery("Max Distance", EC_CONFIG) && sendNumberDiscovery("Absorption", EC_CONFIG) && sendSwitchDiscovery("Active Scan", EC_CONFIG) && sendSwitchDiscovery("Auto Update", EC_CONFIG) && sendSwitchDiscovery("Arduino OTA", EC_CONFIG) && sendSwitchDiscovery("Prerelease", EC_CONFIG) && sendDeleteDiscovery("switch", "OTA Update") && Motion::SendDiscovery(doc)
|
||||
#ifdef MACCHINA_A0
|
||||
&& sendTeleSensorDiscovery("Battery", "", "{{ value_json.batt }}", "%")
|
||||
&& sendTeleBinarySensorDiscovery("Running", "", "{{ value_json.run }}", "running")
|
||||
#endif
|
||||
#ifdef SENSORS
|
||||
&& sendDiscoveryHumidity() && sendDiscoveryTemperature() && sendDiscoveryLux() && sendDiscoveryBME280Temperature() && sendDiscoveryBME280Humidity() && sendDiscoveryBME280Pressure() && sendDiscoveryTSL2561Lux()
|
||||
#endif
|
||||
|
@ -48,11 +52,19 @@ bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int total
|
|||
#endif
|
||||
doc["rssi"] = WiFi.RSSI();
|
||||
#ifdef MACCHINA_A0
|
||||
doc["batt"] = a0_read_batt_mv() / 1000.0f;
|
||||
auto mv = a0_read_batt_mv();
|
||||
doc["mV"] = mv;
|
||||
bool run = (mv > 13200);
|
||||
unsigned int soc = round(-13275.04 + 2.049731 * mv - (0.00007847975 * mv) * mv);
|
||||
doc["batt"] = run ? (unsigned int)100 : max((unsigned int)0, min((unsigned int)100, soc));
|
||||
doc["run"] = run ? "ON" : "OFF";
|
||||
#endif
|
||||
#ifdef VERSION
|
||||
doc["ver"] = String(VERSION);
|
||||
#endif
|
||||
|
||||
if (!BleFingerprintCollection::countIds.isEmpty())
|
||||
doc["count"] = count;
|
||||
if (totalSeen > 0)
|
||||
doc["adverts"] = totalSeen;
|
||||
if (totalFpSeen > 0)
|
||||
|
@ -90,12 +102,7 @@ bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int total
|
|||
void connectToWifi()
|
||||
{
|
||||
Serial.printf("Connecting to WiFi (%s)...\n", WiFi.macAddress().c_str());
|
||||
GUI::blit();
|
||||
|
||||
WiFiSettings.onConnect = []()
|
||||
{
|
||||
GUI::connected(false, false);
|
||||
};
|
||||
GUI::connected(false, false);
|
||||
|
||||
WiFiSettings.onFailure = []()
|
||||
{
|
||||
|
@ -118,46 +125,54 @@ void connectToWifi()
|
|||
#endif
|
||||
room = WiFiSettings.string("room", ESPMAC, "Room");
|
||||
|
||||
WiFiSettings.heading("MQTT Connection");
|
||||
WiFiSettings.heading("MQTT <a href='https://espresense.com/settings#mqtt' target='_blank'>ℹ️</a>", false);
|
||||
mqttHost = WiFiSettings.string("mqtt_host", DEFAULT_MQTT_HOST, "Server");
|
||||
mqttPort = WiFiSettings.integer("mqtt_port", DEFAULT_MQTT_PORT, "Port");
|
||||
mqttUser = WiFiSettings.string("mqtt_user", DEFAULT_MQTT_USER, "Username");
|
||||
mqttPass = WiFiSettings.string("mqtt_pass", DEFAULT_MQTT_PASSWORD, "Password");
|
||||
|
||||
WiFiSettings.heading("Preferences");
|
||||
GUI::statusLed = WiFiSettings.checkbox("status_led", true, "Status LED");
|
||||
|
||||
autoUpdate = WiFiSettings.checkbox("auto_update", DEFAULT_AUTO_UPDATE, "Automatically update");
|
||||
prerelease = WiFiSettings.checkbox("prerelease", false, "Include pre-released versions in auto-update");
|
||||
|
||||
otaUpdate = WiFiSettings.checkbox("ota_update", DEFAULT_OTA_UPDATE, "Arduino OTA Update");
|
||||
discovery = WiFiSettings.checkbox("discovery", true, "Home Assistant Discovery");
|
||||
activeScan = WiFiSettings.checkbox("active_scan", false, "Active scanning (uses more battery but more results)");
|
||||
discovery = WiFiSettings.checkbox("discovery", true, "Send to discovery topic");
|
||||
publishTele = WiFiSettings.checkbox("pub_tele", true, "Send to telemetry topic");
|
||||
publishRooms = WiFiSettings.checkbox("pub_rooms", true, "Send to rooms topic");
|
||||
publishDevices = WiFiSettings.checkbox("pub_devices", true, "Send to devices topic");
|
||||
|
||||
WiFiSettings.heading("Filtering");
|
||||
WiFiSettings.heading("Room Count <a href='https://espresense.com/settings#room-count' target='_blank'>ℹ️</a>", false);
|
||||
BleFingerprintCollection::countIds = WiFiSettings.string("count_ids", "", "Include device ids (space seperated ids)");
|
||||
BleFingerprintCollection::countEnter = WiFiSettings.floating("count_enter", 0, 100, 2, "Start counting devices less than distance (in meters)");
|
||||
BleFingerprintCollection::countExit = WiFiSettings.floating("count_exit", 0, 100, 4, "Stop counting devices greater than distance (in meters)");
|
||||
BleFingerprintCollection::countMs = WiFiSettings.integer("count_ms", 0, 3000000, 30000, "Include devices with age less than (in ms)");
|
||||
|
||||
WiFiSettings.heading("Updating <a href='https://espresense.com/settings#updating' target='_blank'>ℹ️</a>", false);
|
||||
autoUpdate = WiFiSettings.checkbox("auto_update", DEFAULT_AUTO_UPDATE, "Automatically update");
|
||||
prerelease = WiFiSettings.checkbox("prerelease", false, "Include pre-released versions in auto-update");
|
||||
arduinoOta = WiFiSettings.checkbox("arduino_ota", DEFAULT_ARDUINO_OTA, "Arduino OTA Update");
|
||||
|
||||
WiFiSettings.heading("Scanning <a href='https://espresense.com/settings#scanning' target='_blank'>ℹ️</a>", false);
|
||||
activeScan = WiFiSettings.checkbox("active_scan", false, "Request scan results (usually not needed)");
|
||||
BleFingerprintCollection::knownMacs = WiFiSettings.string("known_macs", "", "Known BLE mac addresses (no colons, space seperated)");
|
||||
BleFingerprintCollection::query = WiFiSettings.string("query", DEFAULT_QUERY, "Query device ids for characteristics (eg. apple:1005:9-26)");
|
||||
|
||||
WiFiSettings.heading("Filtering <a href='https://espresense.com/settings#filtering' target='_blank'>ℹ️</a>", false);
|
||||
if (BleFingerprintCollection::query == "1") BleFingerprintCollection::query = "apple:10"; // This is to keep query=true doing the same thing as older firmwares
|
||||
BleFingerprintCollection::include = WiFiSettings.string("include", DEFAULT_INCLUDE, "If set will only send matching to mqtt (eg. apple:iphone10-6 apple:iphone13-2)");
|
||||
BleFingerprintCollection::include = WiFiSettings.string("include", DEFAULT_INCLUDE, "Include only sending these ids to mqtt (eg. apple:iphone10-6 apple:iphone13-2)");
|
||||
BleFingerprintCollection::exclude = WiFiSettings.string("exclude", DEFAULT_EXCLUDE, "Exclude sending these ids to mqtt (eg. exp:20 apple:iphone10-6)");
|
||||
BleFingerprintCollection::maxDistance = WiFiSettings.floating("max_dist", 0, 100, DEFAULT_MAX_DISTANCE, "Maximum distance to report (in meters)");
|
||||
BleFingerprintCollection::skipDistance = WiFiSettings.floating("skip_dist", 0, 10, DEFAULT_SKIP_DISTANCE, "Report early if beacon has moved more than this distance (in meters)");
|
||||
BleFingerprintCollection::skipMs = WiFiSettings.integer("skip_ms", 0, 3000000, DEFAULT_SKIP_MS, "Skip reporting if message age is less that this (in milliseconds)");
|
||||
|
||||
WiFiSettings.heading("Calibration");
|
||||
WiFiSettings.heading("Calibration <a href='https://espresense.com/settings#calibration' target='_blank'>ℹ️</a>", false);
|
||||
BleFingerprintCollection::refRssi = WiFiSettings.integer("ref_rssi", -100, 100, DEFAULT_REF_RSSI, "Rssi expected from a 0dBm transmitter at 1 meter");
|
||||
BleFingerprintCollection::absorption = WiFiSettings.floating("absorption", -100, 100, DEFAULT_ABSORPTION, "Factor used to account for absorption, reflection, or diffraction");
|
||||
BleFingerprintCollection::forgetMs = WiFiSettings.integer("forget_ms", 0, 3000000, DEFAULT_FORGET_MS, "Forget beacon if not seen for (in milliseconds)");
|
||||
|
||||
WiFiSettings.heading("Additional Sensors");
|
||||
WiFiSettings.heading("Misc <a href='https://espresense.com/settings#misc' target='_blank'>ℹ️</a>", false);
|
||||
GUI::statusLed = WiFiSettings.checkbox("status_led", true, "Status LED");
|
||||
Motion::ConnectToWifi();
|
||||
#ifdef SENSORS
|
||||
dht11Pin = WiFiSettings.integer("dht11_pin", 0, "DHT11 sensor pin (0 for disable)");
|
||||
dht22Pin = WiFiSettings.integer("dht22_pin", 0, "DHT22 sensor pin (0 for disable)");
|
||||
dhtTempOffset = WiFiSettings.floating("dhtTemp_offset", -40, 125, 0.0, "DHT temperature offset");
|
||||
|
||||
WiFiSettings.heading("I2C Settings");
|
||||
WiFiSettings.heading("I2C Settings <a href='https://espresense.com/settings#i2c-settings' target='_blank'>ℹ️</a>", false);
|
||||
|
||||
I2CDebug = WiFiSettings.checkbox("I2CDebug", false, "Debug I2C addreses. Look at the serial log to get the correct address");
|
||||
|
||||
|
@ -170,7 +185,7 @@ void connectToWifi()
|
|||
I2C_Bus_2_SDA = WiFiSettings.integer("I2C_Bus_2_SDA", 0, "SDA pin (0 to disable)");
|
||||
I2C_Bus_2_SCL = WiFiSettings.integer("I2C_Bus_2_SCL", 0, "SCL pin (0 to disable)");
|
||||
|
||||
WiFiSettings.heading("I2C Sensors");
|
||||
WiFiSettings.heading("I2C Sensors <a href='https://espresense.com/settings#i2c-sensors' target='_blank'>ℹ️</a>", false);
|
||||
|
||||
WiFiSettings.html("h4", "BH1750 - Ambient Light Sensor:");
|
||||
BH1750_I2c_Bus = WiFiSettings.integer("BH1750_I2c_Bus", 1, 2, DEFAULT_I2C_BUS, "I2C Bus");
|
||||
|
@ -190,9 +205,11 @@ void connectToWifi()
|
|||
|
||||
if (!WiFiSettings.connect(true, 60))
|
||||
ESP.restart();
|
||||
|
||||
#ifdef FIRMWARE
|
||||
Serial.println("Firmware: " + String(FIRMWARE));
|
||||
#endif
|
||||
#ifdef VERSION
|
||||
Serial.println("Version: " + String(VERSION));
|
||||
Serial.println("Version: " + String(VERSION));
|
||||
#endif
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
@ -204,20 +221,14 @@ void connectToWifi()
|
|||
Serial.println(room);
|
||||
Serial.printf("MQTT server: %s:%d\n", mqttHost.c_str(), mqttPort);
|
||||
Serial.printf("Max Distance: %.2f\n", BleFingerprintCollection::maxDistance);
|
||||
Serial.print("Telemetry: ");
|
||||
Serial.println(publishTele ? "enabled" : "disabled");
|
||||
Serial.print("Rooms: ");
|
||||
Serial.println(publishRooms ? "enabled" : "disabled");
|
||||
Serial.print("Devices: ");
|
||||
Serial.println(publishDevices ? "enabled" : "disabled");
|
||||
Serial.print("Discovery: ");
|
||||
Serial.println(discovery ? "enabled" : "disabled");
|
||||
Motion::SerialReport();
|
||||
#ifdef SENSORS
|
||||
Serial.print("DHT11 Sensor: ");
|
||||
Serial.println(dht11Pin ? "enabled" : "disabled");
|
||||
Serial.print("DHT22 Sensor: ");
|
||||
Serial.println(dht22Pin ? "enabled" : "disabled");
|
||||
Serial.print("DHT Temp Offset: ");
|
||||
Serial.println(dhtTempOffset ? "enabled" : "disabled");
|
||||
Serial.print("BH1750_I2c Sensor: ");
|
||||
Serial.println(BH1750_I2c + " on bus " + BH1750_I2c_Bus);
|
||||
Serial.print("BME280_I2c Sensor: ");
|
||||
|
@ -232,6 +243,10 @@ void connectToWifi()
|
|||
Serial.println(BleFingerprintCollection::include);
|
||||
Serial.print("Exclude: ");
|
||||
Serial.println(BleFingerprintCollection::exclude);
|
||||
Serial.print("Known Macs: ");
|
||||
Serial.println(BleFingerprintCollection::knownMacs);
|
||||
Serial.print("Count Ids: ");
|
||||
Serial.println(BleFingerprintCollection::countIds);
|
||||
|
||||
localIp = WiFi.localIP().toString();
|
||||
id = slugify(room);
|
||||
|
@ -309,16 +324,28 @@ void onMqttMessage(char *topic, char *payload, AsyncMqttClientMessageProperties
|
|||
spurt("/exclude", pay);
|
||||
online = false;
|
||||
}
|
||||
else if (command == "known_macs")
|
||||
{
|
||||
BleFingerprintCollection::knownMacs = pay;
|
||||
spurt("/known_macs", pay);
|
||||
online = false;
|
||||
}
|
||||
else if (command == "count_ids")
|
||||
{
|
||||
BleFingerprintCollection::countIds = pay;
|
||||
spurt("/count_ids", pay);
|
||||
online = false;
|
||||
}
|
||||
else if (command == "status_led")
|
||||
{
|
||||
GUI::statusLed = pay == "ON";
|
||||
spurt("/status_led", String(GUI::statusLed));
|
||||
online = false;
|
||||
}
|
||||
else if (command == "ota_update")
|
||||
else if (command == "arduino_ota")
|
||||
{
|
||||
otaUpdate = pay == "ON";
|
||||
spurt("/ota_update", String(otaUpdate));
|
||||
arduinoOta = pay == "ON";
|
||||
spurt("/arduino_ota", String(arduinoOta));
|
||||
online = false;
|
||||
}
|
||||
else if (command == "auto_update")
|
||||
|
@ -345,7 +372,7 @@ void onMqttMessage(char *topic, char *payload, AsyncMqttClientMessageProperties
|
|||
|
||||
void reconnect(TimerHandle_t xTimer)
|
||||
{
|
||||
Serial.printf("%d Reconnect timer\n", xPortGetCoreID());
|
||||
Serial.printf("%u Reconnect timer\n", xPortGetCoreID());
|
||||
if (updateInProgress) return;
|
||||
if (WiFi.isConnected() && mqttClient.connected()) return;
|
||||
|
||||
|
@ -357,12 +384,12 @@ void reconnect(TimerHandle_t xTimer)
|
|||
|
||||
if (!WiFi.isConnected())
|
||||
{
|
||||
Serial.printf("%d Reconnecting to WiFi...\n", xPortGetCoreID());
|
||||
Serial.printf("%u Reconnecting to WiFi...\n", xPortGetCoreID());
|
||||
if (!WiFiSettings.connect(true, 60))
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
Serial.printf("%d Reconnecting to MQTT...\n", xPortGetCoreID());
|
||||
Serial.printf("%u Reconnecting to MQTT...\n", xPortGetCoreID());
|
||||
mqttClient.connect();
|
||||
}
|
||||
|
||||
|
@ -407,29 +434,14 @@ bool reportDevice(BleFingerprint *f)
|
|||
return false;
|
||||
}
|
||||
|
||||
void scanForDevices(void *parameter)
|
||||
int totalFpReported = 0;
|
||||
int totalSeen = 0;
|
||||
int totalFpSeen = 0;
|
||||
int totalFpQueried = 0;
|
||||
|
||||
void reportTask(void *parameter)
|
||||
{
|
||||
connectToMqtt();
|
||||
BLEDevice::init("");
|
||||
for (esp_ble_power_type_t i = ESP_BLE_PWR_TYPE_CONN_HDL0; i <= ESP_BLE_PWR_TYPE_CONN_HDL8; i = esp_ble_power_type_t((int)i + 1))
|
||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9, i);
|
||||
NimBLEDevice::setSecurityAuth(false, false, false);
|
||||
|
||||
auto pBLEScan = BLEDevice::getScan();
|
||||
pBLEScan->setInterval(BLE_SCAN_INTERVAL);
|
||||
pBLEScan->setWindow(BLE_SCAN_WINDOW);
|
||||
pBLEScan->setAdvertisedDeviceCallbacks(&fingerprints, true);
|
||||
if (activeScan) pBLEScan->setActiveScan(true);
|
||||
pBLEScan->setDuplicateFilter(false);
|
||||
pBLEScan->setMaxResults(0);
|
||||
// pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL_INITA);
|
||||
if (!pBLEScan->start(0, nullptr, false))
|
||||
log_e("Error starting continuous ble scan");
|
||||
|
||||
int totalSeen = 0;
|
||||
int totalFpSeen = 0;
|
||||
int totalFpQueried = 0;
|
||||
int totalFpReported = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -439,28 +451,14 @@ void scanForDevices(void *parameter)
|
|||
yield();
|
||||
auto copy = fingerprints.getCopy();
|
||||
|
||||
sendTelemetry(totalSeen, totalFpSeen, totalFpQueried, totalFpReported);
|
||||
int count = 0;
|
||||
for (auto i: copy)
|
||||
if (i->shouldCount())
|
||||
count++;
|
||||
|
||||
yield();
|
||||
sendTelemetry(totalSeen, totalFpSeen, totalFpQueried, totalFpReported, count);
|
||||
yield();
|
||||
|
||||
if (millis() - lastQueryMillis > 3000)
|
||||
{
|
||||
auto started = millis();
|
||||
for (auto f : copy)
|
||||
{
|
||||
if (f->query())
|
||||
totalFpQueried++;
|
||||
|
||||
if (millis() - started > 3000) break;
|
||||
}
|
||||
|
||||
if (!pBLEScan->isScanning())
|
||||
{
|
||||
if (!pBLEScan->start(0, nullptr, true))
|
||||
log_e("Error re-starting continuous ble scan");
|
||||
|
||||
lastQueryMillis = millis(); // If we stopped scanning, don't query for 3 seconds in order for us to catch any missed broadcasts
|
||||
}
|
||||
}
|
||||
|
||||
auto reported = 0;
|
||||
for (auto f : copy)
|
||||
|
@ -476,6 +474,45 @@ void scanForDevices(void *parameter)
|
|||
totalFpReported++;
|
||||
reported++;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scanTask(void *parameter)
|
||||
{
|
||||
NimBLEDevice::init("");
|
||||
for (esp_ble_power_type_t i = ESP_BLE_PWR_TYPE_CONN_HDL0; i <= ESP_BLE_PWR_TYPE_CONN_HDL8; i = esp_ble_power_type_t((int)i + 1))
|
||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9, i);
|
||||
NimBLEDevice::setSecurityAuth(true, true, true);
|
||||
NimBLEDevice::setSecurityRespKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID);
|
||||
NimBLEDevice::setMTU(255);
|
||||
|
||||
auto pBLEScan = NimBLEDevice::getScan();
|
||||
pBLEScan->setInterval(BLE_SCAN_INTERVAL);
|
||||
pBLEScan->setWindow(BLE_SCAN_WINDOW);
|
||||
pBLEScan->setAdvertisedDeviceCallbacks(&fingerprints, true);
|
||||
pBLEScan->setActiveScan(activeScan);
|
||||
pBLEScan->setDuplicateFilter(false);
|
||||
pBLEScan->setMaxResults(0);
|
||||
if (!pBLEScan->start(0, nullptr, false))
|
||||
log_e("Error starting continuous ble scan");
|
||||
|
||||
while (true)
|
||||
{
|
||||
for (auto f : *fingerprints.getNative())
|
||||
if (f->query())
|
||||
totalFpQueried++;
|
||||
|
||||
if (!pBLEScan->isScanning())
|
||||
{
|
||||
if (!pBLEScan->start(0, nullptr, true))
|
||||
log_e("Error re-starting continuous ble scan");
|
||||
delay(3000); // If we stopped scanning, don't query for 3 seconds in order for us to catch any missed broadcasts
|
||||
}
|
||||
else
|
||||
{
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,7 +577,9 @@ void setup()
|
|||
setClock();
|
||||
#endif
|
||||
Motion::Setup();
|
||||
|
||||
#if MACCHINA_A0
|
||||
pinMode(GPIO_NUM_35, INPUT);
|
||||
#endif
|
||||
#ifdef SENSORS
|
||||
if (dht11Pin) dhtSensor.setup(dht11Pin, DHTesp::DHT11);
|
||||
if (dht22Pin) dhtSensor.setup(dht22Pin, DHTesp::DHT22); //(AM2302)
|
||||
|
@ -596,7 +635,7 @@ void setup()
|
|||
{
|
||||
// Init BH1750 (witch default l2c adres)
|
||||
int rc; // Returncode
|
||||
long m; // milli for calibration
|
||||
unsigned long m; // milli for calibration
|
||||
bool state = false;
|
||||
|
||||
// if (! BH1750.begin(BH1750_TO_GROUND))
|
||||
|
@ -646,7 +685,8 @@ void setup()
|
|||
}
|
||||
}
|
||||
#endif
|
||||
xTaskCreatePinnedToCore(scanForDevices, "scanForDevices", 6000, nullptr, 1, &scannerTask, 1);
|
||||
xTaskCreatePinnedToCore(scanTask, "scanTask", 7168, nullptr, 2, &scanTaskHandle, CONFIG_BT_NIMBLE_PINNED_TO_CORE);
|
||||
xTaskCreatePinnedToCore(reportTask, "reportTask", 7168, nullptr, 1, &reportTaskHandle, 1);
|
||||
configureOTA();
|
||||
}
|
||||
|
||||
|
@ -658,11 +698,11 @@ void dhtLoop()
|
|||
if (gotNewTemperature)
|
||||
{
|
||||
float humidity = dhtSensorData.humidity;
|
||||
float temperature = dhtSensorData.temperature;
|
||||
Serial.println("Temp: " + String(temperature, 2) + "'C Humidity: " + String(humidity, 1) + "%");
|
||||
float temperature = dhtSensorData.temperature + dhtTempOffset;
|
||||
Serial.println("Temp: " + String(temperature, 1) + "'C Humidity: " + String(humidity, 1) + "%");
|
||||
|
||||
mqttClient.publish((roomsTopic + "/humidity").c_str(), 0, 1, String(humidity).c_str());
|
||||
mqttClient.publish((roomsTopic + "/temperature").c_str(), 0, 1, String(temperature).c_str());
|
||||
mqttClient.publish((roomsTopic + "/humidity").c_str(), 0, 1, String(humidity, 1).c_str());
|
||||
mqttClient.publish((roomsTopic + "/temperature").c_str(), 0, 1, String(temperature, 1).c_str());
|
||||
|
||||
gotNewTemperature = false;
|
||||
}
|
||||
|
@ -897,12 +937,11 @@ void l2cScanner()
|
|||
|
||||
void loop()
|
||||
{
|
||||
int freeHeap = ESP.getFreeHeap();
|
||||
if (otaUpdate && freeHeap > 4096)
|
||||
uint32_t freeHeap = ESP.getFreeHeap();
|
||||
if (arduinoOta && freeHeap > 4096)
|
||||
ArduinoOTA.handle();
|
||||
if (freeHeap < 10000) Serial.printf("Low memory: %d bytes free", freeHeap);
|
||||
if (freeHeap < 10000) Serial.printf("Low memory: %u bytes free", freeHeap);
|
||||
firmwareUpdate();
|
||||
GUI::blit();
|
||||
Motion::Loop(mqttClient);
|
||||
#ifdef SENSORS
|
||||
dhtLoop();
|
||||
|
|
88
src/main.h
88
src/main.h
|
@ -41,7 +41,7 @@ unsigned long sensorInterval = 60000;
|
|||
//GY-302 lux sensor
|
||||
#include <hp_BH1750.h>
|
||||
hp_BH1750 BH1750;
|
||||
long ms_BH1750;
|
||||
unsigned long ms_BH1750;
|
||||
float lux_BH1750;
|
||||
int lux_BH1750_MQTT;
|
||||
String BH1750_I2c;
|
||||
|
@ -63,41 +63,37 @@ String TSL2561_I2c_Gain;
|
|||
unsigned long tsl2561PreviousMillis = 0;
|
||||
#endif
|
||||
|
||||
static const char *const EC_DIAGNOSTIC = "diagnostic";
|
||||
static const char *const EC_CONFIG = "config";
|
||||
|
||||
AsyncMqttClient mqttClient;
|
||||
TimerHandle_t reconnectTimer;
|
||||
TaskHandle_t scannerTask;
|
||||
TaskHandle_t scanTaskHandle, reportTaskHandle;
|
||||
|
||||
DynamicJsonDocument doc(2048);
|
||||
char buffer[2048];
|
||||
|
||||
bool updateInProgress = false;
|
||||
String localIp;
|
||||
unsigned long lastTeleMillis, lastQueryMillis;
|
||||
unsigned long lastTeleMillis;
|
||||
int reconnectTries = 0;
|
||||
int teleFails = 0;
|
||||
bool online = false; // Have we successfully sent status=online
|
||||
bool sentDiscovery = false; // Have we successfully sent discovery
|
||||
String offline = "offline";
|
||||
String mqttHost;
|
||||
int mqttPort;
|
||||
String mqttUser;
|
||||
String mqttPass;
|
||||
String room;
|
||||
String id;
|
||||
String statusTopic;
|
||||
String teleTopic;
|
||||
String roomsTopic;
|
||||
String setTopic;
|
||||
bool autoUpdate, otaUpdate, prerelease;
|
||||
bool discovery;
|
||||
bool activeScan;
|
||||
bool publishTele;
|
||||
bool publishRooms;
|
||||
bool publishDevices;
|
||||
|
||||
String mqttHost, mqttUser, mqttPass;
|
||||
uint16_t mqttPort;
|
||||
String room, id, statusTopic, teleTopic, roomsTopic, setTopic;
|
||||
|
||||
bool autoUpdate, arduinoOta, prerelease;
|
||||
bool discovery, activeScan, publishTele, publishRooms, publishDevices;
|
||||
|
||||
#ifdef SENSORS
|
||||
int dht11Pin;
|
||||
int dht22Pin;
|
||||
|
||||
uint8_t dht11Pin;
|
||||
uint8_t dht22Pin;
|
||||
float dhtTempOffset;
|
||||
|
||||
/** Initialize DHT sensor 1 */
|
||||
DHTesp dhtSensor;
|
||||
|
@ -185,7 +181,7 @@ void setClock()
|
|||
|
||||
void configureOTA()
|
||||
{
|
||||
if (!otaUpdate) return;
|
||||
if (!arduinoOta) return;
|
||||
ArduinoOTA
|
||||
.onStart([]()
|
||||
{
|
||||
|
@ -296,7 +292,7 @@ void spiffsInit()
|
|||
int flashes = 0;
|
||||
unsigned long debounceDelay = 250;
|
||||
|
||||
long lastDebounceTime = millis();
|
||||
unsigned long lastDebounceTime = millis();
|
||||
while (digitalRead(BUTTON) == BUTTON_PRESSED)
|
||||
{
|
||||
if ((millis() - lastDebounceTime) > debounceDelay)
|
||||
|
@ -336,7 +332,7 @@ bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_
|
|||
|
||||
bool sendOnline()
|
||||
{
|
||||
return pub(statusTopic.c_str(), 0, true, "online") && pub((roomsTopic + "/max_distance").c_str(), 0, true, String(BleFingerprintCollection::maxDistance).c_str()) && pub((roomsTopic + "/absorption").c_str(), 0, true, String(BleFingerprintCollection::absorption).c_str()) && pub((roomsTopic + "/query").c_str(), 0, true, BleFingerprintCollection::query.c_str()) && pub((roomsTopic + "/include").c_str(), 0, true, BleFingerprintCollection::include.c_str()) && pub((roomsTopic + "/exclude").c_str(), 0, true, BleFingerprintCollection::exclude.c_str()) && pub((roomsTopic + "/status_led").c_str(), 0, true, String(GUI::statusLed ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/ota_update").c_str(), 0, true, String(otaUpdate ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/auto_update").c_str(), 0, true, String(autoUpdate ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/prerelease").c_str(), 0, true, String(prerelease ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/active_scan").c_str(), 0, true, String(activeScan ? "ON" : "OFF").c_str());
|
||||
return pub(statusTopic.c_str(), 0, true, "online") && pub((roomsTopic + "/max_distance").c_str(), 0, true, String(BleFingerprintCollection::maxDistance).c_str()) && pub((roomsTopic + "/absorption").c_str(), 0, true, String(BleFingerprintCollection::absorption).c_str()) && pub((roomsTopic + "/query").c_str(), 0, true, BleFingerprintCollection::query.c_str()) && pub((roomsTopic + "/include").c_str(), 0, true, BleFingerprintCollection::include.c_str()) && pub((roomsTopic + "/exclude").c_str(), 0, true, BleFingerprintCollection::exclude.c_str()) && pub((roomsTopic + "/known_macs").c_str(), 0, true, BleFingerprintCollection::knownMacs.c_str()) && pub((roomsTopic + "/count_ids").c_str(), 0, true, BleFingerprintCollection::countIds.c_str()) && pub((roomsTopic + "/status_led").c_str(), 0, true, String(GUI::statusLed ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/arduino_ota").c_str(), 0, true, String(arduinoOta ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/auto_update").c_str(), 0, true, String(autoUpdate ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/prerelease").c_str(), 0, true, String(prerelease ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/active_scan").c_str(), 0, true, String(activeScan ? "ON" : "OFF").c_str());
|
||||
}
|
||||
|
||||
void commonDiscovery()
|
||||
|
@ -378,38 +374,40 @@ bool sendDiscoveryConnectivity()
|
|||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendDiscoveryUptime()
|
||||
bool sendTeleBinarySensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &devClass)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Uptime";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06" PRIx64 "_uptime", ESP.getEfuseMac() >> 24);
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06" PRIx64 "_%s", ESP.getEfuseMac() >> 24, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/telemetry";
|
||||
doc["entity_category"] = "diagnostic";
|
||||
doc["value_template"] = "{{ value_json.uptime }}";
|
||||
doc["unit_of_measurement"] = "s";
|
||||
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
doc["value_template"] = temp;
|
||||
doc["dev_cla"] = devClass;
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/uptime/config";
|
||||
String discoveryTopic = "homeassistant/binary_sensor/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendDiscoveryFreeMem()
|
||||
bool sendTeleSensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &units)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Free Memory";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06" PRIx64 "_free_mem", ESP.getEfuseMac() >> 24);
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06" PRIx64 "_%s", ESP.getEfuseMac() >> 24, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/telemetry";
|
||||
doc["entity_category"] = "diagnostic";
|
||||
doc["value_template"] = "{{ value_json.maxAllocHeap }}";
|
||||
doc["unit_of_measurement"] = "bytes";
|
||||
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
doc["value_template"] = temp;
|
||||
if (!units.isEmpty()) doc["unit_of_measurement"] = units;
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/free_mem/config";
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
@ -654,9 +652,15 @@ bool spurt(const String &fn, const String &content)
|
|||
}
|
||||
|
||||
#ifdef MACCHINA_A0
|
||||
|
||||
int smoothMilliVolts;
|
||||
int a0_read_batt_mv()
|
||||
{
|
||||
float vout = ((float)analogRead(GPIO_NUM_35) + 35) / 215.0;
|
||||
return vout * 1100; // V to mV with +10% correction
|
||||
int mv = round(((float)analogRead(GPIO_NUM_35) + 35) / 0.215);
|
||||
if (smoothMilliVolts)
|
||||
smoothMilliVolts = round(0.1 * (mv - smoothMilliVolts) + smoothMilliVolts);
|
||||
else
|
||||
smoothMilliVolts = mv;
|
||||
return smoothMilliVolts;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue