websockets
This commit is contained in:
parent
39cc68c4d9
commit
b1be320655
141
ESPBMS.ino
141
ESPBMS.ino
@ -1,20 +1,20 @@
|
||||
#include "BLEDevice.h"
|
||||
#include <ETH.h>
|
||||
#include <NTPClient.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <HTTPClient.h>
|
||||
#include "ca_cert.h"
|
||||
#include "config.h"
|
||||
#include "WebSocketManager.h"
|
||||
|
||||
// NTP Client setup
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, "pool.ntp.org");
|
||||
WebSocketManager wsManager("wss://hq.ecomotus.co.uk", 443, "/");
|
||||
|
||||
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_tx("0000ff02-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms tx id
|
||||
|
||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN // ETH_CLOCK_GPIO17_OUT
|
||||
#define ETH_POWER_PIN 16
|
||||
#define ETH_TYPE ETH_PHY_LAN8720
|
||||
#define ETH_ADDR 1
|
||||
#define ETH_MDC_PIN 23
|
||||
#define ETH_MDIO_PIN 18
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte start;
|
||||
@ -28,31 +28,15 @@ bool gotBasicInfo;
|
||||
bool gotCellInfo;
|
||||
static bool eth_ready = false;
|
||||
|
||||
WiFiClientSecure client;
|
||||
HTTPClient https;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
eth_begin();
|
||||
timeClient.begin();
|
||||
client.setCACert(ca_cert);
|
||||
client.setHandshakeTimeout(5);
|
||||
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
||||
BLEDevice::init(""); // Initialize BLE device
|
||||
}
|
||||
|
||||
bool client_connect(){
|
||||
//https.setTimeout(preferences.getInt("http_timeout"));
|
||||
//https.setConnectTimeout(preferences.getInt("http_timeout"));
|
||||
//https.addHeader("Content-Type","application/x-www-form-urlencoded");
|
||||
String url="URL";
|
||||
https.end();
|
||||
if(!https.begin(client, url)) { // HTTPS
|
||||
Serial.println("connect fail");
|
||||
return false;
|
||||
}
|
||||
Serial.println("connect ok");
|
||||
return true;
|
||||
Serial.begin(115200);
|
||||
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
BLEDevice::init("");
|
||||
wsManager.begin();
|
||||
wsManager.sendText("hello");
|
||||
wsManager.sendText("Up: %lu ms", millis());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@ -66,14 +50,6 @@ void loop() {
|
||||
|
||||
Serial.println("Devices found: " + String(foundDevices.getCount()));
|
||||
|
||||
while(!eth_ready){
|
||||
Serial.println("Wait for eth...");
|
||||
delay(250);
|
||||
}
|
||||
timeClient.update();
|
||||
//testClient("www.google.com", 80);
|
||||
client_connect();
|
||||
|
||||
for (int i = 0; i < foundDevices.getCount(); i++) {
|
||||
delay(1000);
|
||||
Serial.printf("\r\n\r\n===============================\r\n\r\n");
|
||||
@ -81,8 +57,6 @@ void loop() {
|
||||
BLEAdvertisedDevice advertisedDevice = foundDevices.getDevice(i);
|
||||
Serial.println("\nFound Device: " + String(advertisedDevice.toString().c_str()));
|
||||
|
||||
client_connect();
|
||||
|
||||
std::string targetAddress = "d0:65:de:e5:89:76";
|
||||
if (advertisedDevice.getAddress().toString() == targetAddress) {
|
||||
Serial.println("Victron device found!");
|
||||
@ -360,14 +334,14 @@ bool processBasicInfo(byte *data, unsigned int dataLen){
|
||||
uint16_t BalanceCodeHigh = (two_ints_into16(data[14], data[15]));
|
||||
uint8_t MosfetStatus = ((byte)data[20]);
|
||||
|
||||
eth_send("test.RC.%s.Voltage %f",currentName, (float)Volts / 1000);
|
||||
eth_send("test.RC.%s.Amps %f",currentName, (float)Amps / 1000);
|
||||
eth_send("test.RC.%s.Watts %f",currentName, (float)Watts);
|
||||
eth_send("test.RC.%s.Capacity_Remain_Ah %f",currentName, (float)CapacityRemainAh / 1000);
|
||||
eth_send("test.RC.%s.Capacity_Remain_Wh %f",currentName, ((float)(CapacityRemainAh) / 1000) * ((float)(Volts) / 1000));
|
||||
eth_send("test.RC.%s.Capacity_Remain_Percent %d",currentName, CapacityRemainPercent);
|
||||
eth_send("test.RC.%s.Temp1 %f",currentName, (float)Temp1 / 10);
|
||||
eth_send("test.RC.%s.Temp2 %f",currentName, (float)Temp2 / 10);
|
||||
wsManager.sendText("test.RC.%s.Voltage %f",currentName, (float)Volts / 1000);
|
||||
wsManager.sendText("test.RC.%s.Amps %f",currentName, (float)Amps / 1000);
|
||||
wsManager.sendText("test.RC.%s.Watts %f",currentName, (float)Watts);
|
||||
wsManager.sendText("test.RC.%s.Capacity_Remain_Ah %f",currentName, (float)CapacityRemainAh / 1000);
|
||||
wsManager.sendText("test.RC.%s.Capacity_Remain_Wh %f",currentName, ((float)(CapacityRemainAh) / 1000) * ((float)(Volts) / 1000));
|
||||
wsManager.sendText("test.RC.%s.Capacity_Remain_Percent %d",currentName, CapacityRemainPercent);
|
||||
wsManager.sendText("test.RC.%s.Temp1 %f",currentName, (float)Temp1 / 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 High: 0x%x\r\n",currentName, BalanceCodeHigh);
|
||||
@ -401,13 +375,13 @@ bool processCellInfo(byte *data, unsigned int dataLen)
|
||||
_cellMin = CellVolt;
|
||||
}
|
||||
|
||||
eth_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);
|
||||
}
|
||||
|
||||
eth_send("test.RC.%s.Max_Cell_Voltage %f",currentName, (float)_cellMax / 1000);
|
||||
eth_send("test.RC.%s.Min_Cell_Voltage %f",currentName, (float)_cellMin / 1000);
|
||||
eth_send("test.RC.%s.Difference_Cell_Voltage %f",currentName, (float)(_cellMax - _cellMin) / 1000);
|
||||
eth_send("test.RC.%s.Average_Cell_Voltage %f",currentName, (float)(_cellSum / NumOfCells) / 1000);
|
||||
wsManager.sendText("test.RC.%s.Max_Cell_Voltage %f",currentName, (float)_cellMax / 1000);
|
||||
wsManager.sendText("test.RC.%s.Min_Cell_Voltage %f",currentName, (float)_cellMin / 1000);
|
||||
wsManager.sendText("test.RC.%s.Difference_Cell_Voltage %f",currentName, (float)(_cellMax - _cellMin) / 1000);
|
||||
wsManager.sendText("test.RC.%s.Average_Cell_Voltage %f",currentName, (float)(_cellSum / NumOfCells) / 1000);
|
||||
|
||||
gotCellInfo=true;
|
||||
|
||||
@ -456,30 +430,6 @@ int16_t two_ints_into16(int highbyte, int lowbyte) // turns two bytes into a sin
|
||||
return result;
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
/*
|
||||
* ETH_CLOCK_GPIO0_IN - default: external clock from crystal oscillator
|
||||
* ETH_CLOCK_GPIO0_OUT - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
|
||||
* ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
|
||||
* ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
|
||||
*/
|
||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN // ETH_CLOCK_GPIO17_OUT
|
||||
|
||||
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
|
||||
#define ETH_POWER_PIN 16
|
||||
|
||||
// Type of the Ethernet PHY (LAN8720 or TLK110)
|
||||
#define ETH_TYPE ETH_PHY_LAN8720
|
||||
|
||||
// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
|
||||
#define ETH_ADDR 1
|
||||
|
||||
// Pin# of the I²C clock signal for the Ethernet PHY
|
||||
#define ETH_MDC_PIN 23
|
||||
|
||||
// Pin# of the I²C IO signal for the Ethernet PHY
|
||||
#define ETH_MDIO_PIN 18
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event) {
|
||||
Serial.print("E:");
|
||||
@ -518,36 +468,3 @@ void WiFiEvent(WiFiEvent_t event) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Overloaded template function for formatted sending
|
||||
template<typename... Args>
|
||||
void eth_send(const char* format, Args... args) {
|
||||
constexpr std::size_t bufferSize = 1024; // Define a reasonable default buffer size
|
||||
std::array<char, bufferSize> buffer;
|
||||
snprintf(buffer.data(), buffer.size(), format, args...);
|
||||
eth_send(buffer.data()); // Call the original eth_send function
|
||||
}
|
||||
|
||||
void eth_send(const char *data) {
|
||||
if(!https.connected()){
|
||||
https.end();
|
||||
client_connect();
|
||||
}
|
||||
Serial.print("http connecting...\r\n");
|
||||
Serial.printf("ETH Send: %s\r\n", data);
|
||||
int httpCode=https.POST(data);
|
||||
if(httpCode==200){
|
||||
Serial.println("post ok");
|
||||
while (client.available()) {
|
||||
Serial.write(client.read());
|
||||
}
|
||||
}else{
|
||||
Serial.print("post fail:");
|
||||
Serial.println(httpCode);
|
||||
}
|
||||
}
|
||||
|
||||
void eth_begin() {
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
|
||||
}
|
||||
|
73
WebSocketManager.h
Normal file
73
WebSocketManager.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef WEBSOCKETMANAGER_H
|
||||
#define WEBSOCKETMANAGER_H
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include "ca_cert.h" // Include the CA certificate
|
||||
|
||||
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()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static void webSocketTask(void *param) {
|
||||
WiFiClientSecure client;
|
||||
client.setCACert(ca_cert);
|
||||
webSocket.beginSSL(serverUrl.c_str(), serverPort, serverPath.c_str(), ca_cert);
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
webSocket.setReconnectInterval(5000);
|
||||
|
||||
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:
|
||||
Serial.println("[WebSocket] Disconnected");
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
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;
|
||||
};
|
||||
|
||||
// Define static members
|
||||
WebSocketsClient WebSocketManager::webSocket;
|
||||
String WebSocketManager::serverUrl = "";
|
||||
uint16_t WebSocketManager::serverPort = 0;
|
||||
String WebSocketManager::serverPath = "";
|
||||
|
||||
#endif // WEBSOCKETMANAGER_H
|
14
victron.ino
14
victron.ino
@ -185,12 +185,12 @@ void decodeVictron(BLEAdvertisedDevice advertisedDevice) {
|
||||
return;
|
||||
}
|
||||
|
||||
eth_send("test.RC.MPPT.1.Battery_Volts %f",batteryVoltage);
|
||||
eth_send("test.RC.MPPT.1.Battery_Amps %f",batteryCurrent);
|
||||
eth_send("test.RC.MPPT.1.Battery_Watts %f",batteryVoltage*batteryCurrent);
|
||||
eth_send("test.RC.MPPT.1.Solar_Watts %f",inputPower);
|
||||
eth_send("test.RC.MPPT.1.Output_Current %f",outputCurrent);
|
||||
eth_send("test.RC.MPPT.1.Yield %f",todayYield);
|
||||
eth_send("test.RC.MPPT.1.State %d",deviceState);
|
||||
wsManager.sendText("test.RC.MPPT.1.Battery_Volts %f",batteryVoltage);
|
||||
wsManager.sendText("test.RC.MPPT.1.Battery_Amps %f",batteryCurrent);
|
||||
wsManager.sendText("test.RC.MPPT.1.Battery_Watts %f",batteryVoltage*batteryCurrent);
|
||||
wsManager.sendText("test.RC.MPPT.1.Solar_Watts %f",inputPower);
|
||||
wsManager.sendText("test.RC.MPPT.1.Output_Current %f",outputCurrent);
|
||||
wsManager.sendText("test.RC.MPPT.1.Yield %f",todayYield);
|
||||
wsManager.sendText("test.RC.MPPT.1.State %d",deviceState);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user