Compare commits
2 Commits
53fa6fa0e1
...
nrf52
| Author | SHA1 | Date | |
|---|---|---|---|
| 05ee88cd31 | |||
| ef50829c81 |
@@ -320,3 +320,31 @@ cd3b462 ignore local
|
|||||||
- src/VictronBLE.h
|
- src/VictronBLE.h
|
||||||
- src/crypto/vble_aes.c
|
- 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**.
|
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.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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
-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);
|
while (1) delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
victron.setDebug(false);
|
victron.setDebug(true);
|
||||||
victron.setCallback(onVictronData);
|
victron.setCallback(onVictronData);
|
||||||
|
|
||||||
// Replace with your own devices (MAC + 32-char hex key from VictronConnect)
|
// Replace with your own devices (MAC + 32-char hex key from VictronConnect)
|
||||||
|
|||||||
@@ -53,6 +53,15 @@ void VictronBLEAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice advertise
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VictronBLE::processDevice(BLEAdvertisedDevice& advertisedDevice) {
|
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;
|
if (!advertisedDevice.haveManufacturerData()) return;
|
||||||
|
|
||||||
// getManufacturerData() returns std::string on older ESP32 BLE libraries and
|
// 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) {
|
void VictronBLE::scanCallback(ble_gap_evt_adv_report_t* report) {
|
||||||
if (s_instance) {
|
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
|
// Manufacturer specific data (AD type 0xFF) — includes the 0x02E1 vendor ID
|
||||||
uint8_t buf[31];
|
uint8_t buf[31];
|
||||||
uint8_t len = Bluefruit.Scanner.parseReportByType(
|
uint8_t len = Bluefruit.Scanner.parseReportByType(
|
||||||
report, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, buf, sizeof(buf));
|
report, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, buf, sizeof(buf));
|
||||||
|
|
||||||
if (len >= 2) {
|
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);
|
s_instance->onAdvertisement(buf, len, mac, report->rssi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user