diff --git a/src/BleSensorGrp.cpp b/src/BleSensorGrp.cpp
index e571c0a..fb1e5e5 100644
--- a/src/BleSensorGrp.cpp
+++ b/src/BleSensorGrp.cpp
@@ -1,4 +1,4 @@
-/***************************************************
+/***************************************************
Copyright (C) 2020 Martin Koerner
This program is free software: you can redistribute it and/or modify
@@ -13,13 +13,15 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-
+
HISTORY: Please refer Github History
-
+
****************************************************/
#include "BleSensorGrp.h"
#include "BleTemperatureMeater.h"
+#include "BleTemperatureMeater2.h"
+#include "BleTemperatureTempSpike.h"
#include "BleTemperatureWlanthermo.h"
#include "BleScaleWlanthermo.h"
#include "BleTemperatureInkbird.h"
@@ -43,6 +45,8 @@
const BLEUuid filterBleUuids[] = {
BLEUuid(SERV_UUID_MEATER),
+ BLEUuid(SERV_UUID_TEMPSPIKE_ADVERTISER),
+ BLEUuid(SERV_UUID_MEATER2),
BLEUuid(SERV_UUID_INKBIRD),
BLEUuid(SERV_UUID_TEMPERATURE_WLANTHERMO)};
@@ -152,8 +156,8 @@ String BleSensorGrp::getDevicesJson()
{
JsonObject sensorObject = sensorsArray.createNestedObject();
sensorObject[BLE_JSON_SENSORS_VALUE] = this->sensors[deviceIndex]->getValue(sensorIndex);
- String unit = this->sensors[deviceIndex]->getUnit();
- if(unit.length() > 0u)
+ String unit = this->sensors[deviceIndex]->getUnit();
+ if (unit.length() > 0u)
{
sensorObject[BLE_JSON_SENSORS_UNIT] = unit;
}
@@ -196,6 +200,18 @@ void BleSensorGrp::scanCb(ble_gap_evt_adv_report_t *report)
BleTemperatureMeater *temp = new BleTemperatureMeater(&report->peer_addr);
gBleSensorGrp.add(temp);
}
+ else if (Bluefruit.Scanner.checkReportForUuid(report, SERV_UUID_TEMPSPIKE_ADVERTISER))
+ {
+ Log.notice("TempSpike %s received" CR, (true == report->type.scan_response) ? "scan response" : "advertising");
+ BleTemperatureTempSpike *temp = new BleTemperatureTempSpike(&report->peer_addr);
+ gBleSensorGrp.add(temp);
+ }
+ else if (Bluefruit.Scanner.checkReportForUuid(report, SERV_UUID_MEATER2))
+ {
+ Log.notice("Meater2 %s received" CR, (true == report->type.scan_response) ? "scan response" : "advertising");
+ BleTemperatureMeater2 *temp = new BleTemperatureMeater2(&report->peer_addr);
+ gBleSensorGrp.add(temp);
+ }
else if (Bluefruit.Scanner.checkReportForUuid(report, SERV_UUID_TEMPERATURE_WLANTHERMO))
{
Log.notice("Wlanthermo %s received" CR, (true == report->type.scan_response) ? "scan response" : "advertising");
@@ -222,7 +238,7 @@ void BleSensorGrp::scanCb(ble_gap_evt_adv_report_t *report)
}
else if (Bluefruit.Scanner.parseReportByType(report, 0xFFu, (uint8_t *)&beacon, sizeof(BeaconType)) == sizeof(BeaconType))
{
- if(BleTemperatureMeatStick::hasMeatStickData(&beacon))
+ if (BleTemperatureMeatStick::hasMeatStickData(&beacon))
{
Log.notice("MeatStick %s received" CR, (true == report->type.scan_response) ? "scan response" : "advertising");
BleTemperatureMeatStick *temp = new BleTemperatureMeatStick(&report->peer_addr, &beacon);
diff --git a/src/BleTemperatureMeater.h b/src/BleTemperatureMeater.h
index 5dbecd4..4bc45c9 100644
--- a/src/BleTemperatureMeater.h
+++ b/src/BleTemperatureMeater.h
@@ -30,8 +30,8 @@ class BLEClientCharacteristicMeater : public BLEClientCharacteristic
public:
BLEClientCharacteristicMeater(BLEUuid bleuuid) : BLEClientCharacteristic(bleuuid){};
bool writeCCCD(uint16_t value) override
- // die Funktion ueberschreibt die urspruengliche Funktion in der BLEClientCharacteristic, dazu muss die urspruengliche Funktion um ein "virtrual" ergaenzt werden
- // zusaetzlich muessen die privaten Variablen auf protected umgestellt werden
+ // diese Funktion ueberschreibt die urspruengliche Funktion in der BLEClientCharacteristic, dazu muss die urspruengliche Funktion um ein "virtual" ergaenzt werden
+ // zusaetzlich muessen die privaten Variablen der BLEClientCharacteristic auf protected umgestellt werden
{
const uint16_t conn_handle = _service->connHandle();
diff --git a/src/BleTemperatureMeater2.cpp b/src/BleTemperatureMeater2.cpp
new file mode 100644
index 0000000..7dd18a0
--- /dev/null
+++ b/src/BleTemperatureMeater2.cpp
@@ -0,0 +1,149 @@
+/***************************************************
+ Copyright (C) 2024 Steffen Ochs
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ HISTORY: Please refer Github History
+
+****************************************************/
+
+#include "BleSensorGrp.h"
+#include "BleTemperatureMeater2.h"
+#include
+
+#define MEATER2_NUM_OF_TEMERATURES 6u
+
+BleTemperatureMeater2::BleTemperatureMeater2(ble_gap_addr_t *peerAddress) : BleSensorBase(peerAddress, MEATER2_NUM_OF_TEMERATURES, false)
+{
+ bleServ = new BLEClientService(BLEUuid(SERV_UUID_MEATER2));
+ bleChar = new BLEClientCharacteristic(BLEUuid(CHAR_UUID_MEATER2));
+ bleChar->setNotifyCallback(BleSensorGrp::notifyCb);
+
+ bleServ->begin();
+ bleChar->begin();
+
+ Bluefruit.Central.connect(peerAddress);
+}
+
+void BleTemperatureMeater2::connect(uint16_t bleConnHdl)
+{
+ char buffer[30] = {0};
+
+ this->bleConnHdl = bleConnHdl;
+
+ BLEConnection *bleConnection = Bluefruit.Connection(bleConnHdl);
+
+ if (bleConnection != NULL)
+ {
+ if (bleConnection->getPeerName(buffer, sizeof(buffer)))
+ {
+ name = buffer;
+ }
+ }
+
+ // disconnect if disabled
+ if (false == enabled)
+ {
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("Discovering Meater2 service ... ");
+
+ // Check for service
+ if (!bleServ->discover(bleConnHdl))
+ {
+ Log.notice("failed!" CR);
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("success" CR);
+
+ // Check characteristic
+ Log.notice("Discovering Meater2 characteristic ... ");
+ if (!bleChar->discover())
+ {
+ Log.notice("failed!" CR);
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("success" CR);
+
+ // Enable notification
+ Log.notice("Enabling Meater2 notification ... ");
+ if (!bleChar->enableNotify())
+ {
+ Log.notice("failed!" CR);
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("success" CR);
+
+ this->connected = true;
+}
+
+float BleTemperatureMeater2::readAmbientTemperature(uint8_t *data)
+{
+ uint16_t t = 0;
+ float temp = 0;
+ t = data[11] << 8;
+ t += data[10];
+ temp = t / 32.0;
+ if (temp > 2000)
+ {
+ temp = temp - 2048;
+ }
+ return temp;
+}
+
+void BleTemperatureMeater2::notify(BLEClientCharacteristic *chr, uint8_t *data, uint16_t len)
+{
+ this->lastSeen = 0u;
+ Log.notice("----------- Meater2 data -----------" CR);
+
+ uint8_t probeId = 0;
+ for (uint8_t i = 0u; i <= 8; i = i + 2)
+ {
+ uint16_t t = 0;
+ t = data[i + 1] << 8;
+ t += data[i];
+ currentValue[probeId] = t / 32.0;
+ if (currentValue[probeId] > 2000)
+ {
+ currentValue[probeId] = currentValue[probeId] - 2048;
+ }
+
+ Log.notice("Probe %d has value %F" CR, probeId, currentValue[probeId]);
+ probeId++;
+ }
+
+ currentValue[5] = readAmbientTemperature(data);
+ Log.notice("Ambient has value %F" CR, currentValue[5]);
+
+ Log.verbose("Raw data: ");
+
+ for (uint8_t i = 0u; i < len; i++)
+ Log.verbose("%x ", data[i]);
+
+ Log.verbose(CR);
+}
+
+void BleTemperatureMeater2::disconnect(uint16_t conn_handle, uint8_t reason)
+{
+ this->bleConnHdl = INVALID_BLE_CONN_HANDLE;
+ this->connected = false;
+}
diff --git a/src/BleTemperatureMeater2.h b/src/BleTemperatureMeater2.h
new file mode 100644
index 0000000..4aea6dd
--- /dev/null
+++ b/src/BleTemperatureMeater2.h
@@ -0,0 +1,39 @@
+/***************************************************
+ Copyright (C) 2024 Steffen Ochs
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ HISTORY: Please refer Github History
+
+****************************************************/
+#pragma once
+
+#include "BleSensorBase.h"
+
+const uint8_t SERV_UUID_MEATER2[16] = {0x8b, 0xcf, 0x55, 0x45, 0xe5, 0xe1, 0xDD, 0xa0, 0x54, 0x4e, 0xf1, 0x59, 0x6c, 0x74, 0xe2, 0xc9};
+const uint8_t CHAR_UUID_MEATER2[16] = {0x76, 0x28, 0x1a, 0x99, 0xd1, 0x45, 0x9b, 0x90, 0xbf, 0x4b, 0x5e, 0x04, 0x74, 0xa7, 0xdd, 0x7e};
+
+class BleTemperatureMeater2 : public BleSensorBase
+{
+public:
+ BleTemperatureMeater2(ble_gap_addr_t *peerAddress);
+ void virtual connect(uint16_t bleConnHdl);
+ void notify(BLEClientCharacteristic *chr, uint8_t *data, uint16_t len);
+ void disconnect(uint16_t conn_handle, uint8_t reason);
+
+private:
+ float readAmbientTemperature(uint8_t *data);
+ BLEClientService *bleServ;
+ BLEClientCharacteristic *bleChar;
+};
diff --git a/src/BleTemperatureTempSpike.cpp b/src/BleTemperatureTempSpike.cpp
new file mode 100644
index 0000000..6b87a21
--- /dev/null
+++ b/src/BleTemperatureTempSpike.cpp
@@ -0,0 +1,142 @@
+/***************************************************
+ Copyright (C) 2020 Martin Koerner
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ HISTORY: Please refer Github History
+
+****************************************************/
+
+#include "BleSensorGrp.h"
+#include "BleTemperatureTempSpike.h"
+#include
+
+#define TEMPSPIKE_NUM_OF_TEMPERATURES 2u
+
+BleTemperatureTempSpike::BleTemperatureTempSpike(ble_gap_addr_t *peerAddress) : BleSensorBase(peerAddress, TEMPSPIKE_NUM_OF_TEMPERATURES, false)
+{
+
+ bleServ = new BLEClientService(BLEUuid(SERV_UUID_TEMPSPIKE));
+ bleChar = new BLEClientCharacteristicTempSpike(BLEUuid(CHAR_UUID_TEMPSPIKE));
+ bleChar->setNotifyCallback(BleSensorGrp::notifyCb);
+
+ bleServ->begin();
+ bleChar->begin();
+
+ // Bluefruit.Scanner.stop();
+
+ Bluefruit.Central.connect(peerAddress);
+}
+
+void BleTemperatureTempSpike::connect(uint16_t bleConnHdl)
+{
+
+ char buffer[30] = {0};
+
+ this->bleConnHdl = bleConnHdl;
+
+ BLEConnection *bleConnection = Bluefruit.Connection(bleConnHdl);
+
+ if (bleConnection != NULL)
+ {
+ if (bleConnection->getPeerName(buffer, sizeof(buffer)))
+ {
+ name = buffer;
+ }
+ }
+
+ // disconnect if disabled
+ if (false == enabled)
+ {
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("Discovering TempSpike service ... ");
+
+ // Check for service
+ if (!bleServ->discover(bleConnHdl))
+ {
+ Log.notice("failed!" CR);
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("success" CR);
+
+ // Check characteristic
+ Log.notice("Discovering TempSpike characteristic ... ");
+ if (!bleChar->discover())
+ {
+ Log.notice("failed!" CR);
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("success" CR);
+
+ // Enable notification
+ Log.notice("Enabling TempSpike notification ... ");
+ if (!bleChar->enableNotify())
+ {
+ Log.notice("failed!" CR);
+ Bluefruit.disconnect(bleConnHdl);
+ return;
+ }
+
+ Log.notice("success" CR);
+ this->connected = true;
+}
+
+float BleTemperatureTempSpike::readTipTemperature(uint8_t *data)
+{
+ SplitTwoBytes tip;
+ tip.lowByte = data[2];
+ tip.highByte = data[3];
+ return (float(tip.value) - 30);
+}
+
+float BleTemperatureTempSpike::readAmbientTemperature(uint8_t *data)
+{
+
+ SplitTwoBytes ambient;
+ ambient.lowByte = data[6];
+ ambient.highByte = data[7];
+
+ return (float(ambient.value) - 30);
+}
+
+void BleTemperatureTempSpike::notify(BLEClientCharacteristic *chr, uint8_t *data, uint16_t len)
+{
+ currentValue[0] = readTipTemperature(data);
+ currentValue[1] = readAmbientTemperature(data);
+ this->lastSeen = 0u;
+
+ Log.notice("----------- TempSpike data -----------" CR);
+ Log.notice("Tip temperature: %F" CR, currentValue[0]);
+ Log.notice("Ambient temperature: %F" CR, currentValue[1]);
+
+ Log.verbose("Raw data: ");
+
+ for (uint8_t i = 0u; i < len; i++)
+ Log.verbose("%x ", data[i]);
+
+ Log.verbose(CR);
+}
+
+void BleTemperatureTempSpike::disconnect(uint16_t conn_handle, uint8_t reason)
+{
+ this->bleConnHdl = INVALID_BLE_CONN_HANDLE;
+ this->connected = false;
+}
diff --git a/src/BleTemperatureTempSpike.h b/src/BleTemperatureTempSpike.h
new file mode 100644
index 0000000..d1acf0c
--- /dev/null
+++ b/src/BleTemperatureTempSpike.h
@@ -0,0 +1,72 @@
+/***************************************************
+ Copyright (C) 2020 Martin Koerner
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ HISTORY: Please refer Github History
+
+****************************************************/
+#pragma once
+
+#include "BleSensorBase.h"
+
+const uint8_t SERV_UUID_TEMPSPIKE[16] = {0x0F, 0x33, 0xF9, 0x4D, 0x4F, 0xA2, 0x54, 0x23, 0xA9, 0xC5, 0x14, 0xEB, 0xAB, 0x7C, 0xBB, 0x93};
+const uint8_t SERV_UUID_TEMPSPIKE_ADVERTISER[16] = {0xbd, 0x42, 0xd9, 0xfd, 0xe6, 0x2e, 0x55, 0xdb, 0xba, 0xd1, 0x6b, 0x6f, 0x31, 0xb6, 0xfb, 0x72};
+const uint8_t CHAR_UUID_TEMPSPIKE[16] = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00};
+
+// Fix for TempSpike
+class BLEClientCharacteristicTempSpike : public BLEClientCharacteristic
+{
+public:
+ BLEClientCharacteristicTempSpike(BLEUuid bleuuid) : BLEClientCharacteristic(bleuuid){};
+ bool writeCCCD(uint16_t value) override
+ // diese Funktion ueberschreibt die urspruengliche Funktion in der BLEClientCharacteristic, dazu muss die urspruengliche Funktion um ein "virtual" ergaenzt werden
+ // zusaetzlich muessen die privaten Variablen der BLEClientCharacteristic auf protected umgestellt werden
+ {
+ const uint16_t conn_handle = _service->connHandle();
+
+ ble_gattc_write_params_t param =
+ {
+ .write_op = BLE_GATT_OP_WRITE_REQ,
+ .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
+ .handle = _cccd_handle,
+ .offset = 0,
+ .len = 2,
+ .p_value = (uint8_t *)&value};
+
+ // TODO only Write without response consume a TX buffer
+ BLEConnection *conn = Bluefruit.Connection(conn_handle);
+ VERIFY(conn && conn->getWriteCmdPacket());
+
+ VERIFY_STATUS(sd_ble_gattc_write(conn_handle, ¶m), false);
+
+ return true;
+ };
+};
+
+
+class BleTemperatureTempSpike : public BleSensorBase
+{
+public:
+ BleTemperatureTempSpike(ble_gap_addr_t *peerAddress);
+ void virtual connect(uint16_t bleConnHdl);
+ void notify(BLEClientCharacteristic *chr, uint8_t *data, uint16_t len);
+ void disconnect(uint16_t conn_handle, uint8_t reason);
+
+private:
+ float readTipTemperature(uint8_t *data);
+ float readAmbientTemperature(uint8_t *data);
+ BLEClientService *bleServ;
+ BLEClientCharacteristicTempSpike *bleChar;
+};