[BLE] Add moving beacon detection (#1636)
This commit is contained in:
1 parent
28f9fbff60
commit
b1667190d5
6 files changed
+56
-4
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
@@ -25,6 +25,8 @@ Added to that it retrieves the measures from the devices below. By default the d
|
|||||||
| BLE watches with fixed MAC||rssi for presence detection|
|
| BLE watches with fixed MAC||rssi for presence detection|
|
||||||
| BLE beacons keychains||rssi for presence detection|
|
| BLE beacons keychains||rssi for presence detection|
|
||||||
| BlueCharm|BC08|acceleration x/y/z-axis/voltage/temperature|
|
| BlueCharm|BC08|acceleration x/y/z-axis/voltage/temperature|
|
||||||
|
| BlueCharm|BC04P|acceleration x/y/z-axis/voltage/temperature|
|
||||||
|
| BlueCharm|BC021|acceleration x/y/z-axis/voltage/temperature|
|
||||||
| BlueMaestro|TempoDisc 1 in 1|temperature/battery|
|
| BlueMaestro|TempoDisc 1 in 1|temperature/battery|
|
||||||
| BlueMaestro|TempoDisc 3 in 1|temperature/humidity/dew point/battery|
|
| BlueMaestro|TempoDisc 3 in 1|temperature/humidity/dew point/battery|
|
||||||
| BlueMaestro|TempoDisc 4 in 1|temperature/humidity/pressure/battery|
|
| BlueMaestro|TempoDisc 4 in 1|temperature/humidity/pressure/battery|
|
||||||
|
|||||||
@@ -52,6 +52,23 @@ Note that you can find apps to simulate beacons and do some tests like [Beacon s
|
|||||||
|
|
||||||
iOS version >=10 devices advertise without an extra app MAC address, nevertheless this address [changes randomly](https://github.com/1technophile/OpenMQTTGateway/issues/71) and cannot be used for presence detection. You must install an app to advertise a fixed MAC address.
|
iOS version >=10 devices advertise without an extra app MAC address, nevertheless this address [changes randomly](https://github.com/1technophile/OpenMQTTGateway/issues/71) and cannot be used for presence detection. You must install an app to advertise a fixed MAC address.
|
||||||
|
|
||||||
|
## Receiving signals from BLE devices with accelerometers for movement detection
|
||||||
|
The gateway is designed to detect BLE trackers from BlueCharm and automatically create a binary sensor entity in accordance with the Home Assistant discovery convention, provided that auto discovery is enabled.
|
||||||
|
|
||||||
|
The binary sensor entity's state will be set to on or off based on whether the BLE beacon's x-axis acceleration value is detected during the time period defined by the movingtimer parameter.
|
||||||
|
|
||||||
|
By default, the movingtimer parameter is set to 60 seconds (60,000 ms). To modify this value, use the following command:
|
||||||
|
|
||||||
|
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"movingtimer":66000}'`
|
||||||
|
|
||||||
|
To ensure proper functionality, configure the beacon using the KBeacon or KBeaconPro app (depending on your specific sensor) with the following settings:
|
||||||
|
* In the General tab, set the Trigger Command to "motion".
|
||||||
|
* In the Slot tab, enable advertisement with the Beacon Type set to "KSensor", the Trigger Only Advertisement option set to "YES", and the Sensor Axis set to "ON".
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Setting a white or black list
|
## Setting a white or black list
|
||||||
A black list is a list of MAC addresses that will never be published by OMG
|
A black list is a list of MAC addresses that will never be published by OMG
|
||||||
to set black list
|
to set black list
|
||||||
|
|||||||
+32
-3
@@ -104,6 +104,7 @@ void BTConfig_init() {
|
|||||||
BTConfig.pubBeaconUuidForTopic = useBeaconUuidForTopic;
|
BTConfig.pubBeaconUuidForTopic = useBeaconUuidForTopic;
|
||||||
BTConfig.ignoreWBlist = false;
|
BTConfig.ignoreWBlist = false;
|
||||||
BTConfig.presenceAwayTimer = PresenceAwayTimer;
|
BTConfig.presenceAwayTimer = PresenceAwayTimer;
|
||||||
|
BTConfig.movingTimer = MovingTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watchdog, if there was no change of BLE scanCount, restart BT
|
// Watchdog, if there was no change of BLE scanCount, restart BT
|
||||||
@@ -149,6 +150,7 @@ String stateBTMeasures(bool start) {
|
|||||||
jo["pubBeaconUuidForTopic"] = BTConfig.pubBeaconUuidForTopic;
|
jo["pubBeaconUuidForTopic"] = BTConfig.pubBeaconUuidForTopic;
|
||||||
jo["ignoreWBlist"] = BTConfig.ignoreWBlist;
|
jo["ignoreWBlist"] = BTConfig.ignoreWBlist;
|
||||||
jo["presenceawaytimer"] = BTConfig.presenceAwayTimer;
|
jo["presenceawaytimer"] = BTConfig.presenceAwayTimer;
|
||||||
|
jo["movingtimer"] = BTConfig.movingTimer;
|
||||||
jo["btqblck"] = btQueueBlocked;
|
jo["btqblck"] = btQueueBlocked;
|
||||||
jo["btqsum"] = btQueueLengthSum;
|
jo["btqsum"] = btQueueLengthSum;
|
||||||
jo["btqsnd"] = btQueueLengthCount;
|
jo["btqsnd"] = btQueueLengthCount;
|
||||||
@@ -227,6 +229,8 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
|
|||||||
Config_update(BTdata, "presenceUseBeaconUuid", BTConfig.presenceUseBeaconUuid);
|
Config_update(BTdata, "presenceUseBeaconUuid", BTConfig.presenceUseBeaconUuid);
|
||||||
// Timer to trigger a device state as offline if not seen
|
// Timer to trigger a device state as offline if not seen
|
||||||
Config_update(BTdata, "presenceawaytimer", BTConfig.presenceAwayTimer);
|
Config_update(BTdata, "presenceawaytimer", BTConfig.presenceAwayTimer);
|
||||||
|
// Timer to trigger a device state as offline if not seen
|
||||||
|
Config_update(BTdata, "movingtimer", BTConfig.movingTimer);
|
||||||
// MinRSSI set
|
// MinRSSI set
|
||||||
Config_update(BTdata, "minrssi", BTConfig.minRssi);
|
Config_update(BTdata, "minrssi", BTConfig.minRssi);
|
||||||
// Send undecoded device data
|
// Send undecoded device data
|
||||||
@@ -277,6 +281,7 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
|
|||||||
jo["pubBeaconUuidForTopic"] = BTConfig.pubBeaconUuidForTopic;
|
jo["pubBeaconUuidForTopic"] = BTConfig.pubBeaconUuidForTopic;
|
||||||
jo["ignoreWBlist"] = BTConfig.ignoreWBlist;
|
jo["ignoreWBlist"] = BTConfig.ignoreWBlist;
|
||||||
jo["presenceawaytimer"] = BTConfig.presenceAwayTimer;
|
jo["presenceawaytimer"] = BTConfig.presenceAwayTimer;
|
||||||
|
jo["movingtimer"] = BTConfig.movingTimer;
|
||||||
// Save config into NVS (non-volatile storage)
|
// Save config into NVS (non-volatile storage)
|
||||||
String conf = "";
|
String conf = "";
|
||||||
serializeJson(jsonBuffer, conf);
|
serializeJson(jsonBuffer, conf);
|
||||||
@@ -490,14 +495,15 @@ void updateDevicesStatus() {
|
|||||||
for (vector<BLEdevice*>::iterator it = devices.begin(); it != devices.end(); ++it) {
|
for (vector<BLEdevice*>::iterator it = devices.begin(); it != devices.end(); ++it) {
|
||||||
BLEdevice* p = *it;
|
BLEdevice* p = *it;
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::NUT ||
|
// Device tracker devices
|
||||||
|
if (BTConfig.presenceEnable && (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::NUT ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::MIBAND ||
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::MIBAND ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::TAGIT ||
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::TAGIT ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::TILE ||
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::TILE ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::TILEN ||
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::TILEN ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::ITAG ||
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::ITAG ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::RUUVITAG_RAWV1 ||
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::RUUVITAG_RAWV1 ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::RUUVITAG_RAWV2) { // We apply the offline status only for tracking device, can be extended further to all the devices
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::RUUVITAG_RAWV2)) { // We apply the offline status only for tracking device, can be extended further to all the devices
|
||||||
if ((p->lastUpdate != 0) && (p->lastUpdate < (now - BTConfig.presenceAwayTimer) && (now > BTConfig.presenceAwayTimer)) &&
|
if ((p->lastUpdate != 0) && (p->lastUpdate < (now - BTConfig.presenceAwayTimer) && (now > BTConfig.presenceAwayTimer)) &&
|
||||||
(BTConfig.ignoreWBlist || ((!oneWhite || isWhite(p)) && !isBlack(p)))) { // Only if WBlist is disabled OR ((no white MAC OR this MAC is white) AND not a black listed MAC)) {
|
(BTConfig.ignoreWBlist || ((!oneWhite || isWhite(p)) && !isBlack(p)))) { // Only if WBlist is disabled OR ((no white MAC OR this MAC is white) AND not a black listed MAC)) {
|
||||||
JsonObject BLEdata = getBTJsonObject();
|
JsonObject BLEdata = getBTJsonObject();
|
||||||
@@ -508,6 +514,18 @@ void updateDevicesStatus() {
|
|||||||
p->lastUpdate = 0;
|
p->lastUpdate = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Moving detection devices (devices with an accelerometer)
|
||||||
|
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BC08) {
|
||||||
|
if ((p->lastUpdate != 0) && (p->lastUpdate < (now - BTConfig.movingTimer) && (now > BTConfig.movingTimer)) &&
|
||||||
|
(BTConfig.ignoreWBlist || ((!oneWhite || isWhite(p)) && !isBlack(p)))) { // Only if WBlist is disabled OR ((no white MAC OR this MAC is white) AND not a black listed MAC)) {
|
||||||
|
JsonObject BLEdata = getBTJsonObject();
|
||||||
|
BLEdata["id"] = p->macAdr;
|
||||||
|
BLEdata["state"] = "offline";
|
||||||
|
pubBT(BLEdata);
|
||||||
|
// We set the lastUpdate to 0 to avoid replublishing the offline state
|
||||||
|
p->lastUpdate = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,7 +740,6 @@ void procBLETask(void* pvParameters) {
|
|||||||
} else {
|
} else {
|
||||||
Log.trace(F("Filtered MAC device" CR));
|
Log.trace(F("Filtered MAC device" CR));
|
||||||
}
|
}
|
||||||
if (BTConfig.presenceEnable)
|
|
||||||
updateDevicesStatus();
|
updateDevicesStatus();
|
||||||
}
|
}
|
||||||
delete (advertisedDevice);
|
delete (advertisedDevice);
|
||||||
@@ -977,6 +994,7 @@ void setupBT() {
|
|||||||
Log.notice(F("minrssi: %d" CR), -abs(BTConfig.minRssi));
|
Log.notice(F("minrssi: %d" CR), -abs(BTConfig.minRssi));
|
||||||
Log.notice(F("Low Power Mode: %d" CR), lowpowermode);
|
Log.notice(F("Low Power Mode: %d" CR), lowpowermode);
|
||||||
Log.notice(F("Presence Away Timer: %d" CR), BTConfig.presenceAwayTimer);
|
Log.notice(F("Presence Away Timer: %d" CR), BTConfig.presenceAwayTimer);
|
||||||
|
Log.notice(F("Moving Timer: %d" CR), BTConfig.movingTimer);
|
||||||
|
|
||||||
atomic_init(&forceBTScan, 0); // in theory, we don't need this
|
atomic_init(&forceBTScan, 0); // in theory, we don't need this
|
||||||
atomic_init(&jsonBTBufferQueueNext, 0); // in theory, we don't need this
|
atomic_init(&jsonBTBufferQueueNext, 0); // in theory, we don't need this
|
||||||
@@ -1057,6 +1075,17 @@ void launchBTDiscovery(bool overrideDiscovery) {
|
|||||||
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
||||||
stateClassNone);
|
stateClassNone);
|
||||||
}
|
}
|
||||||
|
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BC08) {
|
||||||
|
String sensor_name = String(model_id.c_str()) + "-moving";
|
||||||
|
String sensor_id = macWOdots + "-moving";
|
||||||
|
createDiscovery("binary_sensor",
|
||||||
|
discovery_topic.c_str(), sensor_name.c_str(), sensor_id.c_str(),
|
||||||
|
will_Topic, "moving", "{% if value_json.get('accx') -%}on{%- else -%}off{%- endif %}",
|
||||||
|
"on", "off", "",
|
||||||
|
0, "", "", false, "",
|
||||||
|
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
||||||
|
stateClassNone);
|
||||||
|
}
|
||||||
if (!properties.empty()) {
|
if (!properties.empty()) {
|
||||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
deserializeJson(jsonBuffer, properties);
|
deserializeJson(jsonBuffer, properties);
|
||||||
|
|||||||
+5
-1
@@ -94,7 +94,10 @@ extern int btQueueLengthCount;
|
|||||||
# define TimeBtwConnect 3600000 //define default time between BLE connection attempt (not used for immediate actions); in milliseconds
|
# define TimeBtwConnect 3600000 //define default time between BLE connection attempt (not used for immediate actions); in milliseconds
|
||||||
#endif
|
#endif
|
||||||
#ifndef PresenceAwayTimer
|
#ifndef PresenceAwayTimer
|
||||||
# define PresenceAwayTimer 120000 //define the time between Offline Status update for the sensors
|
# define PresenceAwayTimer 120000 //define the time between Offline Status update for the tracker sensors
|
||||||
|
#endif
|
||||||
|
#ifndef MovingTimer
|
||||||
|
# define MovingTimer 60000 //define the time between Offline Status update for the moving sensors with an accelerometer
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BLEScanDuplicateCacheSize
|
#ifndef BLEScanDuplicateCacheSize
|
||||||
@@ -168,6 +171,7 @@ struct BTConfig_s {
|
|||||||
bool pubBeaconUuidForTopic; // Use iBeacon UUID as topic, instead of sender (random) MAC address
|
bool pubBeaconUuidForTopic; // Use iBeacon UUID as topic, instead of sender (random) MAC address
|
||||||
bool ignoreWBlist; // Disable Whitelist & Blacklist
|
bool ignoreWBlist; // Disable Whitelist & Blacklist
|
||||||
unsigned long presenceAwayTimer; //Timer that trigger a tracker state as offline if not seen
|
unsigned long presenceAwayTimer; //Timer that trigger a tracker state as offline if not seen
|
||||||
|
unsigned long movingTimer; //Timer that trigger a moving sensor state as offline if not seen
|
||||||
};
|
};
|
||||||
|
|
||||||
// Global struct to store live BT configuration data
|
// Global struct to store live BT configuration data
|
||||||
|
|||||||
Reference in new issue
Block a user