Compare commits
3 Commits
53fa6fa0e1
..
v0.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 97e57b0306 | |||
| 05ee88cd31 | |||
| ef50829c81 |
@@ -320,3 +320,31 @@ cd3b462 ignore local
|
||||
- src/VictronBLE.h
|
||||
- src/crypto/vble_aes.c
|
||||
|
||||
|
||||
### Session: 2026-06-04 23:58
|
||||
**Commits:**
|
||||
```
|
||||
53fa6fa ignore pka file
|
||||
de6607d Branch version ready for testing with nRF52
|
||||
```
|
||||
**Modified files:**
|
||||
- .gitignore
|
||||
- README.md
|
||||
- UPGRADE_V0.4.md
|
||||
- VERSIONS
|
||||
- library.json
|
||||
- library.properties
|
||||
|
||||
|
||||
### Session: 2026-06-05 00:00
|
||||
**Commits:**
|
||||
```
|
||||
53fa6fa ignore pka file
|
||||
de6607d Branch version ready for testing with nRF52
|
||||
```
|
||||
**Modified files:**
|
||||
- .claude/CLAUDE.md
|
||||
- .gitignore
|
||||
- README.md
|
||||
- UPGRADE_V0.4.md
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
A portable Arduino library for reading Victron Energy device data via Bluetooth Low Energy (BLE) advertisements — runs on both **ESP32** and **nRF52840**.
|
||||
|
||||
**⚠️ API CHANGE in v0.4 — not backwards compatible with v0.3.x**
|
||||
|
||||
v0.4 is a major rework of the library internals: new callback API, reduced memory usage, non-blocking scanning. See [VERSIONS](VERSIONS) for full details. A stable **v1.0** release with a consistent, long-term API is coming soon.
|
||||
v0.6 adds **multi-platform support** (ESP32 + nRF52840) via a hardware-abstracted BLE backend and dependency-free bundled crypto. (v0.5 brought the decoding accuracy fixes and AC charger support; v0.4 reworked the internals — function-pointer callback API, reduced memory usage, non-blocking scanning.) See [VERSIONS](VERSIONS) for full details. A stable **v1.0** release with a consistent, long-term API is coming soon.
|
||||
|
||||
---
|
||||
|
||||
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
# Upgrading to VictronBLE v0.4
|
||||
|
||||
v0.4 is a breaking API change that simplifies the library significantly.
|
||||
|
||||
## Summary of Changes
|
||||
|
||||
- **Callback**: Virtual class → function pointer
|
||||
- **Data access**: Inheritance → tagged union (`VictronDevice` with `solar`, `battery`, `inverter`, `dcdc` members)
|
||||
- **Strings**: Arduino `String` → fixed `char[]` arrays
|
||||
- **Memory**: `std::map` + heap allocation → fixed array, zero dynamic allocation
|
||||
- **Removed**: `getLastError()`, `removeDevice()`, `getDevicesByType()`, per-type getter methods, `VictronDeviceConfig` struct, `VictronDeviceCallback` class
|
||||
- **Removed field**: `panelVoltage` (was unreliably derived from `panelPower / batteryCurrent`)
|
||||
|
||||
## Migration Guide
|
||||
|
||||
### 1. Callback: class → function pointer
|
||||
|
||||
**Before (v0.3):**
|
||||
```cpp
|
||||
class MyCallback : public VictronDeviceCallback {
|
||||
void onSolarChargerData(const SolarChargerData& data) override {
|
||||
Serial.println(data.deviceName + ": " + String(data.panelPower) + "W");
|
||||
}
|
||||
void onBatteryMonitorData(const BatteryMonitorData& data) override {
|
||||
Serial.println("SOC: " + String(data.soc) + "%");
|
||||
}
|
||||
};
|
||||
MyCallback callback;
|
||||
victron.setCallback(&callback);
|
||||
```
|
||||
|
||||
**After (v0.4):**
|
||||
```cpp
|
||||
void onVictronData(const VictronDevice* dev) {
|
||||
switch (dev->deviceType) {
|
||||
case DEVICE_TYPE_SOLAR_CHARGER:
|
||||
Serial.printf("%s: %.0fW\n", dev->name, dev->solar.panelPower);
|
||||
break;
|
||||
case DEVICE_TYPE_BATTERY_MONITOR:
|
||||
Serial.printf("SOC: %.1f%%\n", dev->battery.soc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
victron.setCallback(onVictronData);
|
||||
```
|
||||
|
||||
### 2. Data field access
|
||||
|
||||
Fields moved from flat `SolarChargerData` etc. into the `VictronDevice` tagged union:
|
||||
|
||||
| Old (v0.3) | New (v0.4) |
|
||||
|---|---|
|
||||
| `data.deviceName` | `dev->name` (char[32]) |
|
||||
| `data.macAddress` | `dev->mac` (char[13]) |
|
||||
| `data.rssi` | `dev->rssi` |
|
||||
| `data.lastUpdate` | `dev->lastUpdate` |
|
||||
| `data.batteryVoltage` | `dev->solar.batteryVoltage` |
|
||||
| `data.batteryCurrent` | `dev->solar.batteryCurrent` |
|
||||
| `data.panelPower` | `dev->solar.panelPower` |
|
||||
| `data.yieldToday` | `dev->solar.yieldToday` |
|
||||
| `data.loadCurrent` | `dev->solar.loadCurrent` |
|
||||
| `data.chargeState` | `dev->solar.chargeState` (uint8_t, was enum) |
|
||||
| `data.panelVoltage` | **Removed** - see below |
|
||||
|
||||
### 3. panelVoltage removed
|
||||
|
||||
`panelVoltage` was a derived value (`panelPower / batteryCurrent`) that was unreliable (division by zero when no current, inaccurate due to MPPT conversion). It has been removed.
|
||||
|
||||
If you need an estimate:
|
||||
```cpp
|
||||
float panelVoltage = (dev->solar.batteryCurrent > 0.1f)
|
||||
? dev->solar.panelPower / dev->solar.batteryCurrent
|
||||
: 0.0f;
|
||||
```
|
||||
|
||||
### 4. getLastError() removed
|
||||
|
||||
Debug output now goes directly to Serial when `setDebug(true)` is enabled. Remove any `getLastError()` calls.
|
||||
|
||||
**Before:**
|
||||
```cpp
|
||||
if (!victron.begin(2)) {
|
||||
Serial.println(victron.getLastError());
|
||||
}
|
||||
```
|
||||
|
||||
**After:**
|
||||
```cpp
|
||||
if (!victron.begin(2)) {
|
||||
Serial.println("Failed to initialize VictronBLE!");
|
||||
}
|
||||
```
|
||||
|
||||
### 5. String types
|
||||
|
||||
Device name and MAC are now `char[]` instead of Arduino `String`. Use `Serial.printf()` or `String(dev->name)` if you need a String object.
|
||||
|
||||
### 6. addDevice() parameters
|
||||
|
||||
Parameters changed from `String` to `const char*`. Existing string literals work unchanged. `VictronDeviceConfig` struct is no longer needed.
|
||||
|
||||
```cpp
|
||||
// Both v0.3 and v0.4 - string literals work the same
|
||||
victron.addDevice("MySolar", "f69dfcce55eb",
|
||||
"bf25c098c156afd6a180157b8a3ab1fb", DEVICE_TYPE_SOLAR_CHARGER);
|
||||
```
|
||||
@@ -160,7 +160,7 @@ void setup() {
|
||||
while (1) delay(1000);
|
||||
}
|
||||
|
||||
victron.setDebug(false);
|
||||
victron.setDebug(true);
|
||||
victron.setCallback(onVictronData);
|
||||
|
||||
// Replace with your own devices (MAC + 32-char hex key from VictronConnect)
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "victronble",
|
||||
"version": "0.6.0",
|
||||
"description": "Portable Arduino library for reading Victron Energy device data via Bluetooth Low Energy (BLE) advertisements. Runs on ESP32 and nRF52840. Supports SmartSolar MPPT, SmartShunt, BMV, MultiPlus, Orion, Blue Smart AC chargers and other Victron devices. No external crypto dependency.",
|
||||
"keywords": "victron, ble, bluetooth, solar, mppt, battery, smartshunt, smartsolar, bmv, inverter, multiplus, esp32, nrf52, nrf52840, xiao, iot, energy, monitoring",
|
||||
"description": "Portable Arduino library for reading Victron Energy device data via Bluetooth Low Energy (BLE) advertisements. Runs on ESP32, ESP32-S3, ESP32-C3 and nRF52 (nRF52840, nRF52832). Supports SmartSolar MPPT, SmartShunt, BMV, MultiPlus, Orion, Blue Smart AC chargers and other Victron devices. No external crypto dependency.",
|
||||
"keywords": "victron, ble, bluetooth, solar, mppt, battery, smartshunt, smartsolar, bmv, inverter, multiplus, esp32, esp32-s3, esp32-c3, nrf52, nrf52840, nrf52832, xiao, iot, energy, monitoring",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitea.sh3d.com.au/Sh3d/VictronBLE.git"
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ name=VictronBLE
|
||||
version=0.6.0
|
||||
author=Scott Penrose
|
||||
maintainer=Scott Penrose <scottp@dd.com.au>
|
||||
sentence=Portable library for reading Victron Energy device data via BLE on ESP32 and nRF52840
|
||||
paragraph=Read data from Victron SmartSolar, SmartShunt, BMV, inverters, Blue Smart AC chargers and other devices using Bluetooth Low Energy advertisements. Runs on ESP32 and nRF52840 (Bluefruit) with no external crypto dependency. Supports multiple devices simultaneously with no pairing required.
|
||||
sentence=Portable library for reading Victron Energy device data via BLE on ESP32/S3/C3 and nRF52 (nRF52840/nRF52832)
|
||||
paragraph=Read data from Victron SmartSolar, SmartShunt, BMV, inverters, Blue Smart AC chargers and other devices using Bluetooth Low Energy advertisements. Runs on ESP32, ESP32-S3, ESP32-C3 and nRF52 (nRF52840, nRF52832 — Bluefruit or Seeed cores) with no external crypto dependency. Supports multiple devices simultaneously with no pairing required.
|
||||
category=Communication
|
||||
url=https://gitea.sh3d.com.au/Sh3d/VictronBLE
|
||||
architectures=esp32,nrf52
|
||||
|
||||
@@ -53,6 +53,15 @@ void VictronBLEAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice advertise
|
||||
}
|
||||
|
||||
void VictronBLE::processDevice(BLEAdvertisedDevice& advertisedDevice) {
|
||||
// Debug: print every BLE device seen (before any filtering)
|
||||
if (debugEnabled) {
|
||||
Serial.printf("[VictronBLE] MAC=%-17s RSSI=%-4d Name=%-20s ManData=%s\n",
|
||||
advertisedDevice.getAddress().toString().c_str(),
|
||||
advertisedDevice.getRSSI(),
|
||||
advertisedDevice.haveName() ? advertisedDevice.getName().c_str() : "(none)",
|
||||
advertisedDevice.haveManufacturerData() ? "yes" : "no");
|
||||
}
|
||||
|
||||
if (!advertisedDevice.haveManufacturerData()) return;
|
||||
|
||||
// getManufacturerData() returns std::string on older ESP32 BLE libraries and
|
||||
|
||||
@@ -43,18 +43,39 @@ void VictronBLE::loop() {
|
||||
|
||||
void VictronBLE::scanCallback(ble_gap_evt_adv_report_t* report) {
|
||||
if (s_instance) {
|
||||
// Format MAC (little-endian to big-endian hex)
|
||||
const uint8_t* a = report->peer_addr.addr;
|
||||
char mac[18];
|
||||
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
a[5], a[4], a[3], a[2], a[1], a[0]);
|
||||
|
||||
// Debug: print every BLE device seen (before any filtering)
|
||||
if (s_instance->debugEnabled) {
|
||||
// Manufacturer specific data (AD type 0xFF) — includes the 0x02E1 vendor ID
|
||||
uint8_t mfgBuf[31];
|
||||
uint8_t mfgLen = Bluefruit.Scanner.parseReportByType(
|
||||
report, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, mfgBuf, sizeof(mfgBuf));
|
||||
|
||||
// Try to get device name
|
||||
char nameBuf[32] = "(none)";
|
||||
uint8_t nameLen = Bluefruit.Scanner.parseReportByType(
|
||||
report, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, (uint8_t*)nameBuf, sizeof(nameBuf) - 1);
|
||||
if (nameLen == 0) {
|
||||
nameLen = Bluefruit.Scanner.parseReportByType(
|
||||
report, BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, (uint8_t*)nameBuf, sizeof(nameBuf) - 1);
|
||||
}
|
||||
if (nameLen > 0) nameBuf[nameLen] = '\0';
|
||||
|
||||
Serial.printf("[VictronBLE] MAC=%-17s RSSI=%-4d Name=%-20s ManData=%s\n",
|
||||
mac, report->rssi, nameBuf, mfgLen >= 2 ? "yes" : "no");
|
||||
}
|
||||
|
||||
// Manufacturer specific data (AD type 0xFF) — includes the 0x02E1 vendor ID
|
||||
uint8_t buf[31];
|
||||
uint8_t len = Bluefruit.Scanner.parseReportByType(
|
||||
report, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, buf, sizeof(buf));
|
||||
|
||||
if (len >= 2) {
|
||||
// peer_addr.addr is little-endian (LSB first); format big-endian to
|
||||
// match the AA:BB:CC:DD:EE:FF MAC users copy from VictronConnect.
|
||||
const uint8_t* a = report->peer_addr.addr;
|
||||
char mac[18];
|
||||
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
a[5], a[4], a[3], a[2], a[1], a[0]);
|
||||
s_instance->onAdvertisement(buf, len, mac, report->rssi);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user