Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions docs/companion_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,11 +587,12 @@ def parse_device_info(data):
**PACKET_BATTERY** (0x0C):
```
Byte 0: 0x0C
Bytes 1-2: Battery Level (16-bit little-endian, percentage 0-100)
Bytes 1-2: Battery Milli Volts (16-bit little-endian)

Optional (if data size > 3):
Bytes 3-6: Used Storage (32-bit little-endian, KB)
Bytes 7-10: Total Storage (32-bit little-endian, KB)
Bytes 11: Charging/External Power Flag (uint8, 0=no, 1=yes)
```

**Parsing Pseudocode**:
Expand All @@ -600,15 +601,18 @@ def parse_battery(data):
if len(data) < 3:
return None

level = int.from_bytes(data[1:3], 'little')
info = {'level': level}
milli_volts = int.from_bytes(data[1:3], 'little')
info = {'milli_volts': milli_volts}

if len(data) > 3:
if len(data) >= 11:
used_kb = int.from_bytes(data[3:7], 'little')
total_kb = int.from_bytes(data[7:11], 'little')
info['used_kb'] = used_kb
info['total_kb'] = total_kb

if len(data) >= 12:
info['is_charging'] = data[11] == 1

return info
```

Expand Down
6 changes: 5 additions & 1 deletion examples/companion_radio/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,15 +1309,19 @@ void MyMesh::handleCmdFrame(size_t len) {
}
board.reboot();
} else if (cmd_frame[0] == CMD_GET_BATT_AND_STORAGE) {
uint8_t reply[11];
uint8_t reply[12];
int i = 0;
reply[i++] = RESP_CODE_BATT_AND_STORAGE;
uint16_t battery_millivolts = board.getBattMilliVolts();
uint32_t used = _store->getStorageUsedKb();
uint32_t total = _store->getStorageTotalKb();
// Optional extra byte for companion clients:
// 0 = not externally powered, 1 = externally powered/charging source present.
uint8_t is_charging = board.isExternalPowered() ? 1 : 0;
memcpy(&reply[i], &battery_millivolts, 2); i += 2;
memcpy(&reply[i], &used, 4); i += 4;
memcpy(&reply[i], &total, 4); i += 4;
reply[i++] = is_charging;
_serial->writeFrame(reply, i);
} else if (cmd_frame[0] == CMD_EXPORT_PRIVATE_KEY) {
#if ENABLE_PRIVATE_KEY_EXPORT
Expand Down
21 changes: 20 additions & 1 deletion variants/t1000-e/T1000eBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,23 @@ void T1000eBoard::begin() {
Wire.begin();

delay(10); // give sx1262 some time to power up
}
}

bool T1000eBoard::isExternalPowered() {
// T1000-E exposes dedicated detect lines for external power and charge state.
// Use these first, then fall back to NRF52 USB VBUS detection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does NRF52 fallback provide us with anything? Wouldn't it always be false currently? :)

bool externalPowerDetected = false;
bool chargingDetected = false;

#ifdef EXT_PWR_DETECT
// EXT_PWR_DETECT is high when external power rail is present.
externalPowerDetected = digitalRead(EXT_PWR_DETECT) == HIGH;
#endif

#ifdef EXT_CHRG_DETECT
// Charge detect is typically active-low on PMIC status lines.
chargingDetected = digitalRead(EXT_CHRG_DETECT) == LOW;
#endif

return externalPowerDetected || chargingDetected || NRF52Board::isExternalPowered();
}
1 change: 1 addition & 0 deletions variants/t1000-e/T1000eBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class T1000eBoard : public NRF52BoardDCDC {
public:
T1000eBoard() : NRF52Board("T1000E_OTA") {}
void begin();
bool isExternalPowered() override;

uint16_t getBattMilliVolts() override {
#ifdef BATTERY_PIN
Expand Down