Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BT] Device Tracker sync across gateways #2094

Merged
merged 1 commit into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions docs/use/ble.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,12 @@ Once the data has been transmitted to the MQTT broker, it can be easily integrat
Examples of compatible sensors among [our list](https://decoder.theengs.io/devices/devices_by_brand.html: Mi Flora, Mi jia, LYWDS02, LYWSD03MMC, ClearGrass, Mi scale, iBBQ, TPMS

## Receiving signals from BLE devices for Device Tracker detection
The gateway will detect BLE trackers from Tile, Nut, TagIt and iTag, as well as other devices with additional properties decoding like Mi Band, Amazfit, RuuviTag and others indicated as Device Trackers in the [compatible BLE devices list](https://decoder.theengs.io/devices/devices.html), and automatically create a device tracker entity following the Home Assistant discovery convention (if auto discovery is activated).
The gateway will detect BLE trackers from Tile, Nut, TagIt, iTAG, Gigaset G-Tag and TicWatch GTH (Pro), as well as other devices with additional properties decoding like Mi Band, Amazfit, RuuviTag and others indicated as Device Trackers in the [compatible BLE devices list](https://decoder.theengs.io/devices/devices.html), and automatically create a device tracker entity following the Home Assistant discovery convention (if auto discovery is activated).

The devicen tracker entity created can be attached to a person to leverage presence detection. The `away` or `not home` state is triggered if the BLE tracker is not detected during the timer defined by `presenceawaytimer`.

![Away home Home assistant view](../img/OpenMQTTGateway-BLE-tracker-Home-Assistant.png)

If you have multiple gateways, your BLE trackers may not be detected temporary by one gateway but still by the others. In this case you will see the tracker appears offline briefly and online again once it is detected by the others gateways.

By default `presenceawaytimer` is set to 120s, you can change it from the slider in your controller or with the following command (ms)

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"presenceawaytimer":66000}'`
Expand Down
29 changes: 29 additions & 0 deletions main/ZgatewayBT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,27 @@ void PublishDeviceData(JsonObject& BLEdata) {
Log.notice(F("Not a sensor device filtered" CR));
return;
}

# if BLEDecoder
if (enableMultiGTWSync && BLEdata.containsKey("model_id") && BLEdata.containsKey("id")) {
// Publish tracker sync message
bool isTracker = false;
std::string tag = decoder.getTheengAttribute(BLEdata["model_id"].as<const char*>(), "tag");
if (tag.length() >= 4) {
isTracker = checkIfIsTracker(tag[3]);
}

if (isTracker) {
StaticJsonDocument<JSON_MSG_BUFFER> BLEdataBuffer;
JsonObject TrackerSyncdata = BLEdataBuffer.to<JsonObject>();
TrackerSyncdata["gatewayid"] = gateway_name;
TrackerSyncdata["trackerid"] = BLEdata["id"].as<const char*>();
String topic = String(mqtt_topic) + String(subjectTrackerSync);
TrackerSyncdata["topic"] = topic.c_str();
enqueueJsonObject(TrackerSyncdata);
}
}
# endif
} else {
Log.notice(F("Low rssi, device filtered" CR));
return;
Expand Down Expand Up @@ -1553,6 +1574,14 @@ void XtoBT(const char* topicOri, JsonObject& BTdata) { // json object decoding
Log.error(F("BLE busy - command not sent" CR));
gatewayState = GatewayState::ERROR;
}
} else if (strstr(topicOri, subjectTrackerSync) != NULL) {
if (BTdata.containsKey("gatewayid") && BTdata.containsKey("trackerid") && BTdata["gatewayid"] != gateway_name) {
BLEdevice* device = getDeviceByMac(BTdata["trackerid"].as<const char*>());
if (device != &NO_BT_DEVICE_FOUND && device->lastUpdate != 0) {
device->lastUpdate = 0;
Log.notice(F("Tracker %s disassociated by gateway %s" CR), BTdata["trackerid"].as<const char*>(), BTdata["gatewayid"].as<const char*>());
}
}
}
}
#endif
5 changes: 5 additions & 0 deletions main/config_BT.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern String stateBTMeasures(bool);
#define subjectBTtoMQTT "/BTtoMQTT"
#define subjectMQTTtoBTset "/commands/MQTTtoBT/config"
#define subjectMQTTtoBT "/commands/MQTTtoBT"
#define subjectTrackerSync "internal/trackersync"
// Uncomment to send undecoded device data to another gateway device for decoding
// #define MQTTDecodeTopic "undecoded"
#ifndef UseExtDecoder
Expand Down Expand Up @@ -143,6 +144,10 @@ unsigned long scanCount = 0;
# define useBeaconUuidForTopic false // define true to use iBeacon UUID as topic, instead of sender (random) MAC address
#endif

#ifndef enableMultiGTWSync
# define enableMultiGTWSync true // //define true to use tracker and closest control devices sync across OpenMQTTGateway and Theengs Gateway gateways
#endif

/*--------------HOME ASSISTANT ROOM PRESENCE--------------*/
#define subjectHomePresence "presence/" // will send Home Assistant room presence message to this topic (first part is same for all rooms, second is room name)

Expand Down
4 changes: 4 additions & 0 deletions main/main.ino
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,10 @@ void setupMQTT() {
mqtt->subscribe(subjectMultiGTWIR, receivingDATA, mqtt_max_payload_size);
# endif

# if enableMultiGTWSync
mqtt->subscribe(String(mqtt_topic) + subjectTrackerSync, receivingDATA, mqtt_max_payload_size);
# endif

mqtt->begin();
}
#endif
Expand Down