From c2107da1c72aaa4d8e5690ee01e73085e598c7fb Mon Sep 17 00:00:00 2001 From: Florian <1technophile@users.noreply.github.com> Date: Tue, 27 Jul 2021 06:34:45 -0500 Subject: [PATCH] Add BLE TPMS sensors (#1031) * Add BLE TPMS sensors tire pressure monitoring system --- docs/README.md | 1 + docs/prerequisites/devices.md | 1 + main/ZgatewayBT.ino | 47 +++++++++++++++++++++++++++++++++++ main/config_BT.h | 7 +++--- main/config_mqttDiscovery.h | 2 ++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 9953d3e..6b3a6ab 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,6 +22,7 @@ With OpenMQTTGateway and a controller you can for example: * Actionate a siren if something is going wrong * Detect if your far mailbox has been opened by the postman with LORA * Make smart your old TV or AC system through infrared control +* Monitor vehicle tire pressure The limit is your imagination 😀 diff --git a/docs/prerequisites/devices.md b/docs/prerequisites/devices.md index d8ff0aa..5590821 100644 --- a/docs/prerequisites/devices.md +++ b/docs/prerequisites/devices.md @@ -49,6 +49,7 @@ Added to that it retrieves the measures from the devices below. By default the d | Ibeacon|protocol|UUID/MFID/Major/Minor/Power| | Mokosmart (1)|M1|x_axis/y_axis/z_axis/battery| | Mokosmart (1)|H4|temperature/humidity/volt| +| TPMS|TPMS|temperature/pressure/battery/alarm/count| Exhaustive list [here](https://compatible.openmqttgateway.com/index.php/devices/ble-devices/) diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 9b6cfe5..b00c66d 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -577,6 +577,21 @@ void EddystoneTLMDiscovery(const char* mac, const char* sensorModel) { createDiscoveryFromList(mac, EddystoneTLMsensor, EddystoneTLMparametersCount, "EddystoneTLM", "SensorBlue", sensorModel); } +void TPMSDiscovery(const char* mac, const char* sensorModel) { +# define TPMSparametersCount 5 + Log.trace(F("TPMSDiscovery" CR)); + const char* TPMSsensor[TPMSparametersCount][8] = { + {"sensor", "TPMS-batt", mac, "battery", jsonBatt, "", "", "%"}, + {"sensor", "TPMS-temp", mac, "temperature", jsonTempc, "", "", "°C"}, + {"sensor", "TPMS-pres", mac, "pressure", jsonPres, "", "", "kPa"}, + {"sensor", "TPMS-count", mac, "", jsonCount, "", "", ""}, + {"sensor", "TPMS-alarm", mac, "", jsonAlarm, "", "", ""} + //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement + }; + + createDiscoveryFromList(mac, TPMSsensor, TPMSparametersCount, "TPMS", "TPMS", sensorModel); +} + # else void MiFloraDiscovery(const char* mac, const char* sensorModel) {} void VegTrugDiscovery(const char* mac, const char* sensorModel) {} @@ -601,6 +616,7 @@ void INodeEMDiscovery(const char* mac, const char* sensorModel) {} void WS02Discovery(const char* mac, const char* sensorModel) {} void DT24Discovery(const char* mac, const char* sensorModel) {} void EddystoneTLMDiscovery(const char* mac, const char* sensorModel) {} +void TPMSDiscovery(const char* mac, const char* sensorModel) {} # endif # ifdef ESP32 @@ -1084,6 +1100,7 @@ void launchBTDiscovery() { if (p->sensorModel == MHO_C401) MHO_C401Discovery(macWOdots.c_str(), "MHO_C401"); if (p->sensorModel == INODE_EM) INodeEMDiscovery(macWOdots.c_str(), "INODE_EM"); if (p->sensorModel == DT24) DT24Discovery(macWOdots.c_str(), "DT24-BLE"); + if (p->sensorModel == TPMS) TPMSDiscovery(macWOdots.c_str(), "TPMS"); p->isDisc = true; // we don't need the semaphore and all the search magic via createOrUpdateDevice } else { if (!isDiscovered(p)) { @@ -1347,6 +1364,14 @@ JsonObject& process_bledata(JsonObject& BLEdata) { createOrUpdateDevice(mac, device_flags_connect, DT24); return BLEdata; } + Log.trace(F("Is it a TPMS? %u" CR), strlen(manufacturerdata)); + if (strlen(manufacturerdata) == 36 && strstr(name, "TPMS") != NULL) { + Log.trace(F("TPMS data reading" CR)); + BLEdata.set("model", "TPMS"); + if (device->sensorModel == -1) + createOrUpdateDevice(mac, device_flags_init, TPMS); + return process_tpms(BLEdata); + } } Log.trace(F("Is it a iNode Energy Meter?" CR)); if (strlen(manufacturerdata) == 26 && ((long)value_from_hex_data(manufacturerdata, 0, 4, true) & 0xFFF9) == 0x8290) { @@ -1762,6 +1787,28 @@ JsonObject& process_ibeacon(JsonObject& BLEdata) { BLEdata.set("Power:", (int8_t)value_from_hex_data(manufacturerdata, 48, 4, false)); } +JsonObject& process_tpms(JsonObject& BLEdata) { + const char* manufacturerdata = BLEdata["manufacturerdata"].as(); + + int id = (int)value_from_hex_data(manufacturerdata, 5, 1, false); + double pressure = (double)value_from_hex_data(manufacturerdata, 16, 8, true) / 1000; + double temperature = (double)value_from_hex_data(manufacturerdata, 24, 8, true) / 100; + int battery = (int)value_from_hex_data(manufacturerdata, 32, 2, true); + int alarm = (int)value_from_hex_data(manufacturerdata, 35, 1, false); + + BLEdata.set("count", (int)id); + BLEdata.set("pres", (double)pressure); + BLEdata.set("tempc", (double)temperature); + BLEdata.set("tempf", (double)convertTemp_CtoF(temperature)); + BLEdata.set("batt", (int)battery); + if (alarm == 1) + BLEdata.set("alarm", true); + if (alarm == 0) + BLEdata.set("alarm", false); + + return BLEdata; +} + void hass_presence(JsonObject& HomePresence) { int BLErssi = HomePresence["rssi"]; Log.trace(F("BLErssi %d" CR), BLErssi); diff --git a/main/config_BT.h b/main/config_BT.h index 8d0dd6d..6ecf2c4 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -140,21 +140,22 @@ enum ble_sensor_model { XMTZC05HM, IBSTH1, LYWSD03MMC, - MHO_C401, + MHO_C401, //15 LYWSD03MMC_ATC, INODE_EM, CGDK2, LYWSD03MMC_PVVX, - CGH1, + CGH1, //20 CGPR1, WS02, IBSTH2, IBT4XS, - DT24, + DT24, //25 EDDYSTONE_TLM, MOKOBEACON, MOKOBEACONXPRO, IBEACON, + TPMS, GENERIC, }; diff --git a/main/config_mqttDiscovery.h b/main/config_mqttDiscovery.h index e81d250..fb660e0 100644 --- a/main/config_mqttDiscovery.h +++ b/main/config_mqttDiscovery.h @@ -81,6 +81,7 @@ extern void createDiscovery(const char* sensor_type, # define jsonOpen "{{ value_json.open }}" # define jsonTime "{{ value_json.time }}" # define jsonCount "{{ value_json.count }}" +# define jsonAlarm "{{ value_json.alarm }}" #else // Home assistant autodiscovery value key definition # define jsonBatt "{{ value_json.batt | is_defined }}" # define jsonLux "{{ value_json.lux | is_defined }}" @@ -115,6 +116,7 @@ extern void createDiscovery(const char* sensor_type, # define jsonOpen "{{ value_json.open | is_defined }}" # define jsonTime "{{ value_json.time | is_defined }}" # define jsonCount "{{ value_json.count | is_defined }}" +# define jsonAlarm "{{ value_json.alarm | is_defined }}" #endif #endif