diff --git a/tasmota/xdrv_79_esp32_ble.ino b/tasmota/xdrv_79_esp32_ble.ino
index 6656dada5..5e4c2b70c 100644
--- a/tasmota/xdrv_79_esp32_ble.ino
+++ b/tasmota/xdrv_79_esp32_ble.ino
@@ -1078,6 +1078,10 @@ void setDetails(ble_advertisment_t *ad){
maxlen -= len;
*(p++) = '\"'; maxlen--;
+ sprintf(p, ",\"RSSI\":%d", ad->RSSI);
+ len = strlen(p);
+ p += len;
+
if (BLEAdvertismentDetailsJsonLost){
BLEAdvertismentDetailsJsonLost = 0;
strcpy(p, ",\"lost\":true");
@@ -1598,16 +1602,18 @@ int BLETaskStartScan(int time){
if (BLEMode == BLEModeDisabled) return -4;
// don't scan whilst OTA in progress
if (BLEOtaStallBLE) return -5;
- if (currentOperations.size()) return -3;
+ //if (currentOperations.size()) return -3;
if (BLERunningScan) {
+
// if we hit 2, wait one more time before starting
if (BLERunningScan == 2){
- // wait 100ms
- vTaskDelay(100/ portTICK_PERIOD_MS);
+ // wait 10ms
+ vTaskDelay(10/ portTICK_PERIOD_MS);
BLERunningScan = 0;
+ } else {
+ return -2;
}
- return -2;
}
#ifdef BLE_ESP32_DEBUG
@@ -1753,6 +1759,9 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe
if (pClient->connect(op->addr, true)) {
+ // as soon as connected, start another scan if possible
+ BLE_ESP32::BLETaskStartScan(20);
+
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: connected %s -> getservice"), ((std::string)op->addr).c_str());
#endif
@@ -1951,7 +1960,7 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe
// failed to connect
#ifdef BLE_ESP32_DEBUG
- AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: failed to connect to device %d"), rc);
+ AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: failed to connect to device"));
#endif
}
op->state = newstate;
diff --git a/tasmota/xsns_52_esp32_ibeacon_ble.ino b/tasmota/xsns_52_esp32_ibeacon_ble.ino
index d509332c5..432455924 100644
--- a/tasmota/xsns_52_esp32_ibeacon_ble.ino
+++ b/tasmota/xsns_52_esp32_ibeacon_ble.ino
@@ -1,11 +1,8 @@
/*
xsns_52_esp32_ibeacon_ble.ino
- if (!USE_IBEACON_ESP32 && USE_BLE_ESP32)
- - Support for HM17 BLE Module + ibeacon reader on Tasmota (untested?)
- if (USE_IBEACON_ESP32 && USE_BLE_ESP32)
- Support for BLE_ESP32 ibeacon reader on Tasmota
- Copyright (C) 2020 Gerhard Mutz and Theo Arends
+ Copyright (C) 2020 Gerhard Mutz and Theo Arends and Simon Hailes
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,14 +18,38 @@
along with this program. If not, see .
*/
+////////////////////////////////////////
+// Commands:
+// iBeacon 0/1 - Enable
+// iBeaconOnlyAliased 0/1/2 -
+// 0 = all BLE devices,
+// 1 = only devices with any BLEAlias
+// 2 = only devices which have BLEAlias starting "iB"
+// iBeaconClear - clear list NOW
+// iBeaconPeriod (sec) - update period - default 10s
+// iBeaconTimeout (sec) - timeout period - default 30s
+//
+// posts MQTT about each beacon every iBeaconPeriod (default 10s)
+// MQTT like
+// tele/tasmota_E89E98/SENSOR = {"Time":"2021-02-04T23:20:22","IBEACON":{"MAC":"FFFFA0003B19","NAME":"iB1","RSSI":-81,"STATE":"ON","PERSEC":10}}
+// Always present:
+// Time: time of MQTT send
+// IBEACON.MAC
+// IBEACON.RSSI
+// IBEACON.STATE - ON - present, OFF - last MQTT you will get for now (device removed)
+// Optional:
+// IBEACON.NAME - name if in scan, or BLEAlias if set - only present if NAME present
+// IBEACON.PERSEC - count of adverts per sec. USeful for detecting button press?
+// IBEACON.MAJOR - some iBeacon related term? - only present for some
+// IBEACON.MINOR - some iBeacon related term? - only present for some
+////////////////////////////////////////
+
+
// for testing of BLE_ESP32, we remove xsns_52_ibeacon.ino completely, and instead add this modified xsns_52_ibeacon_BLE_ESP32.ino
// in the future this may be more fine-grained, e.g. to allow hm17 for this, and BLE-ESP32 for other
+#if CONFIG_IDF_TARGET_ESP32
#ifdef USE_BLE_ESP32
-#ifdef USE_IBEACON_ESP32
-
-#ifdef USE_IBEACON
-
#define XSNS_52 52
// keyfob expires after N seconds
@@ -37,64 +58,20 @@
#define IB_UPDATE_TIME_INTERVAL 10
// should be in Settings
-#if 1
- uint8_t ib_upd_interval,ib_tout_interval;
- #define IB_UPDATE_TIME ib_upd_interval
- #define IB_TIMEOUT_TIME ib_tout_interval
-#else
- #undef IB_UPDATE_TIME
- #undef IB_TIMEOUT_TIME
- #define IB_UPDATE_TIME Settings.ib_upd_interval
- #define IB_TIMEOUT_TIME Settings.ib_tout_interval
-#endif
+//#if 1
+uint8_t ib_upd_interval,ib_tout_interval;
+//#undef IB_UPDATE_TIME
+//#undef IB_TIMEOUT_TIME
+#define IB_UPDATE_TIME ib_upd_interval
+#define IB_TIMEOUT_TIME ib_tout_interval
+//#else
+//#undef IB_UPDATE_TIME
+//#undef IB_TIMEOUT_TIME
+//#define IB_UPDATE_TIME Settings.ib_upd_interval
+//#define IB_TIMEOUT_TIME Settings.ib_tout_interval
+//#endif
-char ib_mac[14];
-
-
- struct {
- union {
- struct {
- uint32_t init:1;
- };
- uint32_t all = 0;
- } mode;
- } ESP32BLE;
-
- void *beaconmutex = nullptr;
-
- #define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
-
-#else
-
- #include
-
- #define TMSBSIZ52 512
-
- #define HM17_BAUDRATE 9600
-
- #define IBEACON_DEBUG
-
- // use this for Version 110
- #define HM17_V110
-
- TasmotaSerial *IBEACON_Serial = nullptr;
-
- uint8_t hm17_found,hm17_cmd,hm17_flag;
-
- #ifdef IBEACON_DEBUG
- uint8_t hm17_debug=0;
- #endif
-
- // 78 is max serial response
- #define HM17_BSIZ 128
- char hm17_sbuffer[HM17_BSIZ];
- uint8_t hm17_sindex,hm17_result,hm17_scanning,hm17_connecting;
- uint32_t hm17_lastms;
-
- enum {HM17_TEST,HM17_ROLE,HM17_IMME,HM17_DISI,HM17_IBEA,HM17_SCAN,HM17_DISC,HM17_RESET,HM17_RENEW,HM17_CON};
- #define HM17_SUCESS 99
-
-#endif
+#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
struct IBEACON {
char FACID[8];
@@ -104,16 +81,10 @@ struct IBEACON {
char PWR[2];
char MAC[12];
char RSSI[4];
-#ifdef USE_IBEACON_ESP32
char NAME[16];
-#endif
};
-#ifdef USE_IBEACON_ESP32
- #define MAX_IBEACONS 32
-#else
- #define MAX_IBEACONS 16
-#endif
+#define MAX_IBEACONS 32
struct IBEACON_UID {
char MAC[12];
@@ -123,14 +94,78 @@ struct IBEACON_UID {
char MINOR[4];
uint8_t FLAGS;
uint8_t TIME;
-#ifdef USE_IBEACON_ESP32
uint8_t REPORTED;
uint8_t REPTIME;
+ uint8_t count; // count of adverts in REPTIME (reptime default = 10s)
+ uint32_t lastmqtt; // last time we sent something
char NAME[16];
-#endif
} ibeacons[MAX_IBEACONS];
-#ifdef USE_IBEACON_ESP32
+
+void CmndiBeacon(void);
+void CmndiBeaconOnlyAliased(void);
+void CmndiBeaconClear(void);
+void CmndiBeaconPeriod(void);
+void CmndiBeaconTimeout(void);
+
+#define D_CMND_IBEACON "IBEACON"
+
+const char kiBeacon_Commands[] PROGMEM = D_CMND_IBEACON "|"
+ "|"
+ "onlyaliased|"
+ "clear|"
+ "period|"
+ "timeout";
+
+void (*const iBeacon_Commands[])(void) PROGMEM = {
+ &CmndiBeacon,
+ &CmndiBeaconOnlyAliased,
+ &CmndiBeaconClear,
+ &CmndiBeaconPeriod,
+ &CmndiBeaconTimeout
+};
+
+uint8_t iBeaconOnlyAliased = 0;
+uint8_t iBeaconEnable = 0;
+
+
+void CmndiBeacon(void){
+ if (XdrvMailbox.data_len > 0) {
+ iBeaconEnable = XdrvMailbox.payload;
+ }
+ ResponseCmndNumber(iBeaconEnable);
+}
+
+void CmndiBeaconOnlyAliased(void){
+ if (XdrvMailbox.data_len > 0) {
+ iBeaconOnlyAliased = XdrvMailbox.payload;
+ }
+ ResponseCmndNumber(iBeaconOnlyAliased);
+}
+
+void CmndiBeaconClear(void){
+ uint32_t count = 0;
+ for (uint32_t cnt=0; cnt 0) {
+ IB_UPDATE_TIME = XdrvMailbox.payload;
+ }
+ ResponseCmndNumber(IB_UPDATE_TIME);
+}
+
+void CmndiBeaconTimeout(void){
+ if (XdrvMailbox.data_len > 0) {
+ IB_TIMEOUT_TIME = XdrvMailbox.payload;
+ }
+ ResponseCmndNumber(IB_TIMEOUT_TIME);
+}
+
uint32_t ibeacon_add(struct IBEACON *ib);
@@ -156,12 +191,29 @@ void DumpHex(const unsigned char * in, size_t insz, char * out)
int advertismentCallback(BLE_ESP32::ble_advertisment_t *pStruct)
{
struct IBEACON ib;
+ if (!iBeaconEnable) return 0;
+
BLEAdvertisedDevice *advertisedDevice = pStruct->advertisedDevice;
char sRSSI[6];
itoa(pStruct->RSSI,sRSSI,10);
const uint8_t *MAC = pStruct->addr;
+ const char *alias = BLE_ESP32::getAlias(MAC);
+ if (iBeaconOnlyAliased){
+ // ignore unless we have an alias.
+ if (!alias || !(*alias)){
+ return 0;
+ }
+ }
+ if (!alias) alias = "";
+
+ if (iBeaconOnlyAliased == 2){
+ if (strncmp(alias, "iB", 2)){
+ return 0;
+ }
+ }
+
int manufacturerDataLen = 0;
std::string data;
if (advertisedDevice->haveManufacturerData()){
@@ -192,6 +244,9 @@ int advertismentCallback(BLE_ESP32::ble_advertisment_t *pStruct)
DumpHex((const unsigned char*)MAC,6,ib.MAC);
memcpy(ib.RSSI,sRSSI,4);
memset(ib.NAME,0x0,16);
+ if (*alias){
+ strncpy(ib.NAME, alias, 16);
+ }
// if we added it
if (ibeacon_add(&ib) == 1){
@@ -221,52 +276,22 @@ int advertismentCallback(BLE_ESP32::ble_advertisment_t *pStruct)
memset(ib.NAME,0x0,16);
}
+ if (*alias){
+ strncpy(ib.NAME, alias,16);
+ }
+
ibeacon_add(&ib);
return 0;
}
-void ESP32Init() {
-
- if (!ESP32BLE.mode.init) {
- ESP32BLE.mode.init = 1;
- IB_UPDATE_TIME=IB_UPDATE_TIME_INTERVAL;
- IB_TIMEOUT_TIME=IB_TIMEOUT_INTERVAL;
- }
-}
-
-
-#endif
void IBEACON_Init() {
-
-
-#ifdef USE_IBEACON_ESP32
+ AddLog(LOG_LEVEL_INFO, PSTR("iBeacon register for advert callbacks"));
BLE_ESP32::registerForAdvertismentCallbacks((const char *)"iBeacon", advertismentCallback);
-#else
-
- hm17_found=0;
-
-// actually doesnt work reliably with software serial
- if (PinUsed(GPIO_IBEACON_RX) && PinUsed(GPIO_IBEACON_TX)) {
- IBEACON_Serial = new TasmotaSerial(Pin(GPIO_IBEACON_RX), Pin(GPIO_IBEACON_TX),1,0,TMSBSIZ52);
- if (IBEACON_Serial->begin(HM17_BAUDRATE)) {
- if (IBEACON_Serial->hardwareSerial()) {
- ClaimSerial();
- }
- hm17_sendcmd(HM17_TEST);
- hm17_lastms=millis();
- // in case of using Settings this has to be moved
- IB_UPDATE_TIME=IB_UPDATE_TIME_INTERVAL;
- IB_TIMEOUT_TIME=IB_TIMEOUT_INTERVAL;
- }
- }
-
-#endif
-
+ IB_UPDATE_TIME=IB_UPDATE_TIME_INTERVAL;
+ IB_TIMEOUT_TIME=IB_TIMEOUT_INTERVAL;
}
-#ifdef USE_IBEACON_ESP32
-
void esp32_every_second(void) {
for (uint32_t cnt=0; cnt < MAX_IBEACONS; cnt++) {
if (ibeacons[cnt].FLAGS) {
@@ -279,11 +304,16 @@ void esp32_every_second(void) {
uint32_t ageS = BLE_ESP32::devicePresent(mac);
- // if device not present at all.
- if (!ageS){
+ // if device not present at all or past local timeout.
+ if (!ageS || (ageS > IB_TIMEOUT_TIME)){
//AddLog(LOG_LEVEL_INFO, PSTR("iBeacon no device %s %02x%02x%02x%02x%02x%02x"),tmp, mac[0],mac[1], mac[2],mac[3], mac[4],mac[5]);
ibeacons[cnt].FLAGS=0;
- ibeacon_mqtt(ibeacons[cnt].MAC,"0000",ibeacons[cnt].UID,ibeacons[cnt].MAJOR,ibeacons[cnt].MINOR,ibeacons[cnt].NAME);
+ uint64_t now = esp_timer_get_time();
+ uint32_t nowms = now/1000;
+ float countspermssec = ((float)ibeacons[cnt].count)/(((float)(nowms - ibeacons[cnt].lastmqtt))/1000.0);
+ ibeacon_mqtt(ibeacons[cnt].MAC,"0000",ibeacons[cnt].UID,ibeacons[cnt].MAJOR,ibeacons[cnt].MINOR,ibeacons[cnt].NAME, (int)(countspermssec));
+ ibeacons[cnt].count = 0;
+ ibeacons[cnt].lastmqtt = nowms;
} else {
//AddLog(LOG_LEVEL_INFO, PSTR("iBeacon device %s %02x%02x%02x%02x%02x%02x"),tmp, mac[0],mac[1], mac[2],mac[3], mac[4],mac[5]);
}
@@ -293,90 +323,6 @@ void esp32_every_second(void) {
}
}
-#else
-
-void hm17_every_second(void) {
- if (!IBEACON_Serial) return;
-
- if (hm17_found) {
- if (IB_UPDATE_TIME && (TasmotaGlobal.uptime%IB_UPDATE_TIME==0)) {
- if (hm17_cmd!=99) {
- if (hm17_flag&2) {
- ib_sendbeep();
- } else {
- if (!hm17_connecting) {
- hm17_sendcmd(HM17_DISI);
- }
- }
- }
- }
- for (uint32_t cnt=0;cntIB_TIMEOUT_TIME) {
- ibeacons[cnt].FLAGS=0;
- ibeacon_mqtt(ibeacons[cnt].MAC,"0000",ibeacons[cnt].UID,ibeacons[cnt].MAJOR,ibeacons[cnt].MINOR);
- }
- }
- }
- } else {
- if (TasmotaGlobal.uptime%20==0) {
- hm17_sendcmd(HM17_TEST);
- }
- }
-}
-
-void hm17_sbclr(void) {
- memset(hm17_sbuffer,0,HM17_BSIZ);
- hm17_sindex=0;
- //IBEACON_Serial->flush();
-}
-
-void hm17_sendcmd(uint8_t cmd) {
- hm17_sbclr();
- hm17_cmd=cmd;
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("hm17cmd %d"),cmd);
-#endif
- switch (cmd) {
- case HM17_TEST:
- IBEACON_Serial->write("AT");
- break;
- case HM17_ROLE:
- IBEACON_Serial->write("AT+ROLE1");
- break;
- case HM17_IMME:
- IBEACON_Serial->write("AT+IMME1");
- break;
- case HM17_DISI:
- IBEACON_Serial->write("AT+DISI?");
- hm17_scanning=1;
- break;
- case HM17_IBEA:
- IBEACON_Serial->write("AT+IBEA1");
- break;
- case HM17_RESET:
- IBEACON_Serial->write("AT+RESET");
- break;
- case HM17_RENEW:
- IBEACON_Serial->write("AT+RENEW");
- break;
- case HM17_SCAN:
- IBEACON_Serial->write("AT+SCAN5");
- break;
- case HM17_DISC:
- IBEACON_Serial->write("AT+DISC?");
- hm17_scanning=1;
- break;
- case HM17_CON:
- IBEACON_Serial->write((const uint8_t*)"AT+CON",6);
- IBEACON_Serial->write((const uint8_t*)ib_mac,12);
- hm17_connecting=1;
- break;
- }
-}
-
-#endif
uint32_t ibeacon_add(struct IBEACON *ib) {
/* if (!strncmp(ib->MAJOR,"4B1C",4)) {
@@ -387,9 +333,6 @@ uint32_t ibeacon_add(struct IBEACON *ib) {
return 0;
}
- // don't bother protecting this.
- //TasAutoMutex localmutex(&beaconmutex, "iBeacAdd");
-
// keyfob starts with ffff, ibeacon has valid facid
if (!strncmp(ib->MAC,"FFFF",4) || strncmp(ib->FACID,"00000000",8)) {
for (uint32_t cnt=0;cntUID,PSTR("00000000000000000000000000000000"),32)) {
if (!strncmp(ibeacons[cnt].MAC,ib->MAC,12)) {
// exists
+ strncpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME));
memcpy(ibeacons[cnt].RSSI,ib->RSSI,4);
ibeacons[cnt].TIME=0;
-#ifdef USE_IBEACON_ESP32
if (ibeacons[cnt].REPTIME >= IB_UPDATE_TIME) {
ibeacons[cnt].REPTIME = 0;
ibeacons[cnt].REPORTED = 0;
}
-#endif
+ ibeacons[cnt].count++;
return 2;
}
} else {
if (!strncmp(ibeacons[cnt].UID,ib->UID,32)) {
// exists
+ strncpy(ibeacons[cnt].NAME,ib->NAME,sizeof(ibeacons[cnt].NAME));
memcpy(ibeacons[cnt].RSSI,ib->RSSI,4);
ibeacons[cnt].TIME=0;
-#ifdef USE_IBEACON_ESP32
if (ibeacons[cnt].REPTIME >= IB_UPDATE_TIME) {
ibeacons[cnt].REPTIME = 0;
ibeacons[cnt].REPORTED = 0;
}
-#endif
+ ibeacons[cnt].count++;
return 2;
}
}
@@ -425,6 +368,7 @@ uint32_t ibeacon_add(struct IBEACON *ib) {
}
for (uint32_t cnt=0;cntNAME,sizeof(ibeacons[cnt].NAME));
memcpy(ibeacons[cnt].MAC,ib->MAC,12);
memcpy(ibeacons[cnt].RSSI,ib->RSSI,4);
memcpy(ibeacons[cnt].UID,ib->UID,32);
@@ -432,11 +376,13 @@ uint32_t ibeacon_add(struct IBEACON *ib) {
memcpy(ibeacons[cnt].MINOR,ib->MINOR,4);
ibeacons[cnt].FLAGS=1;
ibeacons[cnt].TIME=0;
-#ifdef USE_IBEACON_ESP32
memcpy(ibeacons[cnt].NAME,ib->NAME,16);
ibeacons[cnt].REPTIME = 0;
ibeacons[cnt].REPORTED = 0;
-#endif
+ ibeacons[cnt].count = 0;
+ uint64_t now = esp_timer_get_time();
+ uint32_t nowms = now/1000;
+ ibeacons[cnt].lastmqtt = nowms;
return 1;
}
}
@@ -444,245 +390,23 @@ uint32_t ibeacon_add(struct IBEACON *ib) {
return 0;
}
-#ifndef USE_IBEACON_ESP32
-
-void hm17_decode(void) {
- struct IBEACON ib;
- switch (hm17_cmd) {
- case HM17_TEST:
- if (!strncmp(hm17_sbuffer,"OK",2)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("AT OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- hm17_found=1;
- }
- break;
- case HM17_ROLE:
- if (!strncmp(hm17_sbuffer,"OK+Set:1",8)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("ROLE OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- }
- break;
- case HM17_IMME:
- if (!strncmp(hm17_sbuffer,"OK+Set:1",8)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("IMME OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- }
- break;
- case HM17_IBEA:
- if (!strncmp(hm17_sbuffer,"OK+Set:1",8)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("IBEA OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- }
- break;
- case HM17_SCAN:
- if (!strncmp(hm17_sbuffer,"OK+Set:5",8)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("SCAN OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- }
- break;
- case HM17_RESET:
- if (!strncmp(hm17_sbuffer,"OK+RESET",8)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("RESET OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- }
- break;
- case HM17_RENEW:
- if (!strncmp(hm17_sbuffer,"OK+RENEW",8)) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("RENEW OK"));
-#endif
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
- }
- break;
- case HM17_CON:
- if (!strncmp(hm17_sbuffer,"OK+CONNA",8)) {
- hm17_sbclr();
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("CONNA OK"));
-#endif
- hm17_connecting=2;
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+CONNE",8)) {
- hm17_sbclr();
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("CONNE ERROR"));
-#endif
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+CONNF",8)) {
- hm17_sbclr();
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("CONNF ERROR"));
-#endif
- break;
- }
- if (hm17_connecting==2 && !strncmp(hm17_sbuffer,"OK+CONN",7)) {
- hm17_sbclr();
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("CONN OK"));
-#endif
- hm17_connecting=3;
- hm17_sendcmd(HM17_TEST);
- hm17_connecting=0;
- break;
- }
- break;
-
- case HM17_DISI:
- case HM17_DISC:
- if (!strncmp(hm17_sbuffer,"OK+DISCS",8)) {
- hm17_sbclr();
- hm17_result=1;
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("DISCS OK"));
-#endif
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+DISIS",8)) {
- hm17_sbclr();
- hm17_result=1;
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("DISIS OK"));
-#endif
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+DISCE",8)) {
- hm17_sbclr();
- hm17_result=HM17_SUCESS;
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR("DISCE OK"));
-#endif
- hm17_scanning=0;
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+NAME:",8)) {
- if (hm17_sbuffer[hm17_sindex-1]=='\n') {
- hm17_result=HM17_SUCESS;
-#ifdef IBEACON_DEBUG
- if (hm17_debug) {
- AddLog(LOG_LEVEL_INFO, PSTR("NAME OK"));
- AddLog(LOG_LEVEL_INFO, PSTR(">>%s"),&hm17_sbuffer[8]);
- }
-#endif
- hm17_sbclr();
- }
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+DIS0:",8)) {
- if (hm17_cmd==HM17_DISI) {
-#ifdef HM17_V110
- goto hm17_v110;
-#endif
- } else {
- if (hm17_sindex==20) {
- hm17_result=HM17_SUCESS;
-#ifdef IBEACON_DEBUG
- if (hm17_debug) {
- AddLog(LOG_LEVEL_INFO, PSTR("DIS0 OK"));
- AddLog(LOG_LEVEL_INFO, PSTR(">>%s"),&hm17_sbuffer[8]);
- }
-#endif
- hm17_sbclr();
- }
- }
- break;
- }
- if (!strncmp(hm17_sbuffer,"OK+DISC:",8)) {
-hm17_v110:
- if (hm17_cmd==HM17_DISI) {
- if (hm17_sindex==78) {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) {
- AddLog(LOG_LEVEL_INFO, PSTR("DISC: OK"));
- //OK+DISC:4C 000C0E:003 A9144081A8 3B16849611 862EC1005: 0B1CE7485D :4DB4E940F C0E:-078
- AddLog(LOG_LEVEL_INFO, PSTR(">>%s"),&hm17_sbuffer[8]);
- }
-#endif
- memcpy(ib.FACID,&hm17_sbuffer[8],8);
- memcpy(ib.UID,&hm17_sbuffer[8+8+1],32);
- memcpy(ib.MAJOR,&hm17_sbuffer[8+8+1+32+1],4);
- memcpy(ib.MINOR,&hm17_sbuffer[8+8+1+32+1+4],4);
- memcpy(ib.PWR,&hm17_sbuffer[8+8+1+32+1+4+4],2);
- memcpy(ib.MAC,&hm17_sbuffer[8+8+1+32+1+4+4+2+1],12);
- memcpy(ib.RSSI,&hm17_sbuffer[8+8+1+32+1+4+4+2+1+12+1],4);
-
- if (ibeacon_add(&ib)) {
- ibeacon_mqtt(ib.MAC,ib.RSSI,ib.UID,ib.MAJOR,ib.MINOR);
- }
- hm17_sbclr();
- hm17_result=1;
- }
- } else {
-#ifdef IBEACON_DEBUG
- if (hm17_debug) AddLog(LOG_LEVEL_INFO, PSTR(">->%s"),&hm17_sbuffer[8]);
-#endif
- }
- break;
- }
- }
-}
-
-#endif
void IBEACON_loop() {
-
-#ifdef USE_IBEACON_ESP32
//TasAutoMutex localmutex(&beaconmutex, "iBeacLoop");
- for (uint32_t cnt=0;cnt 10)) {
+ uint64_t now = esp_timer_get_time();
+ uint32_t nowms = now/1000;
+ float countspermssec = ((float)ibeacons[cnt].count)/(((float)(nowms - ibeacons[cnt].lastmqtt))/1000.0);
+ // squash if it only just appeared
+ if (ibeacons[cnt].count < 2) countspermssec = 0.0;
+ ibeacon_mqtt(ibeacons[cnt].MAC,ibeacons[cnt].RSSI,ibeacons[cnt].UID,ibeacons[cnt].MAJOR,ibeacons[cnt].MINOR,ibeacons[cnt].NAME, (int)(countspermssec));
+ ibeacons[cnt].count = 0;
+ ibeacons[cnt].lastmqtt = nowms;
ibeacons[cnt].REPORTED=1;
+ ibeacons[cnt].REPTIME = 0;
}
}
-
-#else
-
- if (!IBEACON_Serial) return;
-
- uint32_t difftime=millis()-hm17_lastms;
-
- while (IBEACON_Serial->available()) {
- hm17_lastms=millis();
- // shift in
- if (hm17_sindexread();
- hm17_sindex++;
- hm17_decode();
- } else {
- hm17_sindex=0;
- break;
- }
- }
-
- if (hm17_cmd==99) {
- if (hm17_sindex>=HM17_BSIZ-2 || (hm17_sindex && (difftime>100))) {
- AddLog(LOG_LEVEL_INFO, PSTR("%s"),hm17_sbuffer);
- hm17_sbclr();
- }
- }
-
-#endif
-
}
#ifdef USE_WEBSERVER
@@ -691,18 +415,14 @@ const char HTTP_IBEACON_mac[] PROGMEM =
"{s}IBEACON-MAC : %s" " {m} RSSI : %s" "{e}";
const char HTTP_IBEACON_uid[] PROGMEM =
"{s}IBEACON-UID : %s" " {m} RSSI : %s" "{e}";
-#ifdef USE_IBEACON_ESP32
const char HTTP_IBEACON_name[] PROGMEM =
"{s}IBEACON-NAME : %s (%s)" " {m} RSSI : %s" "{e}";
-#endif
void IBEACON_Show(void) {
char mac[14];
char rssi[6];
char uid[34];
-#ifdef USE_IBEACON_ESP32
char name[18];
//TasAutoMutex localmutex(&beaconmutex, "iBeacShow");
-#endif
int total = 0;
for (uint32_t cnt=0;cnt='0' && *cp<='8') {
- hm17_sendcmd(*cp&7);
- Response_P(S_JSON_IBEACON, XSNS_52,"hm17cmd",*cp&7);
- } else if (*cp=='s') {
- cp++;
- len--;
- while (*cp==' ') {
- len--;
- cp++;
- }
- IBEACON_Serial->write((uint8_t*)cp,len);
- hm17_cmd=99;
- Response_P(S_JSON_IBEACON1, XSNS_52,"hm17cmd",cp);
- }
-#endif
-#ifdef IBEACON_DEBUG
- else if (*cp=='d') {
- cp++;
- hm17_debug=atoi(cp);
- Response_P(S_JSON_IBEACON, XSNS_52,"debug",hm17_debug);
- }
-#endif
} else {
serviced=false;
}
return serviced;
}
-#define D_CMND_IBEACON "IBEACON"
-
-#ifndef USE_IBEACON_ESP32
-//"IBEACON_FFFF3D1B1E9D_RSSI", Data "99" causes TAG to beep
-bool ibeacon_cmd(void) {
- ib_mac[0]=0;
- int16_t rssi=0;
- const char S_JSON_IBEACON[] = "{\"" D_CMND_IBEACON "_%s_RSSI\":%d}";
- uint8_t cmd_len = strlen(D_CMND_IBEACON);
- if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_IBEACON), cmd_len)) {
- // IBEACON prefix
- rssi = XdrvMailbox.payload;
- if (rssi==99) {
- memcpy(ib_mac,XdrvMailbox.topic+cmd_len+1,12);
- ib_mac[12]=0;
- if (hm17_scanning) {
- // postpone sendbeep
- hm17_flag|=2;
- } else {
- ib_sendbeep();
- }
- }
- Response_P(S_JSON_IBEACON,ib_mac,rssi);
- return true;
- }
- return false;
-}
-
-void ib_sendbeep(void) {
- hm17_flag=0;
- hm17_sendcmd(HM17_CON);
-}
-
-#endif
-
-#ifdef USE_IBEACON_ESP32
-void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *major,const char *minor, const char *name) {
-#else
-void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *major,const char *minor) {
-#endif
+void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *major,const char *minor, const char *name, int count) {
char s_mac[14];
char s_uid[34];
char s_major[6];
char s_minor[6];
char s_rssi[6];
-#ifdef USE_IBEACON_ESP32
char *s_state;
-#endif
char s_name[18];
memcpy(s_mac,mac,12);
s_mac[12]=0;
@@ -867,32 +510,27 @@ void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *m
memcpy(s_rssi,rssi,4);
s_rssi[4]=0;
int16_t n_rssi=atoi(s_rssi);
-#ifdef USE_IBEACON_ESP32
if (n_rssi) {
s_state=(char *)"ON";
} else {
s_state=(char *)"OFF";
}
-#endif
+ memcpy(s_name,name,16);
+ s_name[16]=0;
+
// if uid == all zeros, take mac
if (!strncmp_P(s_uid,PSTR("00000000000000000000000000000000"),32)) {
-#ifdef USE_IBEACON_ESP32
if (name[0]) {
- memcpy(s_name,name,16);
- s_name[16]=0;
- ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"MAC\":\"%s\",\"NAME\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\"}}"),s_mac,s_name,n_rssi,s_state);
+ ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"MAC\":\"%s\",\"NAME\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\",\"PERSEC\":%d}}"),s_mac,s_name,n_rssi,s_state, count);
} else {
- ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"MAC\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\"}}"),s_mac,n_rssi,s_state);
+ ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"MAC\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\",\"PERSEC\":%d}}"),s_mac,n_rssi,s_state, count);
}
-#else
- ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"MAC\":\"%s\",\"UID\":\"%s\",\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"RSSI\":%d}}"),s_mac,s_uid,s_major,s_minor,n_rssi);
-#endif
} else {
-#ifdef USE_IBEACON_ESP32
- ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"UID\":\"%s\",\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"MAC\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\"}}"),s_uid,s_major,s_minor,s_mac,n_rssi,s_state);
-#else
- ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"UID\":\"%s\",\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"MAC\":\"%s\",\"RSSI\":%d}}"),s_uid,s_major,s_minor,s_mac,n_rssi);
-#endif
+ if (name[0]) {
+ ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"MAC\":\"%s\",\"NAME\":\"%s\",\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"MAC\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\",\"PERSEC\":%d}}"),s_uid,s_name,s_major,s_minor,s_mac,n_rssi,s_state,count);
+ } else {
+ ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "\":{\"UID\":\"%s\",\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"MAC\":\"%s\",\"RSSI\":%d,\"STATE\":\"%s\",\"PERSEC\":%d}}"),s_uid,s_major,s_minor,s_mac,n_rssi,s_state,count);
+ }
}
MqttPublishTeleSensor();
@@ -911,46 +549,29 @@ bool Xsns52(byte function)
case FUNC_INIT:
IBEACON_Init();
break;
-#ifdef USE_IBEACON_ESP32
- case FUNC_EVERY_250_MSECOND:
- if (!ESP32BLE.mode.init) {
- ESP32Init();
- }
- break;
-#endif
case FUNC_LOOP:
- IBEACON_loop();
+ if (iBeaconEnable) IBEACON_loop();
break;
case FUNC_EVERY_SECOND:
-#ifdef USE_IBEACON_ESP32
- esp32_every_second();
-#else
- hm17_every_second();
-#endif
+ if (iBeaconEnable) esp32_every_second();
break;
+ case FUNC_COMMAND:
+ result = DecodeCommand(kiBeacon_Commands, iBeacon_Commands);
+ break;
+
case FUNC_COMMAND_SENSOR:
if (XSNS_52 == XdrvMailbox.index) {
result = xsns52_cmd();
}
break;
-#ifndef USE_IBEACON_ESP32
- case FUNC_COMMAND:
- result=ibeacon_cmd();
- break;
-#endif
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
-#ifndef USE_IBEACON_ESP32
- if (hm17_found) IBEACON_Show();
-#else
- IBEACON_Show();
-#endif
+ if (iBeaconEnable) IBEACON_Show();
break;
#endif // USE_WEBSERVER
}
return result;
}
-#endif // USE_IBEACON
-
-#endif
\ No newline at end of file
+#endif // USE_BLE_ESP32
+#endif // CONFIG_IDF_TARGET_ESP32
diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino
index 188ed2941..93cce5eb8 100755
--- a/tasmota/xsns_52_ibeacon.ino
+++ b/tasmota/xsns_52_ibeacon.ino
@@ -31,16 +31,18 @@
#define IB_UPDATE_TIME_INTERVAL 10
// should be in Settings
-#if 1
+//#if 1
uint8_t ib_upd_interval,ib_tout_interval;
+//#undef IB_UPDATE_TIME
+//#undef IB_TIMEOUT_TIME
#define IB_UPDATE_TIME ib_upd_interval
#define IB_TIMEOUT_TIME ib_tout_interval
-#else
-#undef IB_UPDATE_TIME
-#undef IB_TIMEOUT_TIME
-#define IB_UPDATE_TIME Settings.ib_upd_interval
-#define IB_TIMEOUT_TIME Settings.ib_tout_interval
-#endif
+//#else
+//#undef IB_UPDATE_TIME
+//#undef IB_TIMEOUT_TIME
+//#define IB_UPDATE_TIME Settings.ib_upd_interval
+//#define IB_TIMEOUT_TIME Settings.ib_tout_interval
+//#endif
char ib_mac[14];
diff --git a/tasmota/xsns_62_esp32_mi_ble.ino b/tasmota/xsns_62_esp32_mi_ble.ino
index 403a2e938..cfa81b5ca 100644
--- a/tasmota/xsns_62_esp32_mi_ble.ino
+++ b/tasmota/xsns_62_esp32_mi_ble.ino
@@ -2649,28 +2649,31 @@ void MI32DiscoveryOneMISensor(){
p->nextDiscoveryData = 0;
}
+ char DiscoveryTopic[80];
+ const char *host = NetworkHostname();
+ const char *devtype = kMI32DeviceType[p->type-1];
+ char idstr[32];
+ const char *alias = BLE_ESP32::getAlias(p->MAC);
+ const char *id = idstr;
+ if (alias && *alias){
+ id = alias;
+ } else {
+ sprintf(idstr, PSTR("%s%02x%02x%02x"),
+ devtype,
+ p->MAC[3], p->MAC[4], p->MAC[5]);
+ }
+
+ char SensorTopic[60];
+ sprintf(SensorTopic, "tele/tasmota_ble/%s",
+ id);
+
+
//int i = p->nextDiscoveryData*3;
for (int i = 0; i < datacount*3; i += 3){
if (!classes[i] || !classes[i+1] || !classes[i+2]){
return;
}
- char idstr[32];
- const char *alias = BLE_ESP32::getAlias(p->MAC);
- const char *id = idstr;
- if (alias && *alias){
- id = alias;
- } else {
- sprintf(idstr, PSTR("%s%02x%02x%02x"),
- kMI32DeviceType[p->type-1],
- p->MAC[3], p->MAC[4], p->MAC[5]);
- }
-
- char SensorTopic[60];
- sprintf(SensorTopic, "tele/tasmota_ble/%s",
- id);
-
-
ResponseClear();
/*
@@ -2689,9 +2692,9 @@ void MI32DiscoveryOneMISensor(){
//"\"name\":\"%s\"},"
id,
//\"model\":\"%s\",
- kMI32DeviceType[p->type-1],
+ devtype,
//\"via_device\":\"%s\"
- NetworkHostname(),
+ host,
//"\"dev_cla\":\"%s\","
classes[i],
//"\"json_attr_t\":\"%s\"," - the topic the sensor publishes on
@@ -2709,7 +2712,6 @@ void MI32DiscoveryOneMISensor(){
//
);
- char DiscoveryTopic[80];
sprintf(DiscoveryTopic, "homeassistant/sensor/%s/%s/config",
id, classes[i+1]);