diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7bad2cb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,67 @@ +{ + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cfenv": "cpp", + "typeinfo": "cpp", + "variant": "cpp", + "regex": "cpp", + "bitset": "cpp", + "sstream": "cpp", + "netfwd": "cpp" + } +} \ No newline at end of file diff --git a/components/esp32_presense/BleFingerprint.cpp b/components/esp32_presense/BleFingerprint.cpp index 8e07551..7570f45 100644 --- a/components/esp32_presense/BleFingerprint.cpp +++ b/components/esp32_presense/BleFingerprint.cpp @@ -1,3 +1,5 @@ +#include +#include #include "BleFingerprint.h" #include "MiFloraHandler.h" @@ -42,7 +44,7 @@ bool BleFingerprint::shouldHide(const std::string &s) { bool BleFingerprint::setId(const std::string &newId, short newIdType, const std::string &newName) { if (idType < 0 && newIdType < 0 && newIdType >= idType) return false; if (idType > 0 && newIdType <= idType) return false; - // Serial.printf("setId: %s %d %s OLD idType: %d\r\n", newId.c_str(), newIdType, newName.c_str(), idType); + // ESP_LOGD("setId: %s %d %s OLD idType: %d\r\n", newId.c_str(), newIdType, newName.c_str(), idType); ignore = newIdType < 0; idType = newIdType; @@ -51,17 +53,17 @@ bool BleFingerprint::setId(const std::string &newId, short newIdType, const std: if (BleFingerprintCollection::FindDeviceConfig(newId, dc)) { if (dc.calRssi != NO_RSSI) calRssi = dc.calRssi; - if (!dc.alias.isEmpty()) + if (!dc.alias.empty()) return setId(dc.alias, ID_TYPE_ALIAS, dc.name); - if (!dc.name.isEmpty()) + if (!dc.name.empty()) name = dc.name; - } else if (!newName.isEmpty() && name != newName) + } else if (!newName.empty() && name != newName) name = newName; if (id != newId) { bool newHidden = shouldHide(newId); - countable = !ignore && !hidden && !BleFingerprintCollection::countIds.isEmpty() && prefixExists(BleFingerprintCollection::countIds, newId); - bool newQuery = !ignore && !BleFingerprintCollection::query.isEmpty() && prefixExists(BleFingerprintCollection::query, newId); + countable = !ignore && !hidden && !BleFingerprintCollection::countIds.empty() && prefixExists(BleFingerprintCollection::countIds, newId); + bool newQuery = !ignore && !BleFingerprintCollection::query.empty() && prefixExists(BleFingerprintCollection::query, newId); if (newQuery != allowQuery) { allowQuery = newQuery; if (allowQuery) { @@ -164,14 +166,14 @@ bool ble_ll_resolv_rpa(const uint8_t *rpa, const uint8_t *irk) { if (ecb.cipher_text[15] != rpa[0] || ecb.cipher_text[14] != rpa[1] || ecb.cipher_text[13] != rpa[2]) return false; - // Serial.printf("RPA resolved %d %02x%02x%02x %02x%02x%02x\r\n", err, rpa[0], rpa[1], rpa[2], ecb.cipher_text[15], ecb.cipher_text[14], ecb.cipher_text[13]); + // ESP_LOGD("RPA resolved %d %02x%02x%02x %02x%02x%02x\r\n", err, rpa[0], rpa[1], rpa[2], ecb.cipher_text[15], ecb.cipher_text[14], ecb.cipher_text[13]); return true; } void BleFingerprint::fingerprintAddress() { auto mac = getMac(); - if (!BleFingerprintCollection::knownMacs.isEmpty() && prefixExists(BleFingerprintCollection::knownMacs, mac)) + if (!BleFingerprintCollection::knownMacs.empty() && prefixExists(BleFingerprintCollection::knownMacs, mac)) setId("known:" + mac, ID_TYPE_KNOWN_MAC); else { switch (addressType) { @@ -207,7 +209,7 @@ void BleFingerprint::fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *ad for (auto i = 0; i < serviceAdvCount; i++) { auto uuid = advertisedDevice->getServiceUUID(i); #ifdef VERBOSE - Serial.printf("Verbose | %s | %-58s%ddBm AD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, advertisedDevice->getServiceUUID(i).toString().c_str()); + ESP_LOGD("Verbose | %s | %-58s%ddBm AD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, advertisedDevice->getServiceUUID(i).toString().c_str()); #endif if (uuid == tileUUID) { asRssi = BleFingerprintCollection::rxRefRssi + TILE_TX; @@ -254,7 +256,7 @@ void BleFingerprint::fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *ad std::string sid = advertisedDevice->getServiceUUID(i).toString(); fingerprint = fingerprint + sid.c_str(); } - if (haveTxPower) fingerprint = fingerprint + std::string(-txPower); + if (haveTxPower) fingerprint = fingerprint + std::to_string(-txPower); setId(fingerprint, ID_TYPE_AD); } @@ -265,16 +267,16 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe BLEUUID uuid = advertisedDevice->getServiceDataUUID(i); std::string strServiceData = advertisedDevice->getServiceData(i); #ifdef VERBOSE - Serial.printf("Verbose | %s | %-58s%ddBm SD: %s/%s\r\n", getMac().c_str(), getId().c_str(), rssi, uuid.toString().c_str(), hexStr(strServiceData).c_str()); + ESP_LOGD("Verbose | %s | %-58s%ddBm SD: %s/%s\r\n", getMac().c_str(), getId().c_str(), rssi, uuid.toString().c_str(), hexStr(strServiceData).c_str()); #endif if (uuid == exposureUUID) { // found COVID-19 exposure tracker bcnRssi = BleFingerprintCollection::rxRefRssi + EXPOSURE_TX; - setId("exp:" + std::string(strServiceData.length()), ID_TYPE_EXPOSURE); + setId("exp:" + std::to_string(strServiceData.length()), ID_TYPE_EXPOSURE); // disc = hexStr(strServiceData).c_str(); } else if (uuid == smartTagUUID) { // found Samsung smart tag asRssi = haveTxPower ? BleFingerprintCollection::rxRefRssi + txPower : NO_RSSI; - setId("smarttag:" + std::string(strServiceData.length()), ID_TYPE_SMARTTAG); + setId("smarttag:" + std::to_string(strServiceData.length()), ID_TYPE_SMARTTAG); } else if (uuid == miThermUUID) { asRssi = haveTxPower ? BleFingerprintCollection::rxRefRssi + txPower : NO_RSSI; if (strServiceData.length() == 15) { // custom format @@ -284,7 +286,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe 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\r\n", temp, humidity, mv, battery, serviceData[14], serviceData[13]); + ESP_LOGD("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, flg: 0x%02hhx, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[14], serviceData[13]); #endif setId("miTherm:" + getMac(), ID_TYPE_MITHERM); } else if (strServiceData.length() == 13) { // format atc1441 @@ -296,7 +298,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe battery = serviceData[9]; #ifdef VERBOSE - Serial.printf("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[12]); + ESP_LOGD("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[12]); #endif setId("miTherm:" + getMac(), ID_TYPE_MITHERM); } @@ -328,8 +330,8 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe fingerprint = fingerprint + uuid.toString().c_str(); } } - if (!fingerprint.isEmpty()) { - if (haveTxPower) fingerprint = fingerprint + std::string(-txPower); + if (!fingerprint.empty()) { + if (haveTxPower) fingerprint = fingerprint + std::to_string(-txPower); setId("sd:" + fingerprint, ID_TYPE_SD); } } @@ -337,7 +339,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice, bool haveTxPower, int8_t txPower) { std::string strManufacturerData = advertisedDevice->getManufacturerData(); #ifdef VERBOSE - Serial.printf("Verbose | %s | %-58s%ddBm MD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, hexStr(strManufacturerData).c_str()); + ESP_LOGD("Verbose | %s | %-58s%ddBm MD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, hexStr(strManufacturerData).c_str()); #endif if (strManufacturerData.length() >= 2) { std::string manuf = Sprintf("%02x%02x", strManufacturerData[1], strManufacturerData[0]); @@ -402,7 +404,7 @@ void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertis } else if (manuf != "0000") { mdRssi = haveTxPower ? BleFingerprintCollection::rxRefRssi + txPower : NO_RSSI; std::string fingerprint = Sprintf("md:%s:%u", manuf.c_str(), strManufacturerData.length()); - if (haveTxPower) fingerprint = fingerprint + std::string(-txPower); + if (haveTxPower) fingerprint = fingerprint + std::to_string(-txPower); setId(fingerprint, ID_TYPE_MD); } } @@ -433,25 +435,25 @@ bool BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice) { } bool BleFingerprint::fill(JsonObject *doc) { - (*doc)[F("mac")] = getMac(); - (*doc)[F("id")] = id; - if (!name.isEmpty()) (*doc)[F("name")] = name; - if (idType) (*doc)[F("idType")] = idType; + (*doc)["mac"] = getMac(); + (*doc)["id"] = id; + if (!name.empty()) (*doc)["name"] = name; + if (idType) (*doc)["idType"] = idType; - (*doc)[F("rssi@1m")] = get1mRssi(); - (*doc)[F("rssi")] = rssi; + (*doc)["rssi@1m"] = get1mRssi(); + (*doc)["rssi"] = rssi; - if (isnormal(raw)) (*doc)[F("raw")] = serialized(std::string(raw, 2)); - if (isnormal(dist)) (*doc)[F("distance")] = serialized(std::string(dist, 2)); - if (isnormal(vari)) (*doc)[F("var")] = serialized(std::string(vari, 2)); - if (close) (*doc)[F("close")] = true; + if (isnormal(raw)) (*doc)["raw"] = serialized(std::string(raw, 2)); + if (isnormal(dist)) (*doc)["distance"] = serialized(std::string(dist, 2)); + if (isnormal(vari)) (*doc)["var"] = serialized(std::string(vari, 2)); + if (close) (*doc)["close"] = true; - (*doc)[F("int")] = (millis() - firstSeenMillis) / seenCount; + (*doc)["int"] = (millis() - firstSeenMillis) / seenCount; - if (mv) (*doc)[F("mV")] = mv; - if (battery != 0xFF) (*doc)[F("batt")] = battery; - if (temp) (*doc)[F("temp")] = serialized(std::string(temp, 1)); - if (humidity) (*doc)[F("rh")] = serialized(std::string(humidity, 1)); + if (mv) (*doc)["mV"] = mv; + if (battery != 0xFF) (*doc)["batt"] = battery; + if (temp) (*doc)["temp"] = serialized(std::string(temp, 1)); + if (humidity) (*doc)["rh"] = serialized(std::string(humidity, 1)); return true; } @@ -490,7 +492,7 @@ bool BleFingerprint::query() { bool success = false; - Serial.printf("%u Query | %s | %-58s%ddBm %lums\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, now - lastSeenMillis); + ESP_LOGD("%u Query | %s | %-58s%ddBm %lums\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, now - lastSeenMillis); NimBLEClient *pClient = NimBLEDevice::getClientListSize() ? NimBLEDevice::getClientByPeerAddress(address) : nullptr; if (!pClient) pClient = NimBLEDevice::getDisconnectedClient(); @@ -501,7 +503,7 @@ bool BleFingerprint::query() { NimBLEDevice::getScan()->stop(); if (pClient->connect(address)) { if (allowQuery) { - if (id.startsWith("flora:")) + if (id.rfind("flora:", 0) == 0) success = MiFloraHandler::requestData(pClient, this); else success = NameModelHandler::requestData(pClient, this); @@ -515,8 +517,8 @@ bool BleFingerprint::query() { qryDelayMillis = BleFingerprintCollection::requeryMs; } else { qryAttempts++; - qryDelayMillis = min(int(pow(10, qryAttempts)), 60000); - Serial.printf("%u QryErr | %s | %-58s%ddBm Try %d, retry after %dms\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, qryAttempts, qryDelayMillis); + qryDelayMillis = std::min(int(pow(10, qryAttempts)), 60000); + ESP_LOGD("%u QryErr | %s | %-58s%ddBm Try %d, retry after %dms\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, qryAttempts, qryDelayMillis); } isQuerying = false; return true; diff --git a/components/esp32_presense/BleFingerprint.h b/components/esp32_presense/BleFingerprint.h index c566f7f..720dbc3 100644 --- a/components/esp32_presense/BleFingerprint.h +++ b/components/esp32_presense/BleFingerprint.h @@ -21,6 +21,7 @@ #define log_e ESP_LOGE #define millis esphome::millis +// #define delay esphome::delay #define NO_RSSI int8_t(-128) diff --git a/components/esp32_presense/MiFloraHandler.cpp b/components/esp32_presense/MiFloraHandler.cpp index 78bd7a0..5e8400f 100644 --- a/components/esp32_presense/MiFloraHandler.cpp +++ b/components/esp32_presense/MiFloraHandler.cpp @@ -31,10 +31,10 @@ bool readSensorData(BLERemoteService* floraService, DynamicJsonDocument* doc) { uint32_t brightness = val[3] + val[4] * 256; float conductivity = val[8] + val[9] * 256; - (*doc)[F("temperature")] = temperature; - (*doc)[F("moisture")] = moisture; - (*doc)[F("light")] = brightness; - (*doc)[F("conductivity")] = conductivity; + (*doc)["temperature"] = temperature; + (*doc)["moisture"] = moisture; + (*doc)["light"] = brightness; + (*doc)["conductivity"] = conductivity; floraService->deleteCharacteristics(); @@ -60,7 +60,7 @@ bool readBatteryData(BLERemoteService* floraService, DynamicJsonDocument* doc) { } int8_t battery = val.c_str()[0]; - (*doc)[F("battery")] = battery; + (*doc)["battery"] = battery; floraService->deleteCharacteristics(); return true; @@ -82,16 +82,16 @@ bool forceFloraServiceDataMode(BLERemoteService* floraService) { // Setting the uint8_t buf[2] = {0xA0, 0x1F}; floraCharacteristic->writeValue(buf, 2, true); - delay(500); + esphome::delay(500); floraService->deleteCharacteristics(); return true; } void fillDeviceData(DynamicJsonDocument* doc, BleFingerprint* f) { - (*doc)[F("id")] = f->getId(); - (*doc)[F("mac")] = f->getMac(); - (*doc)[F("rssi")] = f->getRssi(); + (*doc)["id"] = f->getId(); + (*doc)["mac"] = f->getMac(); + (*doc)["rssi"] = f->getRssi(); } bool getFloraData(DynamicJsonDocument* doc, BLERemoteService* floraService, BleFingerprint* f) { diff --git a/components/esp32_presense/MiFloraHandler.h b/components/esp32_presense/MiFloraHandler.h index 44196ab..a65ef44 100644 --- a/components/esp32_presense/MiFloraHandler.h +++ b/components/esp32_presense/MiFloraHandler.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include "BleFingerprint.h" #include "NimBLEClient.h" #include "NimBLEDevice.h" diff --git a/components/esp32_presense/__init__.py b/components/esp32_presense/__init__.py index c018593..fb3af0c 100644 --- a/components/esp32_presense/__init__.py +++ b/components/esp32_presense/__init__.py @@ -30,12 +30,12 @@ CONFIG_SCHEMA = cv.Schema({ async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) - await cg.register_component(var, config) + # await cg.register_component(var, config) cg.add(var.set_room(config[CONF_ROOM_KEY])) - cg.add(var.set_base_topic(config[CONF_BASE_TOPIC_KEY])) - cg.add(var.set_addresses(config[CONF_MAC_KEY])) - cg.add(var.set_max_distance(config[CONF_MAX_DISTANCE])) + # cg.add(var.set_base_topic(config[CONF_BASE_TOPIC_KEY])) + # cg.add(var.set_addresses(config[CONF_MAC_KEY])) + # cg.add(var.set_max_distance(config[CONF_MAX_DISTANCE])) add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True) add_idf_sdkconfig_option("CONFIG_BT_BLUEDROID_ENABLED", False) diff --git a/components/esp32_presense/esp32_presense.cpp b/components/esp32_presense/esp32_presense.cpp index 5bfd776..a1ad4a6 100644 --- a/components/esp32_presense/esp32_presense.cpp +++ b/components/esp32_presense/esp32_presense.cpp @@ -2,7 +2,7 @@ namespace esphome { - namespace esp32_nimble_mqtt_room + namespace esp32_presense { unsigned int totalSeen = 0; unsigned int totalFpSeen = 0; diff --git a/components/esp32_presense/esp32_presense.h b/components/esp32_presense/esp32_presense.h index 8b97be3..58d3214 100644 --- a/components/esp32_presense/esp32_presense.h +++ b/components/esp32_presense/esp32_presense.h @@ -7,7 +7,7 @@ namespace esphome { - namespace esp32_nimble_mqtt_room + namespace esp32_presense { class ESP32Presense : public mqtt::CustomMQTTDevice diff --git a/components/nimble_tracker/nimble_tracker.cpp b/components/nimble_tracker/nimble_tracker.cpp index 8307f1e..ba26790 100644 --- a/components/nimble_tracker/nimble_tracker.cpp +++ b/components/nimble_tracker/nimble_tracker.cpp @@ -57,7 +57,7 @@ namespace esphome } // TODO: It takes some time to setup bluetooth? Why not just move this to loop? - delay(200); + esphome::delay(200); } void NimbleTracker::loop() @@ -71,7 +71,7 @@ namespace esphome } // TODO: we shouldn't block the main thread here, instead work with a setTimeout callback? - delay(200); + esphome::delay(200); } NimbleTrackerEvent *tracker_event = this->tracker_events_.pop(); diff --git a/temp b/temp new file mode 100644 index 0000000..f4c1e4d --- /dev/null +++ b/temp @@ -0,0 +1,79 @@ + +external_components: + - source: + type: local + path: components + +mqtt: + broker: !secret mqtt_broker + username: !secret mqtt_username + password: !secret mqtt_password + discovery: false + id: mqtt_client + +globals: + - id: room_topic + type: std::string + initial_value: '"room_presence/${room_name}"' + +nimble_tracker: + scan_parameters: + # window: 500ms + # interval: 1.2s + + window: 100ms + interval: 100ms + active: false + +sensor: + - platform: nimble_distance + name: "Часы" + mac: "dc:d3:24:8e:a0:05" + id: maxim_watch_distance + on_value: + then: + - lambda: |- + id(mqtt_client)->publish_json(id(room_topic), [=](ArduinoJson::JsonObject root) -> void { + root["id"] = "maxim_watch"; + root["name"] = "Maxim Watch"; + root["distance"] = id(maxim_watch_distance).state; + }); + +esp32: + board: esp32dev + framework: + type: esp-idf + sdkconfig_options: + CONFIG_FREERTOS_UNICORE: y + CONFIG_ESP32_DEFAULT_CPU_FREQ_160: y + CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ: "160" + # From https://github.com/esphome/issues/issues/2941 + # Increase watchdog timeout to flash firmware with bluetooth enabled, fixes error: + # ERROR Error receiving acknowledge binary size: timed out + CONFIG_ESP_TASK_WDT_TIMEOUT_S: "20" + CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y + CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y + + +# Enable logging +logger: +# level: VERY_VERBOSE + +# Enable Home Assistant API +api: + encryption: + key: "gZVa2Smtq23LxQudEPzXAmnHu4CkjuOkhZQTwgbJXl4=" + +ota: + + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: "Esphome-Web-Dc7854" + password: "zBeoh1DTmc9m" + +captive_portal: \ No newline at end of file