Current WIP state, protocol sadly not working

This commit is contained in:
CommanderRedYT
2022-12-26 16:52:25 +01:00
parent 158a5d2d72
commit 04a0cabaed
7 changed files with 582 additions and 442 deletions

View File

@ -1,6 +1,7 @@
set(BOBBY_HEADERS
accessorhelpers.h
antbms.h
antbmsmanager.h
accessors/globalaccessors.h
accessors/settingsaccessors.h
accessors/wifiaccessors.h
@ -259,6 +260,7 @@ set(BOBBY_HEADERS
set(BOBBY_SOURCES
antbms.cpp
antbmsmanager.cpp
accessors/wifistaconfigaccessors.cpp
actions/assertaction.cpp
actions/bmsclearscanaction.cpp

View File

@ -1,350 +1,108 @@
#include "antbms.h"
// local includes
#include "bmsutils.h"
#include "newsettings.h"
// esp-idf includes
#include <esp_log.h>
using namespace std::chrono_literals;
BmsInstruction::BmsInstruction(uint8_t b, uint8_t b2) :
functionCode{b},
length{b2}
{}
void ANTBms::init()
void BmsInstruction::setData(uint8_t *_data, uint8_t _length)
{
// init code
m_initialized = true;
// scan
startScan();
std::copy(_data, _data + _length, this->data);
}
void ANTBms::update()
int BmsInstruction::getAddress() const
{
if (!m_initialized)
return;
return address;
}
handleConnect();
void BmsInstruction::setAddress(int _address)
{
address = _address;
}
if (m_client && (*m_client)->isConnected())
uint8_t *BmsInstruction::getInstruction()
{
if (length == 0)
{
requestData();
return BmsBluetoothInst::buildReadBmsInst(functionCode, address, 0);
}
return BmsBluetoothInst::buildReadBmsInstWithData(this->functionCode, this->address, this->length, this->data);
}
void ANTBms::deinit()
std::string BmsInstruction::toString() const
{
// deinit code
m_initialized = false;
return "BmsInstruction{functionCode=" + std::to_string(functionCode) + ", address=" + std::to_string(address) + ", inst = " + ", data = " + "}";
}
if (m_client)
int CRC16::calcCrc16(const uint8_t *data, uint16_t len)
{
// calculate crc16
uint16_t crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
(*m_client)->disconnect();
m_client.reset();
}
crc ^= (uint16_t) data[pos]; // XOR byte into least sig. byte of crc
if (m_scanResults)
{
m_scanResults.reset();
}
if (m_service)
{
m_service.reset();
}
if (m_rxCharacteristic)
{
m_rxCharacteristic.reset();
}
if (m_txCharacteristic)
{
m_txCharacteristic.reset();
}
m_scanStarted = false;
m_initialized = false;
}
bool ANTBms::isInitialized() const
{
return m_initialized;
}
void ANTBms::startScan()
{
if (!m_initialized)
return;
ESP_LOGI(TAG, "starting scan");
NimBLEScan* pScan = NimBLEDevice::getScan();
pScan->setActiveScan(true);
pScan->setInterval(100);
pScan->setWindow(99);
pScan->setScanCallbacks(new ScanResultsCallback(this), false);
pScan->start(5000);
ESP_LOGI(TAG, "scan started");
m_scanStarted = true;
}
void ANTBms::clearScanResults()
{
m_scanResults.reset();
}
bool ANTBms::getScanStatus() const
{
return m_scanStarted;
}
const std::optional<scanResults_t> &ANTBms::getScanResults()
{
return m_scanResults;
}
void ANTBms::handleConnect()
{
if (!m_initialized)
return;
ESP_LOGD(TAG, "!m_initialized passed");
if (m_connected)
return;
ESP_LOGD(TAG, "m_connected passed");
if (!m_scanResults)
return;
ESP_LOGD(TAG, "!m_scanResults passed");
if (m_scanResults && m_scanResults->entries.empty())
return;
ESP_LOGD(TAG, "m_scanResults->entries.empty() passed");
if (m_client && (*m_client)->isConnected())
return;
ESP_LOGD(TAG, "!m_client.has_value() passed");
if (configs.bmsAddress.value().empty())
return;
ESP_LOGD(TAG, "configs.bmsAddress.value().empty() passed");
ESP_LOGI(TAG, "connecting to bms");
if (NimBLEDevice::getClientListSize())
{
m_client = NimBLEDevice::getClientByPeerAddress(configs.bmsAddress.value());
if (m_client)
{
if (!(*m_client)->connect(configs.bmsAddress.value()))
{
ESP_LOGE(TAG, "Reconnect failed");
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
for (int i = 8; i != 0; i--)
{ // Loop over each bit
if ((crc & 0x0001) != 0)
{ // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
ESP_LOGI(TAG, "Reconnected to client");
}
else
{
m_client = NimBLEDevice::getDisconnectedClient();
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
if (!m_client)
{
if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS)
{
ESP_LOGE(TAG, "Max clients reached - no more connections available!");
return;
}
m_client = NimBLEDevice::createClient();
const auto pClient = *m_client;
pClient->setClientCallbacks(new ClientCallbacks(this), false);
pClient->setConnectTimeout(10);
pClient->setConnectionParams(12, 12, 0, 51);
if (!pClient->connect(configs.bmsAddress.value()))
{
NimBLEDevice::deleteClient(pClient);
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
}
if (!(*m_client)->isConnected())
{
if (!(*m_client)->connect(configs.bmsAddress.value()))
{
ESP_LOGE(TAG, "Failed to connect");
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
}
ESP_LOGI(TAG, "Connected!");
m_connected = true;
m_service = (*m_client)->getService(serviceUUID);
if (!m_service)
{
ESP_LOGE(TAG, "Failed to find our service UUID: %s", serviceUUID.toString().c_str());
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
if (m_service && (*m_service))
{
ESP_LOGI(TAG, "Getting characteristic");
m_rxCharacteristic = (*m_service)->getCharacteristic(charRXUUID);
m_txCharacteristic = (*m_service)->getCharacteristic(charTXUUID);
if ((m_rxCharacteristic && (*m_rxCharacteristic)) && (m_txCharacteristic && (*m_txCharacteristic)))
{
const auto pChr = *m_rxCharacteristic;
if (pChr->canNotify())
{
ESP_LOGI(TAG, "Subscribing to notifications");
if (!pChr->subscribe(true, bmsutils::_notifyCB))
{
(*m_client)->disconnect();
ESP_LOGE(TAG, "Failed to subscribe for notifications");
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_connected = false;
return;
}
ESP_LOGI(TAG, "Subscribed for notifications");
m_connected = true;
// 7ea1010000be1855aa55
uint8_t data[10] = {0x7e, 0xa1, 0x01, 0x00, 0x00, 0xbe, 0x18, 0x55, 0xaa, 0x55};
sendCommand(data, sizeof(data));
return;
}
else
{
ESP_LOGE(TAG, "Characteristic can't notify, disconnecting");
(*m_client)->disconnect();
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_connected = false;
return;
}
}
else
{
ESP_LOGE(TAG, "Failed to find our characteristic UUID: %s", charRXUUID.toString().c_str());
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_connected = false;
return;
}
}
return crc;
}
void ANTBms::notifyCB(NimBLERemoteCharacteristic *pRemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify)
uint8_t *BmsBluetoothInst::buildReadBmsInst(uint8_t b, int i, uint8_t b2)
{
ESP_LOGI(TAG, "Received %s: %s (%.*s)", isNotify ? "notification" : "indication", bmsutils::bytesToHex(pData, length).c_str(), length, pData);
auto *bArr = new uint8_t[64];
bArr[0] = PROTOCOL_FRAME_HEAD;
bArr[1] = PROTOCOL_ADD;
bArr[2] = b;
bArr[3] = (uint8_t) (i & 255);
bArr[4] = (uint8_t) ((i >> 8) & 255);
bArr[5] = b2;
int crc16 = CRC16::calcCrc16(bArr + 1, 5);
ESP_LOGI(TAG, "crc: %d", crc16);
bArr[6] = (uint8_t) (crc16 >> 8);
bArr[7] = (uint8_t) (crc16 & 255);
bArr[8] = -86;
bArr[9] = 85;
return bArr;
}
void ANTBms::requestData()
uint8_t *BmsBluetoothInst::buildReadBmsInstWithData(uint8_t b, int i, uint8_t b2, uint8_t *bArr)
{
if (!m_initialized)
return;
if (!m_connected)
return;
if (espchrono::ago(m_lastRequestTime) > 2000ms || m_newPacketReceived)
auto *bArr2 = new uint8_t[64 + sizeof(bArr)];
bArr2[0] = PROTOCOL_FRAME_HEAD;
bArr2[1] = PROTOCOL_ADD;
bArr2[2] = b;
bArr2[3] = (uint8_t) (i & 255);
bArr2[4] = (uint8_t) ((i >> 8) & 255);
bArr2[5] = b2;
int i2 = 5;
for (int _i = 0; _i < sizeof(bArr); _i++)
{
m_lastRequestTime = espchrono::millis_clock::now();
if (m_toggle)
{
bmsGetInfo3();
m_newPacketReceived = false;
}
else
{
bmsGetInfo4();
m_newPacketReceived = false;
}
m_toggle = !m_toggle;
i2++;
bArr2[i2] = bArr[_i];
}
}
void ANTBms::sendCommand(uint8_t *pData, size_t length)
{
if (!m_initialized)
return;
if (!m_connected)
return;
if (!m_txCharacteristic)
return;
if (!(*m_txCharacteristic))
return;
if (!(*m_txCharacteristic)->canWrite())
return;
ESP_LOGI(TAG, "Sending command: %s", bmsutils::bytesToHex(pData, length).c_str());
(*m_txCharacteristic)->writeValue(pData, length, true);
}
void ANTBms::bmsGetInfo3()
{
// DD A5 03 00 FF FD 77
uint8_t data[7] = {0xdd, 0xa5, 0x3, 0x0, 0xff, 0xfd, 0x77};
sendCommand(data, sizeof(data));
}
void ANTBms::bmsGetInfo4()
{
// DD A5 04 00 FF FC 77
uint8_t data[7] = {0xdd, 0xa5, 0x4, 0x0, 0xff, 0xfc, 0x77};
sendCommand(data, sizeof(data));
int i3 = i2 + 1;
int crc16 = CRC16::calcCrc16(bArr2 + 1, (uint16_t) (sizeof(bArr) + 5));
ESP_LOGI(TAG, "crc: %d", crc16);
bArr2[i3] = (uint8_t) (crc16 >> 8);
int i4 = i3 + 1;
bArr2[i4] = (uint8_t) (crc16 & 255);
int i5 = i4 + 1;
bArr2[i5] = -86;
int i6 = i5 + 1;
bArr2[i6] = 85;
return bArr2;
}

View File

@ -1,126 +1,53 @@
#pragma once
// TODO: jetbrains://idea/navigate/reference?project=bms_base_source_from_JADX&path=com/mayi/bms/bluetooth/BmsBluetoothManager.java
// system includes
#include <optional>
#include <cstdint>
#include <string>
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <NimBLEDevice.h>
#include <espchrono.h>
typedef struct {
NimBLEAddress address;
std::string name;
} scanResult_t;
typedef struct {
std::vector<scanResult_t> entries;
} scanResults_t;
const NimBLEUUID serviceUUID{"0000ffe0-0000-1000-8000-00805f9b34fb"};
const NimBLEUUID charRXUUID {"0000ffe1-0000-1000-8000-00805f9b34fb"};
//const NimBLEUUID charTXUUID {"0000ffe1-0000-1000-8000-00805f9b34fb"}; // same as RX
const NimBLEUUID charTXUUID {"0000ffe2-0000-1000-8000-00805f9b34fb"}; // different
class ANTBms
class CRC16
{
public:
static constexpr const char * const TAG = "ANTBMS";
// basic functions
void init();
void update();
void deinit();
[[nodiscard]] bool isInitialized() const;
// scans
void startScan();
[[nodiscard]] bool getScanStatus() const;
const std::optional<scanResults_t> &getScanResults();
void clearScanResults();
void handleConnect();
void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify);
void requestData();
void sendCommand(uint8_t *pData, size_t length);
private:
class ScanResultsCallback : public NimBLEScanCallbacks
{
public:
explicit ScanResultsCallback(ANTBms* antBms) : m_antBms{antBms} {}
void onScanEnd(NimBLEScanResults scanResults) override
{
m_antBms->m_scanResults.reset();
ESP_LOGI(TAG, "BLE Scan complete");
scanResults_t results;
for (auto &result : scanResults)
{
if (result->isAdvertisingService(serviceUUID))
{
scanResult_t scanResult;
scanResult.address = result->getAddress();
scanResult.name = result->getName();
results.entries.push_back(scanResult);
}
}
m_antBms->m_scanResults = results;
m_antBms->m_scanStarted = false;
}
private:
ANTBms* m_antBms;
};
class ClientCallbacks : public NimBLEClientCallbacks
{
public:
explicit ClientCallbacks(ANTBms* antBms) : m_antBms{antBms} {}
void onConnect(NimBLEClient* pClient) override
{
m_antBms->m_connected = true;
ESP_LOGD(TAG, "Connected to server");
}
void onDisconnect(NimBLEClient* pClient, int reason) override
{
m_antBms->m_connected = false;
ESP_LOGI(TAG, "Disconnected from server (%d)", reason);
}
private:
ANTBms* m_antBms;
};
bool m_initialized{false};
bool m_scanStarted{false};
bool m_connected{false};
bool m_newPacketReceived{false};
bool m_toggle{false};
std::optional<NimBLEClient*> m_client;
std::optional<NimBLERemoteService*> m_service;
std::optional<NimBLERemoteCharacteristic*> m_rxCharacteristic;
std::optional<NimBLERemoteCharacteristic*> m_txCharacteristic;
std::optional<scanResults_t> m_scanResults;
espchrono::millis_clock::time_point m_lastRequestTime;
void bmsGetInfo3();
void bmsGetInfo4();
static int calcCrc16(const uint8_t *data, uint16_t len);
};
class BmsBluetoothInst
{
public:
static constexpr const char * const TAG = "BMSBluetoothInst";
static uint8_t *buildReadBmsInst(uint8_t b, int i, uint8_t b2);
static uint8_t *buildReadBmsInstWithData(uint8_t b, int i, uint8_t b2, uint8_t *bArr);
static constexpr uint8_t PROTOCOL_ADD = 0xA1;
static constexpr uint8_t PROTOCOL_FRAME_HEAD = 0x7E;
};
class BmsInstruction
{
private:
const uint8_t functionCode;
const uint8_t length;
int address{0};
uint8_t data[32]{};
public:
static constexpr const char * const TAG = "BMSInstruction";
BmsInstruction(uint8_t b, uint8_t b2);
void setData(uint8_t *data, uint8_t length);
[[nodiscard]] uint8_t getLength() const;
[[nodiscard]] uint8_t getFunctionCode() const;
[[nodiscard]] int getAddress() const;
void setAddress(int address);
uint8_t* getInstruction();
[[nodiscard]] std::string toString() const;
};

330
main/antbmsmanager.cpp Normal file
View File

@ -0,0 +1,330 @@
#include "antbmsmanager.h"
// local includes
#include "antbms.h"
#include "bmsutils.h"
#include "newsettings.h"
using namespace std::chrono_literals;
void ANTBmsManager::init()
{
// init code
m_initialized = true;
// scan
startScan();
}
void ANTBmsManager::update()
{
if (!m_initialized)
return;
handleConnect();
if (m_client && (*m_client)->isConnected())
{
requestData();
}
}
void ANTBmsManager::deinit()
{
// deinit code
m_initialized = false;
if (m_client)
{
(*m_client)->disconnect();
m_client.reset();
}
if (m_scanResults)
{
m_scanResults.reset();
}
if (m_service)
{
m_service.reset();
}
if (m_rxCharacteristic)
{
m_rxCharacteristic.reset();
}
if (m_txCharacteristic)
{
m_txCharacteristic.reset();
}
m_scanStarted = false;
m_initialized = false;
}
bool ANTBmsManager::isInitialized() const
{
return m_initialized;
}
void ANTBmsManager::startScan()
{
if (!m_initialized)
return;
ESP_LOGI(TAG, "starting scan");
NimBLEScan* pScan = NimBLEDevice::getScan();
pScan->setActiveScan(true);
pScan->setInterval(100);
pScan->setWindow(99);
pScan->setScanCallbacks(new ScanResultsCallback(this), false);
pScan->start(5000);
ESP_LOGI(TAG, "scan started");
m_scanStarted = true;
}
void ANTBmsManager::clearScanResults()
{
m_scanResults.reset();
}
bool ANTBmsManager::getScanStatus() const
{
return m_scanStarted;
}
const std::optional<scanResults_t> &ANTBmsManager::getScanResults()
{
return m_scanResults;
}
void ANTBmsManager::handleConnect()
{
if (!m_initialized)
return;
ESP_LOGD(TAG, "!m_initialized passed");
if (m_connected)
return;
ESP_LOGD(TAG, "m_connected passed");
if (!m_scanResults)
return;
ESP_LOGD(TAG, "!m_scanResults passed");
if (m_scanResults && m_scanResults->entries.empty())
return;
ESP_LOGD(TAG, "m_scanResults->entries.empty() passed");
if (m_client && (*m_client)->isConnected())
return;
ESP_LOGD(TAG, "!m_client.has_value() passed");
if (configs.bmsAddress.value().empty())
return;
ESP_LOGD(TAG, "configs.bmsAddress.value().empty() passed");
ESP_LOGI(TAG, "connecting to bms");
if (NimBLEDevice::getClientListSize())
{
m_client = NimBLEDevice::getClientByPeerAddress(configs.bmsAddress.value());
if (m_client)
{
if (!(*m_client)->connect(configs.bmsAddress.value()))
{
ESP_LOGE(TAG, "Reconnect failed");
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
ESP_LOGI(TAG, "Reconnected to client");
}
else
{
m_client = NimBLEDevice::getDisconnectedClient();
}
}
if (!m_client)
{
if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS)
{
ESP_LOGE(TAG, "Max clients reached - no more connections available!");
return;
}
m_client = NimBLEDevice::createClient(); // this sometimes crashes with StoreProhibited
const auto pClient = *m_client;
pClient->setClientCallbacks(new ClientCallbacks(this), false);
pClient->setConnectTimeout(10);
pClient->setConnectionParams(12, 12, 0, 51);
if (!pClient->connect(configs.bmsAddress.value()))
{
NimBLEDevice::deleteClient(pClient);
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
}
if (!(*m_client)->isConnected())
{
if (!(*m_client)->connect(configs.bmsAddress.value()))
{
ESP_LOGE(TAG, "Failed to connect");
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
}
ESP_LOGI(TAG, "Connected!");
m_connected = true;
m_service = (*m_client)->getService(serviceUUID);
if (!m_service)
{
ESP_LOGE(TAG, "Failed to find our service UUID: %s", serviceUUID.toString().c_str());
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_txCharacteristic.reset();
m_connected = false;
return;
}
if (m_service && (*m_service))
{
ESP_LOGI(TAG, "Getting characteristic");
m_rxCharacteristic = (*m_service)->getCharacteristic(charRXUUID);
m_txCharacteristic = (*m_service)->getCharacteristic(charTXUUID);
if ((m_rxCharacteristic && (*m_rxCharacteristic)) && (m_txCharacteristic && (*m_txCharacteristic)))
{
const auto pChr = *m_rxCharacteristic;
if (pChr->canNotify())
{
ESP_LOGI(TAG, "Subscribing to notifications");
if (!pChr->subscribe(true, bmsutils::_notifyCB))
{
(*m_client)->disconnect();
ESP_LOGE(TAG, "Failed to subscribe for notifications");
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_connected = false;
return;
}
ESP_LOGI(TAG, "Subscribed for notifications");
m_connected = true;
return;
}
else
{
ESP_LOGE(TAG, "Characteristic can't notify, disconnecting");
(*m_client)->disconnect();
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_connected = false;
return;
}
}
else
{
ESP_LOGE(TAG, "Failed to find our characteristic UUID: %s", charRXUUID.toString().c_str());
m_client.reset();
m_service.reset();
m_rxCharacteristic.reset();
m_connected = false;
return;
}
}
}
void ANTBmsManager::notifyCB(NimBLERemoteCharacteristic *pRemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify)
{
ESP_LOGI(TAG, "Received %s: %s (%.*s)", isNotify ? "notification" : "indication", bmsutils::bytesToHex(pData, length).c_str(), length, pData);
}
void ANTBmsManager::requestData()
{
if (!m_initialized)
return;
if (!m_connected)
return;
if (espchrono::ago(m_lastRequestTime) > 2000ms || m_newPacketReceived)
{
m_lastRequestTime = espchrono::millis_clock::now();
readBmsState();
}
}
void ANTBmsManager::sendCommand(uint8_t *pData, size_t length)
{
if (!m_initialized)
return;
if (!m_connected)
return;
if (!m_txCharacteristic)
return;
if (!(*m_txCharacteristic))
return;
if (!(*m_txCharacteristic)->canWrite())
return;
ESP_LOGI(TAG, "Sending command: %s", bmsutils::bytesToHex(pData, length).c_str());
(*m_txCharacteristic)->writeValue(pData, length, true);
}
void ANTBmsManager::readBmsState()
{
BmsInstruction bmsInstruction = BmsInstruction(1, -66);
ESP_LOGI(TAG, "read real status, inst: %s", bmsInstruction.toString().c_str());
const auto inst = bmsInstruction.getInstruction();
sendCommand(inst, sizeof(inst));
}

123
main/antbmsmanager.h Normal file
View File

@ -0,0 +1,123 @@
#pragma once
// system includes
#include <optional>
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <NimBLEDevice.h>
#include <espchrono.h>
typedef struct {
NimBLEAddress address;
std::string name;
} scanResult_t;
typedef struct {
std::vector<scanResult_t> entries;
} scanResults_t;
const NimBLEUUID serviceUUID{"0000ffe0-0000-1000-8000-00805f9b34fb"};
const NimBLEUUID charRXUUID {"0000ffe1-0000-1000-8000-00805f9b34fb"};
const NimBLEUUID charTXUUID {"0000ffe1-0000-1000-8000-00805f9b34fb"}; // same as RX
// const NimBLEUUID charTXUUID {"0000ffe2-0000-1000-8000-00805f9b34fb"}; // different
class ANTBmsManager
{
public:
static constexpr const char * const TAG = "ANTBMS-MANAGER";
// basic functions
void init();
void update();
void deinit();
[[nodiscard]] bool isInitialized() const;
// scans
void startScan();
[[nodiscard]] bool getScanStatus() const;
const std::optional<scanResults_t> &getScanResults();
void clearScanResults();
void handleConnect();
void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify);
void requestData();
void sendCommand(uint8_t *pData, size_t length);
void readBmsState();
private:
class ScanResultsCallback : public NimBLEScanCallbacks
{
public:
explicit ScanResultsCallback(ANTBmsManager* antBms) : m_antBms{antBms} {}
void onScanEnd(NimBLEScanResults scanResults) override
{
m_antBms->m_scanResults.reset();
ESP_LOGI(TAG, "BLE Scan complete");
scanResults_t results;
for (auto &result : scanResults)
{
if (result->isAdvertisingService(serviceUUID))
{
scanResult_t scanResult;
scanResult.address = result->getAddress();
scanResult.name = result->getName();
results.entries.push_back(scanResult);
}
}
m_antBms->m_scanResults = results;
m_antBms->m_scanStarted = false;
}
private:
ANTBmsManager* m_antBms;
};
class ClientCallbacks : public NimBLEClientCallbacks
{
public:
explicit ClientCallbacks(ANTBmsManager* antBms) : m_antBms{antBms} {}
void onConnect(NimBLEClient* pClient) override
{
m_antBms->m_connected = true;
ESP_LOGD(TAG, "Connected to server");
}
void onDisconnect(NimBLEClient* pClient, int reason) override
{
m_antBms->m_connected = false;
ESP_LOGI(TAG, "Disconnected from server (%d)", reason);
}
private:
ANTBmsManager* m_antBms;
};
bool m_initialized{false};
bool m_scanStarted{false};
bool m_connected{false};
bool m_newPacketReceived{false};
bool m_toggle{false};
std::optional<NimBLEClient*> m_client;
std::optional<NimBLERemoteService*> m_service;
std::optional<NimBLERemoteCharacteristic*> m_rxCharacteristic;
std::optional<NimBLERemoteCharacteristic*> m_txCharacteristic;
std::optional<scanResults_t> m_scanResults;
espchrono::millis_clock::time_point m_lastRequestTime;
};

View File

@ -11,7 +11,7 @@
namespace bmsutils {
ANTBms antBms;
ANTBmsManager antBms;
void init() {}
@ -24,7 +24,7 @@ void update()
ESP_LOGI("bmsutils", "initializing bms");
antBms.init();
}
else if (!configs.bmsEnabled.value() && initialized)
else if ((!configs.bmsEnabled.value() || !configs.bleSettings.bleEnabled.value()) && initialized)
{
ESP_LOGI("bmsutils", "deinitializing bms");
antBms.deinit();

View File

@ -1,10 +1,10 @@
#pragma once
// local includes
#include "antbms.h"
#include "antbmsmanager.h"
namespace bmsutils {
extern ANTBms antBms;
extern ANTBmsManager antBms;
void init();