diff --git a/src/Power.cpp b/src/Power.cpp index e582807a64..c70cddba26 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -16,6 +16,8 @@ bool pmu_irq = false; Power *power; +using namespace meshtastic; + /** * If this board has a battery level sensor, set this to a valid implementation */ @@ -97,7 +99,7 @@ void Power::readPowerStatus() if (batteryLevel) { bool hasBattery = batteryLevel->isBatteryConnect(); int batteryVoltageMv = 0; - uint8_t batteryChargePercent = 0; + int8_t batteryChargePercent = 0; if (hasBattery) { batteryVoltageMv = batteryLevel->getBattVoltage(); // If the AXP192 returns a valid battery percentage, use it @@ -114,13 +116,18 @@ void Power::readPowerStatus() } // Notify any status instances that are observing us - const meshtastic::PowerStatus powerStatus = meshtastic::PowerStatus( - hasBattery, batteryLevel->isVBUSPlug(), batteryLevel->isChargeing(), batteryVoltageMv, batteryChargePercent); + const PowerStatus powerStatus = + PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse, + batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); newStatus.notifyObservers(&powerStatus); // If we have a battery at all and it is less than 10% full, force deep sleep if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) powerFSM.trigger(EVENT_LOW_BATTERY); + } else { + // No power sensing on this board - tell everyone else we have no idea what is happening + const PowerStatus powerStatus = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1); + newStatus.notifyObservers(&powerStatus); } } diff --git a/src/PowerStatus.h b/src/PowerStatus.h index f40d9445c1..f875f4f73d 100644 --- a/src/PowerStatus.h +++ b/src/PowerStatus.h @@ -1,103 +1,91 @@ #pragma once -#include #include "Status.h" #include "configuration.h" +#include -namespace meshtastic { - - /// Describes the state of the GPS system. - class PowerStatus : public Status +namespace meshtastic +{ + +/** + * A boolean where we have a third state of Unknown + */ +enum OptionalBool { OptFalse = 0, OptTrue = 1, OptUnknown = 2 }; + +/// Describes the state of the GPS system. +class PowerStatus : public Status +{ + + private: + CallbackObserver statusObserver = + CallbackObserver(this, &PowerStatus::updateStatus); + + /// Whether we have a battery connected + OptionalBool hasBattery = OptUnknown; + /// Battery voltage in mV, valid if haveBattery is true + int batteryVoltageMv; + /// Battery charge percentage, either read directly or estimated + int8_t batteryChargePercent; + /// Whether USB is connected + OptionalBool hasUSB = OptUnknown; + /// Whether we are charging the battery + OptionalBool isCharging = OptUnknown; + + public: + PowerStatus() { statusType = STATUS_TYPE_POWER; } + PowerStatus(OptionalBool hasBattery, OptionalBool hasUSB, OptionalBool isCharging, int batteryVoltageMv = -1, + int8_t batteryChargePercent = -1) + : Status() { + this->hasBattery = hasBattery; + this->hasUSB = hasUSB; + this->isCharging = isCharging; + this->batteryVoltageMv = batteryVoltageMv; + this->batteryChargePercent = batteryChargePercent; + } + PowerStatus(const PowerStatus &); + PowerStatus &operator=(const PowerStatus &); - private: - CallbackObserver statusObserver = CallbackObserver(this, &PowerStatus::updateStatus); - - /// Whether we have a battery connected - bool hasBattery; - /// Battery voltage in mV, valid if haveBattery is true - int batteryVoltageMv; - /// Battery charge percentage, either read directly or estimated - uint8_t batteryChargePercent; - /// Whether USB is connected - bool hasUSB; - /// Whether we are charging the battery - bool isCharging; - - public: + void observe(Observable *source) { statusObserver.observe(source); } - PowerStatus() { - statusType = STATUS_TYPE_POWER; - } - PowerStatus( bool hasBattery, bool hasUSB, bool isCharging, int batteryVoltageMv, uint8_t batteryChargePercent ) : Status() - { - this->hasBattery = hasBattery; - this->hasUSB = hasUSB; - this->isCharging = isCharging; - this->batteryVoltageMv = batteryVoltageMv; - this->batteryChargePercent = batteryChargePercent; - } - PowerStatus(const PowerStatus &); - PowerStatus &operator=(const PowerStatus &); - - void observe(Observable *source) - { - statusObserver.observe(source); - } + bool getHasBattery() const { return hasBattery == OptTrue; } - bool getHasBattery() const - { - return hasBattery; - } + bool getHasUSB() const { return hasUSB == OptTrue; } - bool getHasUSB() const - { - return hasUSB; - } + /// Can we even know if this board has USB power or not + bool knowsUSB() const { return hasUSB != OptUnknown; } - bool getIsCharging() const - { - return isCharging; - } + bool getIsCharging() const { return isCharging == OptTrue; } - int getBatteryVoltageMv() const - { - return batteryVoltageMv; - } + int getBatteryVoltageMv() const { return batteryVoltageMv; } - uint8_t getBatteryChargePercent() const - { - return batteryChargePercent; - } + uint8_t getBatteryChargePercent() const { return batteryChargePercent; } - bool matches(const PowerStatus *newStatus) const + bool matches(const PowerStatus *newStatus) const + { + return (newStatus->getHasBattery() != hasBattery || newStatus->getHasUSB() != hasUSB || + newStatus->getBatteryVoltageMv() != batteryVoltageMv); + } + int updateStatus(const PowerStatus *newStatus) + { + // Only update the status if values have actually changed + bool isDirty; { - return ( - newStatus->getHasBattery() != hasBattery || - newStatus->getHasUSB() != hasUSB || - newStatus->getBatteryVoltageMv() != batteryVoltageMv - ); + isDirty = matches(newStatus); + initialized = true; + hasBattery = newStatus->hasBattery; + batteryVoltageMv = newStatus->getBatteryVoltageMv(); + batteryChargePercent = newStatus->getBatteryChargePercent(); + hasUSB = newStatus->hasUSB; + isCharging = newStatus->isCharging; } - int updateStatus(const PowerStatus *newStatus) { - // Only update the status if values have actually changed - bool isDirty; - { - isDirty = matches(newStatus); - initialized = true; - hasBattery = newStatus->getHasBattery(); - batteryVoltageMv = newStatus->getBatteryVoltageMv(); - batteryChargePercent = newStatus->getBatteryChargePercent(); - hasUSB = newStatus->getHasUSB(); - isCharging = newStatus->getIsCharging(); - } - if(isDirty) { - DEBUG_MSG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent); - onNewStatus.notifyObservers(this); - } - return 0; + if (isDirty) { + DEBUG_MSG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent); + onNewStatus.notifyObservers(this); } + return 0; + } +}; - }; - -} +} // namespace meshtastic extern meshtastic::PowerStatus *powerStatus; diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 281737560f..3cf3e93f73 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -774,7 +774,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 // Display power status if (powerStatus->getHasBattery()) drawBattery(display, x, y + 2, imgBattery, powerStatus); - else + else if (powerStatus->knowsUSB()) display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower); // Display nodes status drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);