Compare commits
1 Commits
eth_hq_esp
...
eth_websoc
Author | SHA1 | Date | |
---|---|---|---|
|
a5c342b26f |
52
Buffer.h
52
Buffer.h
@@ -1,52 +0,0 @@
|
|||||||
#ifndef BUFFER_H
|
|
||||||
#define BUFFER_H
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
class Buffer {
|
|
||||||
private:
|
|
||||||
char* data_;
|
|
||||||
size_t size_;
|
|
||||||
size_t currentLength_;
|
|
||||||
const char separator_;
|
|
||||||
boolean overflow=false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Buffer(size_t size, const char separator = '\0')
|
|
||||||
: size_(size), currentLength_(0), separator_(separator) {
|
|
||||||
data_ = new char[size_];
|
|
||||||
data_[0] = '\0'; // Ensure the buffer is null-terminated
|
|
||||||
}
|
|
||||||
|
|
||||||
~Buffer() {
|
|
||||||
delete[] data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool add(const char* str) {
|
|
||||||
size_t strLength = strlen(str);
|
|
||||||
if (currentLength_ + strLength + 1 + (currentLength_ > 0 && separator_ != '\0') < size_) {
|
|
||||||
if (currentLength_ > 0 && separator_ != '\0') {
|
|
||||||
strcat(data_, &separator_);
|
|
||||||
++currentLength_;
|
|
||||||
}
|
|
||||||
strcat(data_, str);
|
|
||||||
currentLength_ += strLength;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
overflow=true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
data_[0] = '\0';
|
|
||||||
currentLength_ = 0;
|
|
||||||
overflow=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* get() const {
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
154
ESPBMS.ino
154
ESPBMS.ino
@@ -1,20 +1,19 @@
|
|||||||
#include "HQ.h"
|
|
||||||
|
|
||||||
#include "BLEDevice.h"
|
#include "BLEDevice.h"
|
||||||
|
#include <ETH.h>
|
||||||
|
#include "WebSocketManager.h"
|
||||||
|
|
||||||
|
WebSocketManager wsManager("ws://chodbox.home.arpa", 8765, "/");
|
||||||
|
|
||||||
static BLEUUID serviceUUID("0000ff00-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms service
|
static BLEUUID serviceUUID("0000ff00-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms service
|
||||||
static BLEUUID charUUID_rx("0000ff01-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms rx id
|
static BLEUUID charUUID_rx("0000ff01-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms rx id
|
||||||
static BLEUUID charUUID_tx("0000ff02-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms tx id
|
static BLEUUID charUUID_tx("0000ff02-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms tx id
|
||||||
|
|
||||||
#ifndef ETH_PHY_TYPE
|
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN // ETH_CLOCK_GPIO17_OUT
|
||||||
#define ETH_PHY_TYPE ETH_PHY_LAN8720
|
#define ETH_POWER_PIN 16
|
||||||
#define ETH_PHY_ADDR 1
|
#define ETH_TYPE ETH_PHY_LAN8720
|
||||||
#define ETH_PHY_MDC 23
|
#define ETH_ADDR 1
|
||||||
#define ETH_PHY_MDIO 18
|
#define ETH_MDC_PIN 23
|
||||||
#define ETH_PHY_POWER 16
|
#define ETH_MDIO_PIN 18
|
||||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
|
|
||||||
#endif
|
|
||||||
#include <ETH.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -29,50 +28,13 @@ bool gotBasicInfo;
|
|||||||
bool gotCellInfo;
|
bool gotCellInfo;
|
||||||
static bool eth_ready = false;
|
static bool eth_ready = false;
|
||||||
|
|
||||||
void onEvent(arduino_event_id_t event){
|
|
||||||
Serial.print("E:");
|
|
||||||
Serial.println(event);
|
|
||||||
switch (event) {
|
|
||||||
case ARDUINO_EVENT_ETH_START:
|
|
||||||
Serial.println("[ETH] Started");
|
|
||||||
//set eth hostname here
|
|
||||||
ETH.setHostname("esp32-ethernet");
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
|
||||||
Serial.println("[ETH] Connected");
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
|
||||||
Serial.print("[ETH] MAC: ");
|
|
||||||
Serial.print(ETH.macAddress());
|
|
||||||
Serial.print(", IPv4: ");
|
|
||||||
Serial.print(ETH.localIP());
|
|
||||||
if (ETH.fullDuplex()) {
|
|
||||||
Serial.print(", FULL_DUPLEX");
|
|
||||||
}
|
|
||||||
Serial.print(", ");
|
|
||||||
Serial.print(ETH.linkSpeed());
|
|
||||||
Serial.println("Mbps");
|
|
||||||
eth_ready = true;
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
|
||||||
Serial.println("[ETH] Disconnected");
|
|
||||||
eth_ready = false;
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_ETH_STOP:
|
|
||||||
Serial.println("[ETH] Stopped");
|
|
||||||
eth_ready = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Network.onEvent(onEvent);
|
WiFi.onEvent(WiFiEvent);
|
||||||
ETH.begin();
|
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
|
||||||
BLEDevice::init("");
|
BLEDevice::init("");
|
||||||
|
wsManager.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
@@ -82,24 +44,29 @@ void loop() {
|
|||||||
|
|
||||||
BLEScan* pBLEScan = BLEDevice::getScan(); // Create new scan
|
BLEScan* pBLEScan = BLEDevice::getScan(); // Create new scan
|
||||||
pBLEScan->setActiveScan(true); // Active scan uses more power, but get results faster
|
pBLEScan->setActiveScan(true); // Active scan uses more power, but get results faster
|
||||||
BLEScanResults* foundDevices = pBLEScan->start(5); //seconds
|
BLEScanResults foundDevices = pBLEScan->start(5); //seconds
|
||||||
|
|
||||||
Serial.println("Devices found: " + String(foundDevices->getCount()));
|
Serial.println("Devices found: " + String(foundDevices.getCount()));
|
||||||
|
|
||||||
while(!eth_ready){
|
while(!eth_ready){
|
||||||
Serial.println("Wait for eth...");
|
Serial.println("Wait for eth...");
|
||||||
delay(250);
|
delay(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < foundDevices->getCount(); i++) {
|
while(!wsManager.isConnected()){
|
||||||
|
Serial.println("Wait for socket...");
|
||||||
|
delay(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < foundDevices.getCount(); i++) {
|
||||||
delay(1000);
|
delay(1000);
|
||||||
Serial.printf("\r\n\r\n===============================\r\n\r\n");
|
Serial.printf("\r\n\r\n===============================\r\n\r\n");
|
||||||
|
|
||||||
BLEAdvertisedDevice advertisedDevice = foundDevices->getDevice(i);
|
BLEAdvertisedDevice advertisedDevice = foundDevices.getDevice(i);
|
||||||
Serial.println("\nFound Device: " + String(advertisedDevice.toString().c_str()));
|
Serial.println("\nFound Device: " + String(advertisedDevice.toString().c_str()));
|
||||||
|
|
||||||
String targetAddress = "d0:65:de:e5:89:76";
|
std::string targetAddress = "d0:65:de:e5:89:76";
|
||||||
if (advertisedDevice.getAddress().toString().c_str() == targetAddress) {
|
if (advertisedDevice.getAddress().toString() == targetAddress) {
|
||||||
Serial.println("Victron device found!");
|
Serial.println("Victron device found!");
|
||||||
decodeVictron(advertisedDevice);
|
decodeVictron(advertisedDevice);
|
||||||
break;
|
break;
|
||||||
@@ -144,15 +111,12 @@ void loop() {
|
|||||||
// Get BMS receive characteristic
|
// Get BMS receive characteristic
|
||||||
Serial.println("Get BMS receive characteristic...");
|
Serial.println("Get BMS receive characteristic...");
|
||||||
BLERemoteCharacteristic* pRemoteCharacteristic_rx = pRemoteService->getCharacteristic(charUUID_rx);
|
BLERemoteCharacteristic* pRemoteCharacteristic_rx = pRemoteService->getCharacteristic(charUUID_rx);
|
||||||
Serial.println("Got BMS receive characteristic...");
|
|
||||||
if (pRemoteCharacteristic_rx == nullptr){
|
if (pRemoteCharacteristic_rx == nullptr){
|
||||||
Serial.println(String("BLE: failed to find RX UUID"));
|
Serial.println(String("BLE: failed to find RX UUID"));
|
||||||
Serial.print("Failed to find rx UUID: ");
|
Serial.print("Failed to find rx UUID: ");
|
||||||
Serial.println(charUUID_rx.toString().c_str());
|
Serial.println(charUUID_rx.toString().c_str());
|
||||||
pClient->disconnect();
|
pClient->disconnect();
|
||||||
continue;
|
continue;
|
||||||
}else {
|
|
||||||
Serial.println("RX characteristic found successfully.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register callback for remote characteristic (receive channel)
|
// Register callback for remote characteristic (receive channel)
|
||||||
@@ -191,7 +155,7 @@ void loop() {
|
|||||||
gotBasicInfo=false;
|
gotBasicInfo=false;
|
||||||
gotCellInfo=false;
|
gotCellInfo=false;
|
||||||
|
|
||||||
String deviceName = advertisedDevice.getName();
|
std::__cxx11::string deviceName = advertisedDevice.getName();
|
||||||
strncpy(currentName, deviceName.c_str(), sizeof(currentName) - 1);
|
strncpy(currentName, deviceName.c_str(), sizeof(currentName) - 1);
|
||||||
currentName[sizeof(currentName) - 1] = '\0'; // Ensure null-termination
|
currentName[sizeof(currentName) - 1] = '\0'; // Ensure null-termination
|
||||||
// Convert to lowercase and replace spaces with dots
|
// Convert to lowercase and replace spaces with dots
|
||||||
@@ -222,7 +186,6 @@ void loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pClient->disconnect();
|
pClient->disconnect();
|
||||||
hq.poll();
|
|
||||||
}
|
}
|
||||||
Serial.println("Reboot!");
|
Serial.println("Reboot!");
|
||||||
delay(100);
|
delay(100);
|
||||||
@@ -379,14 +342,14 @@ bool processBasicInfo(byte *data, unsigned int dataLen){
|
|||||||
uint16_t BalanceCodeHigh = (two_ints_into16(data[14], data[15]));
|
uint16_t BalanceCodeHigh = (two_ints_into16(data[14], data[15]));
|
||||||
uint8_t MosfetStatus = ((byte)data[20]);
|
uint8_t MosfetStatus = ((byte)data[20]);
|
||||||
|
|
||||||
hq.send("test.RC.%s.Voltage %f",currentName, (float)Volts / 1000);
|
wsManager.sendText("test.RC.%s.Voltage %f",currentName, (float)Volts / 1000);
|
||||||
hq.send("test.RC.%s.Amps %f",currentName, (float)Amps / 1000);
|
wsManager.sendText("test.RC.%s.Amps %f",currentName, (float)Amps / 1000);
|
||||||
hq.send("test.RC.%s.Watts %f",currentName, (float)Watts);
|
wsManager.sendText("test.RC.%s.Watts %f",currentName, (float)Watts);
|
||||||
hq.send("test.RC.%s.Capacity_Remain_Ah %f",currentName, (float)CapacityRemainAh / 1000);
|
wsManager.sendText("test.RC.%s.Capacity_Remain_Ah %f",currentName, (float)CapacityRemainAh / 1000);
|
||||||
hq.send("test.RC.%s.Capacity_Remain_Wh %f",currentName, ((float)(CapacityRemainAh) / 1000) * ((float)(Volts) / 1000));
|
wsManager.sendText("test.RC.%s.Capacity_Remain_Wh %f",currentName, ((float)(CapacityRemainAh) / 1000) * ((float)(Volts) / 1000));
|
||||||
hq.send("test.RC.%s.Capacity_Remain_Percent %d",currentName, CapacityRemainPercent);
|
wsManager.sendText("test.RC.%s.Capacity_Remain_Percent %d",currentName, CapacityRemainPercent);
|
||||||
hq.send("test.RC.%s.Temp1 %f",currentName, (float)Temp1 / 10);
|
wsManager.sendText("test.RC.%s.Temp1 %f",currentName, (float)Temp1 / 10);
|
||||||
hq.send("test.RC.%s.Temp2 %f",currentName, (float)Temp2 / 10);
|
wsManager.sendText("test.RC.%s.Temp2 %f",currentName, (float)Temp2 / 10);
|
||||||
/*
|
/*
|
||||||
Serial.printf("%s Balance Code Low: 0x%x\r\n",currentName, BalanceCodeLow);
|
Serial.printf("%s Balance Code Low: 0x%x\r\n",currentName, BalanceCodeLow);
|
||||||
Serial.printf("%s Balance Code High: 0x%x\r\n",currentName, BalanceCodeHigh);
|
Serial.printf("%s Balance Code High: 0x%x\r\n",currentName, BalanceCodeHigh);
|
||||||
@@ -420,13 +383,13 @@ bool processCellInfo(byte *data, unsigned int dataLen)
|
|||||||
_cellMin = CellVolt;
|
_cellMin = CellVolt;
|
||||||
}
|
}
|
||||||
|
|
||||||
hq.send("test.RC.%s.Cell.%d.Voltage %f",currentName, i+1,(float)CellVolt/1000);
|
wsManager.sendText("test.RC.%s.Cell.%d.Voltage %f",currentName, i+1,(float)CellVolt/1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
hq.send("test.RC.%s.Max_Cell_Voltage %f",currentName, (float)_cellMax / 1000);
|
wsManager.sendText("test.RC.%s.Max_Cell_Voltage %f",currentName, (float)_cellMax / 1000);
|
||||||
hq.send("test.RC.%s.Min_Cell_Voltage %f",currentName, (float)_cellMin / 1000);
|
wsManager.sendText("test.RC.%s.Min_Cell_Voltage %f",currentName, (float)_cellMin / 1000);
|
||||||
hq.send("test.RC.%s.Difference_Cell_Voltage %f",currentName, (float)(_cellMax - _cellMin) / 1000);
|
wsManager.sendText("test.RC.%s.Difference_Cell_Voltage %f",currentName, (float)(_cellMax - _cellMin) / 1000);
|
||||||
hq.send("test.RC.%s.Average_Cell_Voltage %f",currentName, (float)(_cellSum / NumOfCells) / 1000);
|
wsManager.sendText("test.RC.%s.Average_Cell_Voltage %f",currentName, (float)(_cellSum / NumOfCells) / 1000);
|
||||||
|
|
||||||
gotCellInfo=true;
|
gotCellInfo=true;
|
||||||
|
|
||||||
@@ -474,3 +437,42 @@ int16_t two_ints_into16(int highbyte, int lowbyte) // turns two bytes into a sin
|
|||||||
result = (result | lowbyte); //OR operation, merge the two
|
result = (result | lowbyte); //OR operation, merge the two
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WiFiEvent(WiFiEvent_t event) {
|
||||||
|
Serial.print("E:");
|
||||||
|
Serial.println(event);
|
||||||
|
switch (event) {
|
||||||
|
case ARDUINO_EVENT_ETH_START:
|
||||||
|
Serial.println("ETH Started");
|
||||||
|
//set eth hostname here
|
||||||
|
ETH.setHostname("esp32-ethernet");
|
||||||
|
break;
|
||||||
|
case ARDUINO_EVENT_ETH_CONNECTED:
|
||||||
|
Serial.println("ETH Connected");
|
||||||
|
break;
|
||||||
|
case ARDUINO_EVENT_ETH_GOT_IP:
|
||||||
|
Serial.print("ETH MAC: ");
|
||||||
|
Serial.print(ETH.macAddress());
|
||||||
|
Serial.print(", IPv4: ");
|
||||||
|
Serial.print(ETH.localIP());
|
||||||
|
if (ETH.fullDuplex()) {
|
||||||
|
Serial.print(", FULL_DUPLEX");
|
||||||
|
}
|
||||||
|
Serial.print(", ");
|
||||||
|
Serial.print(ETH.linkSpeed());
|
||||||
|
Serial.println("Mbps");
|
||||||
|
eth_ready = true;
|
||||||
|
break;
|
||||||
|
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||||
|
Serial.println("ETH Disconnected");
|
||||||
|
eth_ready = false;
|
||||||
|
break;
|
||||||
|
case ARDUINO_EVENT_ETH_STOP:
|
||||||
|
Serial.println("ETH Stopped");
|
||||||
|
eth_ready = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
98
HQ.h
98
HQ.h
@@ -1,98 +0,0 @@
|
|||||||
#ifndef HQ_H
|
|
||||||
#define HQ_H
|
|
||||||
|
|
||||||
#include <NetworkClientSecure.h>
|
|
||||||
#include <HTTPClient.h>
|
|
||||||
#include "Buffer.h"
|
|
||||||
#include "ca_cert.h"
|
|
||||||
|
|
||||||
class HQ {
|
|
||||||
public:
|
|
||||||
// Public static function to get the instance of the singleton class
|
|
||||||
static HQ& getInstance() {
|
|
||||||
static HQ instance; // Create a single instance of the class on first call
|
|
||||||
return instance; // Return the single instance on each call
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private constructor and copy constructor to prevent outside instantiation
|
|
||||||
HQ(){
|
|
||||||
client = new NetworkClientSecure;
|
|
||||||
if(!client) {
|
|
||||||
Serial.printf("Unable to create HTTP client\r\n");
|
|
||||||
}
|
|
||||||
client->setCACert(ca_cert);
|
|
||||||
client->setHandshakeTimeout(5);
|
|
||||||
}
|
|
||||||
HQ(const HQ&) = delete;
|
|
||||||
Buffer txBuffer=Buffer(4096,'&');
|
|
||||||
Buffer rxBuffer=Buffer(1024,'\n');
|
|
||||||
NetworkClientSecure *client;
|
|
||||||
|
|
||||||
public:
|
|
||||||
unsigned long httpErrors=0;
|
|
||||||
boolean send(const char *s){
|
|
||||||
Serial.printf("HQ_SEND:%s\r\n",s);
|
|
||||||
return txBuffer.add(s);
|
|
||||||
}
|
|
||||||
template<typename T, typename... Args>
|
|
||||||
boolean send(const char* format, T arg1, Args... args)
|
|
||||||
{
|
|
||||||
static char msg[1024];
|
|
||||||
snprintf(msg, 1024, format, arg1, args...);
|
|
||||||
|
|
||||||
return send(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean poll(){
|
|
||||||
String payload;
|
|
||||||
if(strlen(txBuffer.get())){
|
|
||||||
payload+=txBuffer.get();
|
|
||||||
}
|
|
||||||
if(payload.isEmpty()){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
HTTPClient https;
|
|
||||||
https.setTimeout(1000);
|
|
||||||
https.setConnectTimeout(1000);
|
|
||||||
https.addHeader("Content-Type","application/x-www-form-urlencoded");
|
|
||||||
String url="https://api.ecomotus.co.uk/api/v1/graphite";
|
|
||||||
Serial.printf("Connecting to %s\r\n",url.c_str());
|
|
||||||
if(!https.begin(*client, url)) { // HTTPS
|
|
||||||
Serial.printf("HTTP Connection Failed\r\n");
|
|
||||||
httpErrors++;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int httpCode=https.POST(payload);
|
|
||||||
if(httpCode==200){
|
|
||||||
txBuffer.clear();
|
|
||||||
// Read all the lines of the reply from server and print them to Serial
|
|
||||||
boolean command=false;
|
|
||||||
char buff[128];
|
|
||||||
int totalSize=0;
|
|
||||||
NetworkClient * stream = https.getStreamPtr();
|
|
||||||
while(stream->available() && totalSize<1000) {
|
|
||||||
size_t size=stream->readBytesUntil('\n',buff,120);
|
|
||||||
totalSize+=size;
|
|
||||||
buff[size]=0;
|
|
||||||
Serial.printf("Response: %s\r\n",buff);
|
|
||||||
if(command==true){
|
|
||||||
rxBuffer.add(buff);
|
|
||||||
command=false;
|
|
||||||
}
|
|
||||||
if(0==strcmp(buff,"COMMAND")){
|
|
||||||
command=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Serial.printf("Got %d bytes\r\n",totalSize);
|
|
||||||
}else{
|
|
||||||
Serial.printf("HTTP Error: %d\r\n",httpCode);
|
|
||||||
httpErrors++;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
HQ& hq = HQ::getInstance();
|
|
||||||
#endif
|
|
83
WebSocketManager.h
Normal file
83
WebSocketManager.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#ifndef WEBSOCKETMANAGER_H
|
||||||
|
#define WEBSOCKETMANAGER_H
|
||||||
|
|
||||||
|
#include <WebSocketsClient.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include "ca_cert.h"
|
||||||
|
|
||||||
|
class WebSocketManager {
|
||||||
|
public:
|
||||||
|
WebSocketManager(const char* server, uint16_t port, const char* url) {
|
||||||
|
serverUrl = server;
|
||||||
|
serverPort = port;
|
||||||
|
serverPath = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
void begin() {
|
||||||
|
xTaskCreate(&WebSocketManager::webSocketTask, "WebSocketTask", 8192, nullptr, 1, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void sendText(const char* format, Args... args) {
|
||||||
|
if (webSocket.isConnected() && isConnected) {
|
||||||
|
char buffer[512]; // Define a buffer to hold the constructed message
|
||||||
|
snprintf(buffer, sizeof(buffer), format, args...); // Use snprintf to format the string
|
||||||
|
webSocket.sendTXT(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void webSocketTask(void *param) {
|
||||||
|
WiFiClient client;
|
||||||
|
//client.setCACert(ca_cert);
|
||||||
|
//webSocket.beginSSL(serverUrl.c_str(), serverPort, serverPath.c_str(), ca_cert);
|
||||||
|
webSocket.begin(serverUrl.c_str(), serverPort, serverPath.c_str());
|
||||||
|
webSocket.onEvent(webSocketEvent);
|
||||||
|
webSocket.setReconnectInterval(1000);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
webSocket.loop();
|
||||||
|
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||||
|
switch (type) {
|
||||||
|
case WStype_DISCONNECTED:
|
||||||
|
connected = false;
|
||||||
|
Serial.println("[WebSocket] Disconnected");
|
||||||
|
break;
|
||||||
|
case WStype_CONNECTED:
|
||||||
|
connected = true;
|
||||||
|
Serial.println("[WebSocket] Connected");
|
||||||
|
break;
|
||||||
|
case WStype_TEXT:
|
||||||
|
Serial.print("[WebSocket] Received: ");
|
||||||
|
Serial.println((char*)payload);
|
||||||
|
break;
|
||||||
|
case WStype_BIN:
|
||||||
|
Serial.println("[WebSocket] Received binary data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static WebSocketsClient webSocket;
|
||||||
|
static String serverUrl;
|
||||||
|
static uint16_t serverPort;
|
||||||
|
static String serverPath;
|
||||||
|
static bool connected;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define static members
|
||||||
|
WebSocketsClient WebSocketManager::webSocket;
|
||||||
|
String WebSocketManager::serverUrl = "";
|
||||||
|
uint16_t WebSocketManager::serverPort = 0;
|
||||||
|
String WebSocketManager::serverPath = "";
|
||||||
|
bool WebSocketManager::connected = false;
|
||||||
|
|
||||||
|
#endif // WEBSOCKETMANAGER_H
|
@@ -10,7 +10,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "#define VERSION \"${NAME}\"" >> compile_flags.h
|
echo "#define VERSION \"${NAME}\"" >> compile_flags.h
|
||||||
arduino-cli compile --build-property build.partitions=huge_app --build-property upload.maximum_size=3145728 -e -b esp32:esp32:esp32 || exit 1
|
arduino-cli compile $LIBS -e -b esp32:esp32:esp32 || exit 1
|
||||||
mv build/esp32.esp32.esp32/*.ino.bin Compiled/${NAME}.bin
|
mv build/esp32.esp32.esp32/*.ino.bin Compiled/${NAME}.bin
|
||||||
mv build/esp32.esp32.esp32/*.ino.elf Compiled/${NAME}.elf
|
mv build/esp32.esp32.esp32/*.ino.elf Compiled/${NAME}.elf
|
||||||
mv build/esp32.esp32.esp32/*.ino.partitions.bin Compiled/${NAME}.partitions.bin
|
mv build/esp32.esp32.esp32/*.ino.partitions.bin Compiled/${NAME}.partitions.bin
|
||||||
|
26
victron.ino
26
victron.ino
@@ -76,12 +76,20 @@ void decodeVictron(BLEAdvertisedDevice advertisedDevice) {
|
|||||||
// at the end.
|
// at the end.
|
||||||
uint8_t manCharBuf[manDataSizeMax+1];
|
uint8_t manCharBuf[manDataSizeMax+1];
|
||||||
|
|
||||||
String manData = advertisedDevice.getManufacturerData(); // lib code returns String.
|
#ifdef USE_String
|
||||||
|
String manData = advertisedDevice.getManufacturerData(); // lib code returns String.
|
||||||
|
#else
|
||||||
|
std::string manData = advertisedDevice.getManufacturerData(); // lib code returns std::string
|
||||||
|
#endif
|
||||||
int manDataSize=manData.length(); // This does not count the null at the end.
|
int manDataSize=manData.length(); // This does not count the null at the end.
|
||||||
|
|
||||||
// Copy the data from the String to a byte array. Must have the +1 so we
|
// Copy the data from the String to a byte array. Must have the +1 so we
|
||||||
// don't lose the last character to the null terminator.
|
// don't lose the last character to the null terminator.
|
||||||
manData.toCharArray((char *)manCharBuf,manDataSize+1);
|
#ifdef USE_String
|
||||||
|
manData.toCharArray((char *)manCharBuf,manDataSize+1);
|
||||||
|
#else
|
||||||
|
manData.copy((char *)manCharBuf, manDataSize+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Now let's setup a pointer to a struct to get to the data more cleanly.
|
// Now let's setup a pointer to a struct to get to the data more cleanly.
|
||||||
victronManufacturerData * vicData=(victronManufacturerData *)manCharBuf;
|
victronManufacturerData * vicData=(victronManufacturerData *)manCharBuf;
|
||||||
@@ -177,12 +185,12 @@ void decodeVictron(BLEAdvertisedDevice advertisedDevice) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hq.send("test.RC.MPPT.1.Battery_Volts %f",batteryVoltage);
|
wsManager.sendText("test.RC.MPPT.1.Battery_Volts %f",batteryVoltage);
|
||||||
hq.send("test.RC.MPPT.1.Battery_Amps %f",batteryCurrent);
|
wsManager.sendText("test.RC.MPPT.1.Battery_Amps %f",batteryCurrent);
|
||||||
hq.send("test.RC.MPPT.1.Battery_Watts %f",batteryVoltage*batteryCurrent);
|
wsManager.sendText("test.RC.MPPT.1.Battery_Watts %f",batteryVoltage*batteryCurrent);
|
||||||
hq.send("test.RC.MPPT.1.Solar_Watts %f",inputPower);
|
wsManager.sendText("test.RC.MPPT.1.Solar_Watts %f",inputPower);
|
||||||
hq.send("test.RC.MPPT.1.Output_Current %f",outputCurrent);
|
wsManager.sendText("test.RC.MPPT.1.Output_Current %f",outputCurrent);
|
||||||
hq.send("test.RC.MPPT.1.Yield %f",todayYield);
|
wsManager.sendText("test.RC.MPPT.1.Yield %f",todayYield);
|
||||||
hq.send("test.RC.MPPT.1.State %d",deviceState);
|
wsManager.sendText("test.RC.MPPT.1.State %d",deviceState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user