Files
bobbycar-boardcomputer-firm…/main/ble_bobby.cpp
T

310 lines
9.7 KiB
C++
Raw Normal View History

2021-11-02 11:39:36 +01:00
#include "ble_bobby.h"
// esp-idf includes
#include <esp_log.h>
2021-12-29 00:40:05 +01:00
// 3rdparty lib includes
#include <ArduinoJson.h>
#include <wifi_bobbycar.h>
#include <futurecpp.h>
// local includes
#ifdef FEATURE_LEDSTRIP
#include "ledstrip.h"
#endif
#include "globals.h"
#include "modes/remotecontrolmode.h"
#include "utils.h"
#include "newsettings.h"
2021-11-02 11:39:36 +01:00
#ifdef FEATURE_BLE
2021-12-29 00:40:05 +01:00
namespace {
constexpr const char * const TAG = "BOBBYBLE";
class RemoteControlCallbacks : public NimBLECharacteristicCallbacks
{
public:
void onWrite(NimBLECharacteristic* pCharacteristic) override;
};
#ifdef FEATURE_WIRELESS_CONFIG
class WirelessSettingsCallbacks : public NimBLECharacteristicCallbacks
{
public:
void onWrite(NimBLECharacteristic* pCharacteristic) override;
};
class WiFiListCallbacks : public NimBLECharacteristicCallbacks
{
public:
void onRead(NimBLECharacteristic* pCharacteristic) override;
};
#endif // FEATURE_WIRELESS_CONFIG
} // namespace
2021-11-02 11:39:36 +01:00
BLEServer *pServer{};
BLEService *pService{};
BLECharacteristic *livestatsCharacteristic{};
BLECharacteristic *remotecontrolCharacteristic{};
#ifdef FEATURE_WIRELESS_CONFIG
BLECharacteristic *wirelessConfig{};
BLECharacteristic *getwifilist{};
2021-12-29 00:40:05 +01:00
#endif // FEATURE_WIRELESS_CONFIG
2021-11-02 11:39:36 +01:00
2021-12-29 00:40:05 +01:00
namespace {
2021-11-02 11:39:36 +01:00
RemoteControlCallbacks bleRemoteCallbacks;
#ifdef FEATURE_WIRELESS_CONFIG
WirelessSettingsCallbacks bleWirelessSettingsCallbacks;
WiFiListCallbacks bleWiFiListCallbacks;
2021-12-29 00:40:05 +01:00
#endif // FEATURE_WIRELESS_CONFIG
2021-11-02 11:39:36 +01:00
void createBle()
{
ESP_LOGI("BOBBY", "called");
2021-12-29 00:40:05 +01:00
BLEDevice::init(configs.bluetoothName.value);
2021-11-02 11:39:36 +01:00
const auto serviceUuid{"0335e46c-f355-4ce6-8076-017de08cee98"};
pServer = BLEDevice::createServer();
pService = pServer->createService(serviceUuid);
livestatsCharacteristic = pService->createCharacteristic("a48321ea-329f-4eab-a401-30e247211524", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
remotecontrolCharacteristic = pService->createCharacteristic("4201def0-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::WRITE);
remotecontrolCharacteristic->setCallbacks(&bleRemoteCallbacks);
#ifdef FEATURE_WIRELESS_CONFIG
wirelessConfig = pService->createCharacteristic("4201def1-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::WRITE);
wirelessConfig->setCallbacks(&bleWirelessSettingsCallbacks);
getwifilist = pService->createCharacteristic("4201def2-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::READ);
getwifilist->setCallbacks(&bleWiFiListCallbacks);
#endif
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(serviceUuid);
pAdvertising->setScanResponse(true);
BLEDevice::startAdvertising();
}
void destroyBle()
{
ESP_LOGI("BOBBY", "called");
BLEDevice::deinit(true);
pServer = {};
pService = {};
livestatsCharacteristic = {};
remotecontrolCharacteristic = {};
#ifdef FEATURE_WIRELESS_CONFIG
wirelessConfig = {};
getwifilist = {};
#endif
}
2021-11-07 13:04:19 +01:00
} // namespace
2021-11-02 11:39:36 +01:00
void initBle()
{
if (configs.bleSettings.bleEnabled.value)
2021-11-02 11:39:36 +01:00
createBle();
}
void handleBle()
{
if (configs.bleSettings.bleEnabled.value)
2021-11-02 11:39:36 +01:00
{
if (!pServer)
createBle();
if (livestatsCharacteristic->getSubscribedCount())
{
StaticJsonDocument<1024> doc;
{
auto arr = doc.createNestedArray("v");
if (controllers.front.feedbackValid)
arr.add(controllers.front.getCalibratedVoltage());
else
arr.add(nullptr);
if (controllers.back.feedbackValid)
arr.add(controllers.back.getCalibratedVoltage());
else
arr.add(nullptr);
}
{
auto arr = doc.createNestedArray("t");
if (controllers.front.feedbackValid)
arr.add(fixBoardTemp(controllers.front.feedback.boardTemp));
else
arr.add(nullptr);
if (controllers.back.feedbackValid)
arr.add(fixBoardTemp(controllers.back.feedback.boardTemp));
else
arr.add(nullptr);
}
{
auto arr = doc.createNestedArray("e");
if (controllers.front.feedbackValid)
{
arr.add(controllers.front.feedback.left.error);
arr.add(controllers.front.feedback.right.error);
}
else
{
arr.add(nullptr);
arr.add(nullptr);
}
if (controllers.back.feedbackValid)
{
arr.add(controllers.back.feedback.left.error);
arr.add(controllers.back.feedback.right.error);
}
else
{
arr.add(nullptr);
arr.add(nullptr);
}
}
{
auto arr = doc.createNestedArray("s");
if (controllers.front.feedbackValid)
{
2022-01-03 17:13:45 +01:00
arr.add(convertToKmh(controllers.front.feedback.left.speed * (profileSettings.controllerHardware.invertFrontLeft ? -1 : 1)));
arr.add(convertToKmh(controllers.front.feedback.right.speed * (profileSettings.controllerHardware.invertFrontRight ? -1 : 1)));
2021-11-02 11:39:36 +01:00
}
else
{
arr.add(nullptr);
arr.add(nullptr);
}
if (controllers.back.feedbackValid)
{
2022-01-03 17:13:45 +01:00
arr.add(convertToKmh(controllers.back.feedback.left.speed * (profileSettings.controllerHardware.invertBackLeft ? -1 : 1)));
arr.add(convertToKmh(controllers.back.feedback.right.speed * (profileSettings.controllerHardware.invertBackRight ? -1 : 1)));
2021-11-02 11:39:36 +01:00
}
else
{
arr.add(nullptr);
arr.add(nullptr);
}
}
{
auto arr = doc.createNestedArray("a");
if (controllers.front.feedbackValid)
{
arr.add(fixCurrent(controllers.front.feedback.left.dcLink) * 2);
arr.add(fixCurrent(controllers.front.feedback.right.dcLink) * 2);
}
else
{
arr.add(nullptr);
arr.add(nullptr);
}
if (controllers.back.feedbackValid)
{
arr.add(fixCurrent(controllers.back.feedback.left.dcLink) * 2);
arr.add(fixCurrent(controllers.back.feedback.right.dcLink) * 2);
}
else
{
arr.add(nullptr);
arr.add(nullptr);
}
}
std::string json;
serializeJson(doc, json);
livestatsCharacteristic->setValue(json);
livestatsCharacteristic->notify();
}
}
else if (pServer)
{
destroyBle();
}
}
2021-12-29 00:40:05 +01:00
namespace {
2021-11-02 11:39:36 +01:00
void RemoteControlCallbacks::onWrite(NimBLECharacteristic* pCharacteristic)
{
const auto &val = pCharacteristic->getValue();
StaticJsonDocument<256> doc;
if (const auto error = deserializeJson(doc, val))
{
ESP_LOGW(TAG, "ignoring cmd with invalid json: %.*s %s", val.size(), val.data(), error.c_str());
return;
}
#ifdef FEATURE_LEDSTRIP
auto newBlinkAnimation = doc["anim"].as<int16_t>();
if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation;
2021-12-29 00:40:05 +01:00
#endif // FEATURE_LEDSTRIP
2021-11-02 11:39:36 +01:00
2022-01-03 17:13:45 +01:00
const bool isInverted = (profileSettings.controllerHardware.invertFrontLeft && !profileSettings.controllerHardware.invertFrontRight);
2021-11-20 12:47:02 +01:00
2021-11-02 11:39:36 +01:00
if (!simplified)
{
modes::remoteControlMode.setCommand(RemoteCommand{
2021-11-20 12:47:02 +01:00
.frontLeft = doc[isInverted ? "fr":"fl"].as<int16_t>(),
.frontRight = doc[isInverted ? "fl":"fr"].as<int16_t>(),
2021-11-02 11:39:36 +01:00
.backLeft = doc["bl"].as<int16_t>(),
.backRight = doc["br"].as<int16_t>()
});
}
}
#ifdef FEATURE_WIRELESS_CONFIG
void WirelessSettingsCallbacks::onWrite(NimBLECharacteristic* pCharacteristic)
{
const auto &val = pCharacteristic->getValue();
StaticJsonDocument<256> doc;
if (const auto error = deserializeJson(doc, val))
{
ESP_LOGW(TAG, "ignoring cmd with invalid json: %.*s %s", val.size(), val.data(), error.c_str());
return;
}
auto write_type = doc["type"].as<std::string>();
if (write_type == "wifi") {
const int index = doc["wifi_index"].as<int>();
ESP_LOGI(TAG, "[ble_config]: Set wifi%i: WiFi-SSID: %s, WiFi-Password: ***", doc["wifi_index"].as<int>(), doc["wifi_ssid"].as<const char*>());
2021-12-29 00:40:05 +01:00
configs.write_config(configs.wifi_configs[index].ssid, doc["wifi_ssid"].as<std::string>());
configs.write_config(configs.wifi_configs[index].key, doc["wifi_pass"].as<std::string>());
2021-11-02 11:39:36 +01:00
} else {
const auto deserialized = deserializeJson(doc, val);
ESP_LOGW(TAG, "Unkown type %s -> json: %.*s %s", doc["type"].as<const char*>(), val.size(), val.data(), deserialized.c_str());
}
}
2021-12-29 00:40:05 +01:00
void WiFiListCallbacks::onRead(NimBLECharacteristic *pCharacteristic)
{
2021-11-02 11:39:36 +01:00
StaticJsonDocument<768> responseDoc;
auto wifiArray = responseDoc.createNestedArray("wifis");
ESP_LOGI(TAG, "[ble_wifilist] Got request for listing wifi ssids.");
2021-12-29 00:40:05 +01:00
for (const auto &wifi : configs.wifi_configs)
{
wifiArray.add(wifi.ssid.value);
2021-11-02 11:39:36 +01:00
}
2021-12-29 00:40:05 +01:00
responseDoc["wifi_count"] = configs.wifi_configs.size();
2021-11-02 11:39:36 +01:00
std::string json;
serializeJson(responseDoc, json);
pCharacteristic->setValue(json);
}
2021-12-29 00:40:05 +01:00
#endif // FEATURE_WIRELESS_CONFIG
} // namespace
2021-11-02 11:39:36 +01:00
#endif