kopia lustrzana https://github.com/meshtastic/firmware
Refactored status handlers and merged
commit
f5b7c33d4e
|
@ -48,7 +48,6 @@ Items after the first final candidate release.
|
||||||
- split out the software update utility so other projects can use it. Have the appload specify the URL for downloads.
|
- split out the software update utility so other projects can use it. Have the appload specify the URL for downloads.
|
||||||
- read the PMU battery fault indicators and blink/led/warn user on screen
|
- read the PMU battery fault indicators and blink/led/warn user on screen
|
||||||
- discard very old nodedb records (> 1wk)
|
- discard very old nodedb records (> 1wk)
|
||||||
- add a watchdog timer
|
|
||||||
- handle millis() rollover in GPS.getTime - otherwise we will break after 50 days
|
- handle millis() rollover in GPS.getTime - otherwise we will break after 50 days
|
||||||
- report esp32 device code bugs back to the mothership via android
|
- report esp32 device code bugs back to the mothership via android
|
||||||
- change BLE bonding to something more secure. see comment by pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND)
|
- change BLE bonding to something more secure. see comment by pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND)
|
||||||
|
|
157
src/GPSStatus.h
157
src/GPSStatus.h
|
@ -1,79 +1,108 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "lock.h"
|
#include "Status.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
namespace meshtastic {
|
namespace meshtastic {
|
||||||
|
|
||||||
/// Describes the state of the GPS system.
|
/// Describes the state of the GPS system.
|
||||||
struct GPSStatus
|
class GPSStatus : public Status
|
||||||
{
|
|
||||||
|
|
||||||
bool isDirty = false;
|
|
||||||
bool hasLock = false; // default to false, until we complete our first read
|
|
||||||
bool isConnected = false; // Do we have a GPS we are talking to
|
|
||||||
|
|
||||||
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
|
|
||||||
int32_t altitude = 0;
|
|
||||||
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs scaling before use)
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class GPSStatusHandler
|
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
|
||||||
GPSStatus status;
|
|
||||||
CallbackObserver<GPSStatusHandler, const GPSStatus> gpsObserver = CallbackObserver<GPSStatusHandler, const GPSStatus>(this, &GPSStatusHandler::updateStatus);
|
|
||||||
bool initialized = false;
|
|
||||||
/// Protects all of internal state.
|
|
||||||
Lock lock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Observable<void *> onNewStatus;
|
|
||||||
|
|
||||||
void observe(Observable<const GPSStatus> *source)
|
|
||||||
{
|
{
|
||||||
gpsObserver.observe(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInitialized() { LockGuard guard(&lock); return initialized; }
|
private:
|
||||||
bool hasLock() { LockGuard guard(&lock); return status.hasLock; }
|
CallbackObserver<GPSStatus, const GPSStatus *> statusObserver = CallbackObserver<GPSStatus, const GPSStatus *>(this, &GPSStatus::updateStatus);
|
||||||
bool isConnected() { LockGuard guard(&lock); return status.isConnected; }
|
|
||||||
int32_t getLatitude() { LockGuard guard(&lock); return status.latitude; }
|
|
||||||
int32_t getLongitude() { LockGuard guard(&lock); return status.longitude; }
|
|
||||||
int32_t getAltitude() { LockGuard guard(&lock); return status.altitude; }
|
|
||||||
uint32_t getDOP() { LockGuard guard(&lock); return status.dop; }
|
|
||||||
|
|
||||||
int updateStatus(const GPSStatus newStatus) {
|
bool hasLock = false; // default to false, until we complete our first read
|
||||||
// Only update the status if values have actually changed
|
bool isConnected = false; // Do we have a GPS we are talking to
|
||||||
status.isDirty = (
|
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
|
||||||
newStatus.hasLock != status.hasLock ||
|
int32_t altitude = 0;
|
||||||
newStatus.isConnected != status.isConnected ||
|
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs scaling before use)
|
||||||
newStatus.latitude != status.latitude ||
|
|
||||||
newStatus.longitude != status.longitude ||
|
public:
|
||||||
newStatus.altitude != status.altitude ||
|
|
||||||
newStatus.dop != status.latitude
|
GPSStatus() {
|
||||||
);
|
statusType = STATUS_TYPE_GPS;
|
||||||
|
}
|
||||||
|
GPSStatus( bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop ) : Status()
|
||||||
{
|
{
|
||||||
LockGuard guard(&lock);
|
this->hasLock = hasLock;
|
||||||
initialized = true;
|
this->isConnected = isConnected;
|
||||||
status.hasLock = newStatus.hasLock;
|
this->latitude = latitude;
|
||||||
status.isConnected = newStatus.isConnected;
|
this->longitude = longitude;
|
||||||
status.latitude = newStatus.latitude;
|
this->altitude = altitude;
|
||||||
status.longitude = newStatus.longitude;
|
this->dop = dop;
|
||||||
status.altitude = newStatus.altitude;
|
|
||||||
status.dop = newStatus.dop;
|
|
||||||
}
|
}
|
||||||
if(status.isDirty) {
|
GPSStatus(const GPSStatus &);
|
||||||
DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f\n", status.latitude * 1e-7, status.longitude * 1e-7, status.altitude, status.dop * 1e-2);
|
GPSStatus &operator=(const GPSStatus &);
|
||||||
onNewStatus.notifyObservers(NULL);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
void observe(Observable<const GPSStatus *> *source)
|
||||||
|
{
|
||||||
|
statusObserver.observe(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getHasLock() const
|
||||||
|
{
|
||||||
|
return hasLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getIsConnected() const
|
||||||
|
{
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getLatitude() const
|
||||||
|
{
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getLongitude() const
|
||||||
|
{
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getAltitude() const
|
||||||
|
{
|
||||||
|
return altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getDOP() const
|
||||||
|
{
|
||||||
|
return dop;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matches(const GPSStatus *newStatus) const
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
newStatus->hasLock != hasLock ||
|
||||||
|
newStatus->isConnected != isConnected ||
|
||||||
|
newStatus->latitude != latitude ||
|
||||||
|
newStatus->longitude != longitude ||
|
||||||
|
newStatus->altitude != altitude ||
|
||||||
|
newStatus->dop != dop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
int updateStatus(const GPSStatus *newStatus) {
|
||||||
|
// Only update the status if values have actually changed
|
||||||
|
bool isDirty;
|
||||||
|
{
|
||||||
|
isDirty = matches(newStatus);
|
||||||
|
initialized = true;
|
||||||
|
hasLock = newStatus->hasLock;
|
||||||
|
isConnected = newStatus->isConnected;
|
||||||
|
latitude = newStatus->latitude;
|
||||||
|
longitude = newStatus->longitude;
|
||||||
|
altitude = newStatus->altitude;
|
||||||
|
dop = newStatus->dop;
|
||||||
|
}
|
||||||
|
if(isDirty) {
|
||||||
|
DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f\n", latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2);
|
||||||
|
onNewStatus.notifyObservers(this);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern meshtastic::GPSStatus gpsStatus;
|
extern meshtastic::GPSStatus *gpsStatus;
|
107
src/NodeStatus.h
107
src/NodeStatus.h
|
@ -1,62 +1,73 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "lock.h"
|
#include "Status.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
namespace meshtastic {
|
namespace meshtastic {
|
||||||
|
|
||||||
/// Describes the state of the GPS system.
|
/// Describes the state of the NodeDB system.
|
||||||
struct NodeStatus
|
class NodeStatus : public Status
|
||||||
{
|
|
||||||
|
|
||||||
bool isDirty = false;
|
|
||||||
size_t numOnline; // Number of nodes online
|
|
||||||
size_t numTotal; // Number of nodes total
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class NodeStatusHandler
|
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
|
||||||
NodeStatus status;
|
|
||||||
CallbackObserver<NodeStatusHandler, const NodeStatus> nodeObserver = CallbackObserver<NodeStatusHandler, const NodeStatus>(this, &NodeStatusHandler::updateStatus);
|
|
||||||
bool initialized = false;
|
|
||||||
/// Protects all of internal state.
|
|
||||||
Lock lock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Observable<void *> onNewStatus;
|
|
||||||
|
|
||||||
void observe(Observable<const NodeStatus> *source)
|
|
||||||
{
|
{
|
||||||
nodeObserver.observe(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInitialized() const { return initialized; }
|
private:
|
||||||
size_t getNumOnline() const { return status.numOnline; }
|
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver = CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
|
||||||
size_t getNumTotal() const { return status.numTotal; }
|
|
||||||
|
|
||||||
int updateStatus(const NodeStatus newStatus)
|
uint8_t numOnline = 0;
|
||||||
{
|
uint8_t numTotal = 0;
|
||||||
// Only update the status if values have actually changed
|
|
||||||
status.isDirty = (
|
public:
|
||||||
newStatus.numOnline != status.numOnline ||
|
|
||||||
newStatus.numTotal != status.numTotal
|
NodeStatus() {
|
||||||
);
|
statusType = STATUS_TYPE_NODE;
|
||||||
LockGuard guard(&lock);
|
|
||||||
initialized = true;
|
|
||||||
status.numOnline = newStatus.numOnline;
|
|
||||||
status.numTotal = newStatus.numTotal;
|
|
||||||
if(status.isDirty) {
|
|
||||||
DEBUG_MSG("Node status update: %d online, %d total\n", status.numOnline, status.numTotal);
|
|
||||||
onNewStatus.notifyObservers(NULL);
|
|
||||||
}
|
}
|
||||||
return 0;
|
NodeStatus( uint8_t numOnline, uint8_t numTotal ) : Status()
|
||||||
}
|
{
|
||||||
|
this->numOnline = numOnline;
|
||||||
|
this->numTotal = numTotal;
|
||||||
|
}
|
||||||
|
NodeStatus(const NodeStatus &);
|
||||||
|
NodeStatus &operator=(const NodeStatus &);
|
||||||
|
|
||||||
};
|
void observe(Observable<const NodeStatus *> *source)
|
||||||
|
{
|
||||||
|
statusObserver.observe(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getNumOnline() const
|
||||||
|
{
|
||||||
|
return numOnline;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getNumTotal() const
|
||||||
|
{
|
||||||
|
return numTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matches(const NodeStatus *newStatus) const
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
newStatus->getNumOnline() != numOnline ||
|
||||||
|
newStatus->getNumTotal() != numTotal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
int updateStatus(const NodeStatus *newStatus) {
|
||||||
|
// Only update the status if values have actually changed
|
||||||
|
bool isDirty;
|
||||||
|
{
|
||||||
|
isDirty = matches(newStatus);
|
||||||
|
initialized = true;
|
||||||
|
numOnline = newStatus->getNumOnline();
|
||||||
|
numTotal = newStatus->getNumTotal();
|
||||||
|
}
|
||||||
|
if(isDirty) {
|
||||||
|
DEBUG_MSG("Node status update: %d online, %d total\n", numOnline, numTotal);
|
||||||
|
onNewStatus.notifyObservers(this);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern meshtastic::NodeStatus nodeStatus;
|
extern meshtastic::NodeStatus *nodeStatus;
|
|
@ -30,25 +30,27 @@ bool Power::setup()
|
||||||
// TODO(girts): move this and other axp stuff to power.h/power.cpp.
|
// TODO(girts): move this and other axp stuff to power.h/power.cpp.
|
||||||
void Power::readPowerStatus()
|
void Power::readPowerStatus()
|
||||||
{
|
{
|
||||||
meshtastic::PowerStatus status;
|
bool hasBattery = axp.isBatteryConnect();
|
||||||
status.hasBattery = axp.isBatteryConnect();
|
int batteryVoltageMv = 0;
|
||||||
if (status.hasBattery) {
|
uint8_t batteryChargePercent = 0;
|
||||||
status.batteryVoltageMv = axp.getBattVoltage();
|
if (hasBattery) {
|
||||||
|
batteryVoltageMv = axp.getBattVoltage();
|
||||||
// If the AXP192 returns a valid battery percentage, use it
|
// If the AXP192 returns a valid battery percentage, use it
|
||||||
if (axp.getBattPercentage() >= 0) {
|
if (axp.getBattPercentage() >= 0) {
|
||||||
status.batteryChargePercent = axp.getBattPercentage();
|
batteryChargePercent = axp.getBattPercentage();
|
||||||
} else {
|
} else {
|
||||||
// If the AXP192 returns a percentage less than 0, the feature is either not supported or there is an error
|
// If the AXP192 returns a percentage less than 0, the feature is either not supported or there is an error
|
||||||
// In that case, we compute an estimate of the charge percent based on maximum and minimum voltages defined in power.h
|
// In that case, we compute an estimate of the charge percent based on maximum and minimum voltages defined in power.h
|
||||||
status.batteryChargePercent = clamp((int)(((status.batteryVoltageMv - BAT_MILLIVOLTS_EMPTY) * 1e2) / (BAT_MILLIVOLTS_FULL - BAT_MILLIVOLTS_EMPTY)), 0, 100);
|
batteryChargePercent = clamp((int)(((batteryVoltageMv - BAT_MILLIVOLTS_EMPTY) * 1e2) / (BAT_MILLIVOLTS_FULL - BAT_MILLIVOLTS_EMPTY)), 0, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status.hasUSB = axp.isVBUSPlug();
|
|
||||||
status.isCharging = axp.isChargeing();
|
// Notify any status instances that are observing us
|
||||||
newStatus.notifyObservers(status);
|
const meshtastic::PowerStatus powerStatus = meshtastic::PowerStatus(hasBattery, axp.isVBUSPlug(), axp.isChargeing(), batteryVoltageMv, batteryChargePercent);
|
||||||
|
newStatus.notifyObservers(&powerStatus);
|
||||||
|
|
||||||
// If we have a battery at all and it is less than 10% full, force deep sleep
|
// If we have a battery at all and it is less than 10% full, force deep sleep
|
||||||
if (status.hasBattery && !status.hasUSB &&
|
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() &&
|
||||||
axp.getBattVoltage() < MIN_BAT_MILLIVOLTS)
|
axp.getBattVoltage() < MIN_BAT_MILLIVOLTS)
|
||||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +1,103 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "lock.h"
|
#include <Arduino.h>
|
||||||
|
#include "Status.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
namespace meshtastic
|
namespace meshtastic {
|
||||||
{
|
|
||||||
|
|
||||||
/// Describes the state of the power system.
|
/// Describes the state of the GPS system.
|
||||||
struct PowerStatus
|
class PowerStatus : public Status
|
||||||
{
|
|
||||||
|
|
||||||
/// Whether or not values have changed since last read
|
|
||||||
bool isDirty = false;
|
|
||||||
/// 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
|
|
||||||
int batteryChargePercent;
|
|
||||||
/// Whether USB is connected
|
|
||||||
bool hasUSB;
|
|
||||||
/// Whether we are charging the battery
|
|
||||||
bool isCharging;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class PowerStatusHandler
|
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
|
||||||
PowerStatus status;
|
|
||||||
CallbackObserver<PowerStatusHandler, const PowerStatus> powerObserver = CallbackObserver<PowerStatusHandler, const PowerStatus>(this, &PowerStatusHandler::updateStatus);
|
|
||||||
bool initialized = false;
|
|
||||||
/// Protects all of internal state.
|
|
||||||
Lock lock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Observable<void *> onNewStatus;
|
|
||||||
|
|
||||||
void observe(Observable<const PowerStatus> *source)
|
|
||||||
{
|
{
|
||||||
powerObserver.observe(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInitialized() { LockGuard guard(&lock); return initialized; }
|
private:
|
||||||
bool isCharging() { LockGuard guard(&lock); return status.isCharging; }
|
CallbackObserver<PowerStatus, const PowerStatus *> statusObserver = CallbackObserver<PowerStatus, const PowerStatus *>(this, &PowerStatus::updateStatus);
|
||||||
bool hasUSB() { LockGuard guard(&lock); return status.hasUSB; }
|
|
||||||
bool hasBattery() { LockGuard guard(&lock); return status.hasBattery; }
|
|
||||||
int getBatteryVoltageMv() { LockGuard guard(&lock); return status.batteryVoltageMv; }
|
|
||||||
int getBatteryChargePercent() { LockGuard guard(&lock); return status.batteryChargePercent; }
|
|
||||||
|
|
||||||
int updateStatus(const PowerStatus newStatus) {
|
/// Whether we have a battery connected
|
||||||
// Only update the status if values have actually changed
|
bool hasBattery;
|
||||||
status.isDirty = (
|
/// Battery voltage in mV, valid if haveBattery is true
|
||||||
newStatus.hasBattery != status.hasBattery ||
|
int batteryVoltageMv;
|
||||||
newStatus.hasUSB != status.hasUSB ||
|
/// Battery charge percentage, either read directly or estimated
|
||||||
newStatus.batteryVoltageMv != status.batteryVoltageMv
|
uint8_t batteryChargePercent;
|
||||||
);
|
/// Whether USB is connected
|
||||||
LockGuard guard(&lock);
|
bool hasUSB;
|
||||||
initialized = true;
|
/// Whether we are charging the battery
|
||||||
status.hasBattery = newStatus.hasBattery;
|
bool isCharging;
|
||||||
status.batteryVoltageMv = newStatus.batteryVoltageMv;
|
|
||||||
status.batteryChargePercent = newStatus.batteryChargePercent;
|
public:
|
||||||
status.hasUSB = newStatus.hasUSB;
|
|
||||||
status.isCharging = newStatus.isCharging;
|
PowerStatus() {
|
||||||
if(status.isDirty) {
|
statusType = STATUS_TYPE_POWER;
|
||||||
DEBUG_MSG("Battery %dmV %d%%\n", status.batteryVoltageMv, status.batteryChargePercent);
|
|
||||||
onNewStatus.notifyObservers(this);
|
|
||||||
}
|
}
|
||||||
return 0;
|
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 &);
|
||||||
|
|
||||||
} // namespace meshtastic
|
void observe(Observable<const PowerStatus *> *source)
|
||||||
|
{
|
||||||
|
statusObserver.observe(source);
|
||||||
|
}
|
||||||
|
|
||||||
extern meshtastic::PowerStatus powerStatus;
|
bool getHasBattery() const
|
||||||
|
{
|
||||||
|
return hasBattery;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getHasUSB() const
|
||||||
|
{
|
||||||
|
return hasUSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getIsCharging() const
|
||||||
|
{
|
||||||
|
return isCharging;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getBatteryVoltageMv() const
|
||||||
|
{
|
||||||
|
return batteryVoltageMv;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getBatteryChargePercent() const
|
||||||
|
{
|
||||||
|
return batteryChargePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern meshtastic::PowerStatus *powerStatus;
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Observer.h"
|
||||||
|
|
||||||
|
// Constants for the various status types, so we can tell subclass instances apart
|
||||||
|
#define STATUS_TYPE_BASE 0
|
||||||
|
#define STATUS_TYPE_POWER 1
|
||||||
|
#define STATUS_TYPE_GPS 2
|
||||||
|
#define STATUS_TYPE_NODE 3
|
||||||
|
|
||||||
|
|
||||||
|
namespace meshtastic
|
||||||
|
{
|
||||||
|
|
||||||
|
// A base class for observable status
|
||||||
|
class Status
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// Allows us to observe an Observable
|
||||||
|
CallbackObserver<Status, const Status *> statusObserver = CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
|
||||||
|
bool initialized = false;
|
||||||
|
// Workaround for no typeid support
|
||||||
|
int statusType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Allows us to generate observable events
|
||||||
|
Observable<const Status *> onNewStatus;
|
||||||
|
|
||||||
|
// Enable polymorphism ?
|
||||||
|
virtual ~Status() = default;
|
||||||
|
|
||||||
|
Status() {
|
||||||
|
if (!statusType)
|
||||||
|
{
|
||||||
|
statusType = STATUS_TYPE_BASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent object copy/move
|
||||||
|
Status(const Status &) = delete;
|
||||||
|
Status &operator=(const Status &) = delete;
|
||||||
|
|
||||||
|
// Start observing a source of data
|
||||||
|
void observe(Observable<const Status *> *source)
|
||||||
|
{
|
||||||
|
statusObserver.observe(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines whether or not existing data matches the data in another Status instance
|
||||||
|
bool matches(const Status *otherStatus) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isInitialized() const
|
||||||
|
{
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getStatusType() const
|
||||||
|
{
|
||||||
|
return statusType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the Observable we're observing generates a new notification
|
||||||
|
int updateStatus(const Status *newStatus)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
|
@ -17,8 +17,15 @@ void Thread::callRun(void *_this)
|
||||||
|
|
||||||
void WorkerThread::doRun()
|
void WorkerThread::doRun()
|
||||||
{
|
{
|
||||||
|
startWatchdog();
|
||||||
|
|
||||||
while (!wantExit) {
|
while (!wantExit) {
|
||||||
|
stopWatchdog();
|
||||||
block();
|
block();
|
||||||
|
startWatchdog();
|
||||||
|
|
||||||
|
// no need - startWatchdog is guaranteed to give us one full watchdog interval
|
||||||
|
// serviceWatchdog(); // Let our loop worker have one full watchdog interval (at least) to run
|
||||||
|
|
||||||
#ifdef DEBUG_STACK
|
#ifdef DEBUG_STACK
|
||||||
static uint32_t lastPrint = 0;
|
static uint32_t lastPrint = 0;
|
||||||
|
@ -30,6 +37,8 @@ void WorkerThread::doRun()
|
||||||
|
|
||||||
loop();
|
loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopWatchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <Arduino.h>
|
#include "esp_task_wdt.h"
|
||||||
#include "freertosinc.h"
|
#include "freertosinc.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
#ifdef HAS_FREE_RTOS
|
#ifdef HAS_FREE_RTOS
|
||||||
|
|
||||||
|
@ -26,6 +27,23 @@ class Thread
|
||||||
*/
|
*/
|
||||||
virtual void doRun() = 0;
|
virtual void doRun() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All thread run methods must periodically call serviceWatchdog, or the system will declare them hung and panic.
|
||||||
|
*
|
||||||
|
* this only applies after startWatchdog() has been called. If you need to sleep for a long time call stopWatchdog()
|
||||||
|
*/
|
||||||
|
void serviceWatchdog() { esp_task_wdt_reset(); }
|
||||||
|
void startWatchdog()
|
||||||
|
{
|
||||||
|
auto r = esp_task_wdt_add(taskHandle);
|
||||||
|
assert(r == ESP_OK);
|
||||||
|
}
|
||||||
|
void stopWatchdog()
|
||||||
|
{
|
||||||
|
auto r = esp_task_wdt_delete(taskHandle);
|
||||||
|
assert(r == ESP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void callRun(void *_this);
|
static void callRun(void *_this);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
#include "MeshBluetoothService.h"
|
#include "MeshBluetoothService.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "esp_task_wdt.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
bool bluetoothOn;
|
bool bluetoothOn;
|
||||||
|
|
||||||
|
@ -84,6 +85,15 @@ void esp32Setup()
|
||||||
|
|
||||||
// enableModemSleep();
|
// enableModemSleep();
|
||||||
|
|
||||||
|
// Since we are turning on watchdogs rather late in the release schedule, we really don't want to catch any
|
||||||
|
// false positives. The wait-to-sleep timeout for shutting down radios is 30 secs, so pick 45 for now.
|
||||||
|
#define APP_WATCHDOG_SECS 45
|
||||||
|
|
||||||
|
auto res = esp_task_wdt_init(APP_WATCHDOG_SECS, true);
|
||||||
|
assert(res == ESP_OK);
|
||||||
|
|
||||||
|
res = esp_task_wdt_add(NULL);
|
||||||
|
assert(res == ESP_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -106,10 +116,10 @@ uint32_t axpDebugRead()
|
||||||
Periodic axpDebugOutput(axpDebugRead);
|
Periodic axpDebugOutput(axpDebugRead);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// loop code specific to ESP32 targets
|
/// loop code specific to ESP32 targets
|
||||||
void esp32Loop()
|
void esp32Loop()
|
||||||
{
|
{
|
||||||
|
esp_task_wdt_reset(); // service our app level watchdog
|
||||||
loopBLE();
|
loopBLE();
|
||||||
|
|
||||||
// for debug printing
|
// for debug printing
|
||||||
|
|
|
@ -41,7 +41,7 @@ class GPS : public Observable<void *>
|
||||||
|
|
||||||
virtual ~GPS() {}
|
virtual ~GPS() {}
|
||||||
|
|
||||||
Observable<const meshtastic::GPSStatus> newStatus;
|
Observable<const meshtastic::GPSStatus *> newStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if we succeeded
|
* Returns true if we succeeded
|
||||||
|
|
|
@ -65,13 +65,9 @@ void NEMAGPS::loop()
|
||||||
if (hasValidLocation)
|
if (hasValidLocation)
|
||||||
notifyObservers(NULL);
|
notifyObservers(NULL);
|
||||||
}
|
}
|
||||||
meshtastic::GPSStatus status;
|
|
||||||
status.hasLock = hasLock();
|
// Notify any status instances that are observing us
|
||||||
status.isConnected = isConnected;
|
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop);
|
||||||
status.latitude = latitude;
|
newStatus.notifyObservers(&status);
|
||||||
status.longitude = longitude;
|
|
||||||
status.altitude = altitude;
|
|
||||||
status.dop = dop;
|
|
||||||
newStatus.notifyObservers(status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -128,14 +128,9 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
||||||
} else // we didn't get a location update, go back to sleep and hope the characters show up
|
} else // we didn't get a location update, go back to sleep and hope the characters show up
|
||||||
wantNewLocation = true;
|
wantNewLocation = true;
|
||||||
|
|
||||||
meshtastic::GPSStatus status;
|
// Notify any status instances that are observing us
|
||||||
status.hasLock = hasLock();
|
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop);
|
||||||
status.isConnected = isConnected;
|
newStatus.notifyObservers(&status);
|
||||||
status.latitude = latitude;
|
|
||||||
status.longitude = longitude;
|
|
||||||
status.altitude = altitude;
|
|
||||||
status.dop = dop;
|
|
||||||
newStatus.notifyObservers(status);
|
|
||||||
|
|
||||||
// Once we have sent a location once we only poll the GPS rarely, otherwise check back every 1s until we have something over
|
// Once we have sent a location once we only poll the GPS rarely, otherwise check back every 1s until we have something over
|
||||||
// the serial
|
// the serial
|
||||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -57,13 +57,13 @@
|
||||||
meshtastic::Screen screen(SSD1306_ADDRESS);
|
meshtastic::Screen screen(SSD1306_ADDRESS);
|
||||||
|
|
||||||
// Global power status
|
// Global power status
|
||||||
meshtastic::PowerStatusHandler *powerStatusHandler = new meshtastic::PowerStatusHandler();
|
meshtastic::PowerStatus *powerStatus = new meshtastic::PowerStatus();
|
||||||
|
|
||||||
// Global GPS status
|
// Global GPS status
|
||||||
meshtastic::GPSStatusHandler *gpsStatusHandler = new meshtastic::GPSStatusHandler();
|
meshtastic::GPSStatus *gpsStatus = new meshtastic::GPSStatus();
|
||||||
|
|
||||||
// Global Node status
|
// Global Node status
|
||||||
meshtastic::NodeStatusHandler *nodeStatusHandler = new meshtastic::NodeStatusHandler();
|
meshtastic::NodeStatus *nodeStatus = new meshtastic::NodeStatus();
|
||||||
|
|
||||||
bool ssd1306_found;
|
bool ssd1306_found;
|
||||||
bool axp192_found;
|
bool axp192_found;
|
||||||
|
@ -127,7 +127,7 @@ static uint32_t ledBlinker()
|
||||||
setLed(ledOn);
|
setLed(ledOn);
|
||||||
|
|
||||||
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
||||||
return powerStatusHandler->isCharging() ? 1000 : (ledOn ? 2 : 1000);
|
return powerStatus->getIsCharging() ? 1000 : (ledOn ? 2 : 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic ledPeriodic(ledBlinker);
|
Periodic ledPeriodic(ledBlinker);
|
||||||
|
@ -231,8 +231,8 @@ void setup()
|
||||||
esp32Setup();
|
esp32Setup();
|
||||||
power = new Power();
|
power = new Power();
|
||||||
power->setup();
|
power->setup();
|
||||||
power->setStatusHandler(powerStatusHandler);
|
power->setStatusHandler(powerStatus);
|
||||||
powerStatusHandler->observe(&power->newStatus);
|
powerStatus->observe(&power->newStatus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NRF52_SERIES
|
#ifdef NRF52_SERIES
|
||||||
|
@ -263,8 +263,8 @@ void setup()
|
||||||
gps = new NEMAGPS();
|
gps = new NEMAGPS();
|
||||||
gps->setup();
|
gps->setup();
|
||||||
#endif
|
#endif
|
||||||
gpsStatusHandler->observe(&gps->newStatus);
|
gpsStatus->observe(&gps->newStatus);
|
||||||
nodeStatusHandler->observe(&nodeDB.newStatus);
|
nodeStatus->observe(&nodeDB.newStatus);
|
||||||
|
|
||||||
service.init();
|
service.init();
|
||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
|
|
|
@ -12,11 +12,11 @@ extern bool isUSBPowered;
|
||||||
|
|
||||||
// Global Screen singleton.
|
// Global Screen singleton.
|
||||||
extern meshtastic::Screen screen;
|
extern meshtastic::Screen screen;
|
||||||
extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class
|
//extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class
|
||||||
|
|
||||||
extern meshtastic::PowerStatusHandler *powerStatusHandler;
|
//extern meshtastic::PowerStatus *powerStatus;
|
||||||
extern meshtastic::GPSStatusHandler *gpsStatusHandler;
|
//extern meshtastic::GPSStatus *gpsStatus;
|
||||||
extern meshtastic::NodeStatusHandler *nodeStatusHandler;
|
//extern meshtastic::NodeStatusHandler *nodeStatusHandler;
|
||||||
|
|
||||||
// Return a human readable string of the form "Meshtastic_ab13"
|
// Return a human readable string of the form "Meshtastic_ab13"
|
||||||
const char *getDeviceName();
|
const char *getDeviceName();
|
||||||
|
|
|
@ -303,7 +303,7 @@ int MeshService::onGPSChanged(void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include our current battery voltage in our position announcement
|
// Include our current battery voltage in our position announcement
|
||||||
pos.battery_level = powerStatusHandler->getBatteryChargePercent();
|
pos.battery_level = powerStatus->getBatteryChargePercent();
|
||||||
updateBatteryLevel(pos.battery_level);
|
updateBatteryLevel(pos.battery_level);
|
||||||
|
|
||||||
// We limit our GPS broadcasts to a max rate
|
// We limit our GPS broadcasts to a max rate
|
||||||
|
|
|
@ -34,7 +34,7 @@ class NodeDB
|
||||||
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled
|
bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled
|
||||||
NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
|
NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
|
||||||
bool updateTextMessage = false; // if true, the GUI should show a new text message
|
bool updateTextMessage = false; // if true, the GUI should show a new text message
|
||||||
Observable<const meshtastic::NodeStatus> newStatus;
|
Observable<const meshtastic::NodeStatus *> newStatus;
|
||||||
|
|
||||||
/// don't do mesh based algoritm for node id assignment (initially)
|
/// don't do mesh based algoritm for node id assignment (initially)
|
||||||
/// instead just store in flash - possibly even in the initial alpha release do this hack
|
/// instead just store in flash - possibly even in the initial alpha release do this hack
|
||||||
|
@ -97,10 +97,8 @@ class NodeDB
|
||||||
/// Notify observers of changes to the DB
|
/// Notify observers of changes to the DB
|
||||||
void notifyObservers() {
|
void notifyObservers() {
|
||||||
// Notify observers of the current node state
|
// Notify observers of the current node state
|
||||||
meshtastic::NodeStatus status;
|
const meshtastic::NodeStatus status = meshtastic::NodeStatus(getNumOnlineNodes(), getNumNodes());
|
||||||
status.numOnline = getNumOnlineNodes();
|
newStatus.notifyObservers(&status);
|
||||||
status.numTotal = getNumNodes();
|
|
||||||
newStatus.notifyObservers(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// read our db from flash
|
/// read our db from flash
|
||||||
|
|
|
@ -20,19 +20,19 @@ class Power : public PeriodicTask
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Observable<const meshtastic::PowerStatus> newStatus;
|
Observable<const meshtastic::PowerStatus *> newStatus;
|
||||||
|
|
||||||
void readPowerStatus();
|
void readPowerStatus();
|
||||||
void loop();
|
void loop();
|
||||||
virtual bool setup();
|
virtual bool setup();
|
||||||
virtual void doTask();
|
virtual void doTask();
|
||||||
void setStatusHandler(meshtastic::PowerStatusHandler *handler)
|
void setStatusHandler(meshtastic::PowerStatus *handler)
|
||||||
{
|
{
|
||||||
statusHandler = handler;
|
statusHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
meshtastic::PowerStatusHandler *statusHandler;
|
meshtastic::PowerStatus *statusHandler;
|
||||||
virtual void axp192Init();
|
virtual void axp192Init();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -177,7 +177,7 @@ static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char *
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Draw power bars or a charging indicator on an image of a battery, determined by battery charge voltage or percentage.
|
// Draw power bars or a charging indicator on an image of a battery, determined by battery charge voltage or percentage.
|
||||||
static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer, PowerStatusHandler *powerStatusHandler)
|
static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer, const PowerStatus *powerStatus)
|
||||||
{
|
{
|
||||||
static const uint8_t powerBar[3] = { 0x81, 0xBD, 0xBD };
|
static const uint8_t powerBar[3] = { 0x81, 0xBD, 0xBD };
|
||||||
static const uint8_t lightning[8] = { 0xA1, 0xA1, 0xA5, 0xAD, 0xB5, 0xA5, 0x85, 0x85 };
|
static const uint8_t lightning[8] = { 0xA1, 0xA1, 0xA5, 0xAD, 0xB5, 0xA5, 0x85, 0x85 };
|
||||||
|
@ -186,12 +186,12 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
|
||||||
imgBuffer[i] = 0x81;
|
imgBuffer[i] = 0x81;
|
||||||
}
|
}
|
||||||
// If charging, draw a charging indicator
|
// If charging, draw a charging indicator
|
||||||
if (powerStatusHandler->isCharging()) {
|
if (powerStatus->getIsCharging()) {
|
||||||
memcpy(imgBuffer + 3, lightning, 8);
|
memcpy(imgBuffer + 3, lightning, 8);
|
||||||
// If not charging, Draw power bars
|
// If not charging, Draw power bars
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if(powerStatusHandler->getBatteryChargePercent() >= 25 * i)
|
if(powerStatus->getBatteryChargePercent() >= 25 * i)
|
||||||
memcpy(imgBuffer + 1 + (i * 3), powerBar, 3);
|
memcpy(imgBuffer + 1 + (i * 3), powerBar, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,23 +199,23 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw nodes status
|
// Draw nodes status
|
||||||
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatusHandler *nodeStatusHandler)
|
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus)
|
||||||
{
|
{
|
||||||
char usersString[20];
|
char usersString[20];
|
||||||
sprintf(usersString, "%d/%d", nodeStatusHandler->getNumOnline(), nodeStatusHandler->getNumTotal());
|
sprintf(usersString, "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||||
display->drawFastImage(x, y, 8, 8, imgUser);
|
display->drawFastImage(x, y, 8, 8, imgUser);
|
||||||
display->drawString(x + 10, y - 2, usersString);
|
display->drawString(x + 10, y - 2, usersString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw GPS status summary
|
// Draw GPS status summary
|
||||||
static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, GPSStatusHandler *gps)
|
static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||||
{
|
{
|
||||||
if (!gps->isConnected()) {
|
if (!gps->getIsConnected()) {
|
||||||
display->drawString(x, y - 2, "No GPS");
|
display->drawString(x, y - 2, "No GPS");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
display->drawFastImage(x, y, 6, 8, gps->hasLock() ? imgPositionSolid : imgPositionEmpty);
|
display->drawFastImage(x, y, 6, 8, gps->getHasLock() ? imgPositionSolid : imgPositionEmpty);
|
||||||
if (!gps->hasLock()) {
|
if (!gps->getHasLock()) {
|
||||||
display->drawString(x + 8, y - 2, "No sats");
|
display->drawString(x + 8, y - 2, "No sats");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -581,9 +581,9 @@ void Screen::setup()
|
||||||
ui.update();
|
ui.update();
|
||||||
|
|
||||||
// Subscribe to status updates
|
// Subscribe to status updates
|
||||||
powerStatusObserver.observe(&powerStatusHandler->onNewStatus);
|
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
||||||
gpsStatusObserver.observe(&gpsStatusHandler->onNewStatus);
|
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
||||||
nodeStatusObserver.observe(&nodeStatusHandler->onNewStatus);
|
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::doTask()
|
void Screen::doTask()
|
||||||
|
@ -671,7 +671,7 @@ void Screen::setFrames()
|
||||||
showingNormalScreen = true;
|
showingNormalScreen = true;
|
||||||
|
|
||||||
// We don't show the node info our our node (if we have it yet - we should)
|
// We don't show the node info our our node (if we have it yet - we should)
|
||||||
size_t numnodes = nodeStatusHandler->getNumTotal();
|
size_t numnodes = nodeStatus->getNumTotal();
|
||||||
if (numnodes > 0)
|
if (numnodes > 0)
|
||||||
numnodes--;
|
numnodes--;
|
||||||
|
|
||||||
|
@ -751,14 +751,14 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||||
snprintf(channelStr, sizeof(channelStr), "#%s", channelName.c_str());
|
snprintf(channelStr, sizeof(channelStr), "#%s", channelName.c_str());
|
||||||
|
|
||||||
// Display power status
|
// Display power status
|
||||||
if (powerStatusHandler->hasBattery())
|
if (powerStatus->getHasBattery())
|
||||||
drawBattery(display, x, y + 2, imgBattery, powerStatusHandler);
|
drawBattery(display, x, y + 2, imgBattery, powerStatus);
|
||||||
else
|
else
|
||||||
display->drawFastImage(x, y + 2, 16, 8, powerStatusHandler->hasUSB() ? imgUSB : imgPower);
|
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
|
||||||
// Display nodes status
|
// Display nodes status
|
||||||
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatusHandler);
|
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);
|
||||||
// Display GPS status
|
// Display GPS status
|
||||||
drawGPS(display, x + (SCREEN_WIDTH * 0.66), y + 2, gpsStatusHandler);
|
drawGPS(display, x + (SCREEN_WIDTH * 0.66), y + 2, gpsStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
display->drawString(x, y + FONT_HEIGHT, channelStr);
|
display->drawString(x, y + FONT_HEIGHT, channelStr);
|
||||||
|
@ -784,19 +784,14 @@ void Screen::adjustBrightness()
|
||||||
dispdev.setBrightness(brightness);
|
dispdev.setBrightness(brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Screen::handlePowerStatusUpdate(void *arg) {
|
int Screen::handleStatusUpdate(const Status *arg) {
|
||||||
//DEBUG_MSG("Screen got power status update\n");
|
DEBUG_MSG("Screen got status update %d\n", arg->getStatusType());
|
||||||
setPeriod(1); // Update the screen right away
|
switch(arg->getStatusType())
|
||||||
return 0;
|
{
|
||||||
}
|
case STATUS_TYPE_NODE:
|
||||||
int Screen::handleGPSStatusUpdate(void *arg) {
|
setFrames();
|
||||||
//DEBUG_MSG("Screen got gps status update\n");
|
break;
|
||||||
setPeriod(1); // Update the screen right away
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int Screen::handleNodeStatusUpdate(void *arg) {
|
|
||||||
//DEBUG_MSG("Screen got node status update\n");
|
|
||||||
setFrames(); // Update our frames if the node database has changed
|
|
||||||
setPeriod(1); // Update the screen right away
|
setPeriod(1); // Update the screen right away
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
10
src/screen.h
10
src/screen.h
|
@ -62,9 +62,9 @@ class DebugInfo
|
||||||
// simultaneously).
|
// simultaneously).
|
||||||
class Screen : public PeriodicTask
|
class Screen : public PeriodicTask
|
||||||
{
|
{
|
||||||
CallbackObserver<Screen, void *> powerStatusObserver = CallbackObserver<Screen, void *>(this, &Screen::handlePowerStatusUpdate);
|
CallbackObserver<Screen, const Status *> powerStatusObserver = CallbackObserver<Screen, const Status *>(this, &Screen::handleStatusUpdate);
|
||||||
CallbackObserver<Screen, void *> gpsStatusObserver = CallbackObserver<Screen, void *>(this, &Screen::handleGPSStatusUpdate);
|
CallbackObserver<Screen, const Status *> gpsStatusObserver = CallbackObserver<Screen, const Status *>(this, &Screen::handleStatusUpdate);
|
||||||
CallbackObserver<Screen, void *> nodeStatusObserver = CallbackObserver<Screen, void *>(this, &Screen::handleNodeStatusUpdate);
|
CallbackObserver<Screen, const Status *> nodeStatusObserver = CallbackObserver<Screen, const Status *>(this, &Screen::handleStatusUpdate);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Screen(uint8_t address, int sda = -1, int scl = -1);
|
Screen(uint8_t address, int sda = -1, int scl = -1);
|
||||||
|
@ -162,9 +162,7 @@ class Screen : public PeriodicTask
|
||||||
// Use this handle to set things like battery status, user count, GPS status, etc.
|
// Use this handle to set things like battery status, user count, GPS status, etc.
|
||||||
DebugInfo *debug() { return &debugInfo; }
|
DebugInfo *debug() { return &debugInfo; }
|
||||||
|
|
||||||
int handlePowerStatusUpdate(void *arg);
|
int handleStatusUpdate(const meshtastic::Status *arg);
|
||||||
int handleGPSStatusUpdate(void *arg);
|
|
||||||
int handleNodeStatusUpdate(void *arg);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Updates the UI.
|
/// Updates the UI.
|
||||||
|
|
Ładowanie…
Reference in New Issue