sforkowany z mirror/meshtastic-firmware
track last contact times for nodes and show in gui
rodzic
9e5a960a04
commit
efa91f6767
1
TODO.md
1
TODO.md
|
@ -1,5 +1,6 @@
|
||||||
# High priority
|
# High priority
|
||||||
|
|
||||||
|
* after reboot, channel number is getting reset to zero! fix!
|
||||||
* have node info screen show real info (including time since last contact, distance and heading)
|
* have node info screen show real info (including time since last contact, distance and heading)
|
||||||
* make debug info screen show real data (including battery level & charging)
|
* make debug info screen show real data (including battery level & charging)
|
||||||
* make real implementation of getNumOnlineNodes
|
* make real implementation of getNumOnlineNodes
|
||||||
|
|
|
@ -173,6 +173,32 @@ const NodeInfo *NodeDB::readNextInfo()
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||||
|
uint32_t sinceLastSeen(const NodeInfo *n)
|
||||||
|
{
|
||||||
|
uint32_t now = gps.getTime() / 1000;
|
||||||
|
|
||||||
|
int delta = (int)(now - n->last_seen);
|
||||||
|
if (delta < 0) // our clock must be slightly off still - not set from GPS yet
|
||||||
|
delta = 0;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NUM_ONLINE_SECS (60 * 2) // 2 hrs to consider someone offline
|
||||||
|
|
||||||
|
size_t NodeDB::getNumOnlineNodes()
|
||||||
|
{
|
||||||
|
size_t numseen = 0;
|
||||||
|
|
||||||
|
// FIXME this implementation is kinda expensive
|
||||||
|
for(int i = 0; i < *numNodes; i++)
|
||||||
|
if(sinceLastSeen(&nodes[i]) < NUM_ONLINE_SECS)
|
||||||
|
numseen++;
|
||||||
|
|
||||||
|
return numseen;
|
||||||
|
}
|
||||||
|
|
||||||
/// given a subpacket sniffed from the network, update our DB state
|
/// given a subpacket sniffed from the network, update our DB state
|
||||||
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
||||||
void NodeDB::updateFrom(const MeshPacket &mp)
|
void NodeDB::updateFrom(const MeshPacket &mp)
|
||||||
|
@ -188,7 +214,7 @@ void NodeDB::updateFrom(const MeshPacket &mp)
|
||||||
if (oldNumNodes != *numNodes)
|
if (oldNumNodes != *numNodes)
|
||||||
updateGUI = true; // we just created a nodeinfo
|
updateGUI = true; // we just created a nodeinfo
|
||||||
|
|
||||||
info->last_seen = gps.getTime();
|
info->last_seen = gps.getTime() / 1000; // we keep time in seconds, not msecs
|
||||||
|
|
||||||
switch (p.which_variant)
|
switch (p.which_variant)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,9 @@ extern RadioConfig &radioConfig;
|
||||||
extern ChannelSettings &channelSettings;
|
extern ChannelSettings &channelSettings;
|
||||||
extern User &owner;
|
extern User &owner;
|
||||||
|
|
||||||
|
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||||
|
uint32_t sinceLastSeen(const NodeInfo *n);
|
||||||
|
|
||||||
class NodeDB
|
class NodeDB
|
||||||
{
|
{
|
||||||
// NodeNum provisionalNodeNum; // if we are trying to find a node num this is our current attempt
|
// NodeNum provisionalNodeNum; // if we are trying to find a node num this is our current attempt
|
||||||
|
@ -71,7 +74,7 @@ public:
|
||||||
NodeInfo *getNodeByIndex(size_t x) { assert(x < *numNodes); return &nodes[x]; }
|
NodeInfo *getNodeByIndex(size_t x) { assert(x < *numNodes); return &nodes[x]; }
|
||||||
|
|
||||||
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
|
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
|
||||||
size_t getNumOnlineNodes() { return getNumNodes() - 1; /* FIXME */ }
|
size_t getNumOnlineNodes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// Select which T-Beam board is being used. Only uncomment one. Note: these options now come from platformio standard build file flags
|
// Select which T-Beam board is being used. Only uncomment one. Note: these options now come from platformio standard build file flags
|
||||||
//#ifdef ARDUINO_T_Beam
|
//#ifdef ARDUINO_T_Beam
|
||||||
#define T_BEAM_V10 // AKA Rev1 (second board released)
|
//#define T_BEAM_V10 // AKA Rev1 (second board released)
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#ifdef ARDUINO_HELTEC_WIFI_LORA_32_V2
|
//#ifdef ARDUINO_HELTEC_WIFI_LORA_32_V2
|
||||||
//#define HELTEC_LORA32
|
#define HELTEC_LORA32
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
// If we are using the JTAG port for debugging, some pins must be left free for that (and things like GPS have to be disabled)
|
// If we are using the JTAG port for debugging, some pins must be left free for that (and things like GPS have to be disabled)
|
||||||
|
|
|
@ -34,8 +34,8 @@ typedef enum _ChannelSettings_ModemConfig {
|
||||||
|
|
||||||
typedef enum _DeviceState_Version {
|
typedef enum _DeviceState_Version {
|
||||||
DeviceState_Version_Unset = 0,
|
DeviceState_Version_Unset = 0,
|
||||||
DeviceState_Version_Minimum = 6,
|
DeviceState_Version_Minimum = 7,
|
||||||
DeviceState_Version_Current = 6
|
DeviceState_Version_Current = 7
|
||||||
} DeviceState_Version;
|
} DeviceState_Version;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
|
@ -86,7 +86,7 @@ typedef struct _NodeInfo {
|
||||||
User user;
|
User user;
|
||||||
bool has_position;
|
bool has_position;
|
||||||
Position position;
|
Position position;
|
||||||
uint64_t last_seen;
|
uint32_t last_seen;
|
||||||
int32_t snr;
|
int32_t snr;
|
||||||
int32_t frequency_error;
|
int32_t frequency_error;
|
||||||
} NodeInfo;
|
} NodeInfo;
|
||||||
|
@ -311,7 +311,7 @@ X(a, STATIC, SINGULAR, BOOL, promiscuous_mode, 101)
|
||||||
X(a, STATIC, SINGULAR, INT32, num, 1) \
|
X(a, STATIC, SINGULAR, INT32, num, 1) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
|
X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
|
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
|
||||||
X(a, STATIC, SINGULAR, UINT64, last_seen, 4) \
|
X(a, STATIC, SINGULAR, UINT32, last_seen, 4) \
|
||||||
X(a, STATIC, SINGULAR, INT32, snr, 5) \
|
X(a, STATIC, SINGULAR, INT32, snr, 5) \
|
||||||
X(a, STATIC, SINGULAR, INT32, frequency_error, 6)
|
X(a, STATIC, SINGULAR, INT32, frequency_error, 6)
|
||||||
#define NodeInfo_CALLBACK NULL
|
#define NodeInfo_CALLBACK NULL
|
||||||
|
@ -391,9 +391,9 @@ extern const pb_msgdesc_t ToRadio_msg;
|
||||||
#define ChannelSettings_size 50
|
#define ChannelSettings_size 50
|
||||||
#define RadioConfig_size 72
|
#define RadioConfig_size 72
|
||||||
#define RadioConfig_UserPreferences_size 18
|
#define RadioConfig_UserPreferences_size 18
|
||||||
#define NodeInfo_size 162
|
#define NodeInfo_size 157
|
||||||
#define MyNodeInfo_size 13
|
#define MyNodeInfo_size 13
|
||||||
#define DeviceState_size 13349
|
#define DeviceState_size 13189
|
||||||
#define FromRadio_size 253
|
#define FromRadio_size 253
|
||||||
#define ToRadio_size 247
|
#define ToRadio_size 247
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
|
|
||||||
#define FONT_HEIGHT 14 // actually 13 for "ariel 10" but want a little extra space
|
#define FONT_HEIGHT 14 // actually 13 for "ariel 10" but want a little extra space
|
||||||
|
#define FONT_HEIGHT_16 (ArialMT_Plain_16[1] + 1)
|
||||||
#define SCREEN_WIDTH 128
|
#define SCREEN_WIDTH 128
|
||||||
#define SCREEN_HEIGHT 64
|
#define SCREEN_HEIGHT 64
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ SSD1306Wire dispdev(SSD1306_ADDRESS, I2C_SDA, I2C_SCL);
|
||||||
SSD1306Wire dispdev(SSD1306_ADDRESS, 0, 0); // fake values to keep build happy, we won't ever init
|
SSD1306Wire dispdev(SSD1306_ADDRESS, 0, 0); // fake values to keep build happy, we won't ever init
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool disp; // true if we are using display
|
bool disp; // true if we are using display
|
||||||
bool screenOn; // true if the display is currently powered
|
bool screenOn; // true if the display is currently powered
|
||||||
|
|
||||||
OLEDDisplayUi ui(&dispdev);
|
OLEDDisplayUi ui(&dispdev);
|
||||||
|
@ -66,9 +66,9 @@ void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
||||||
|
|
||||||
display->drawXbm(x + 32, y, icon_width, icon_height, (const uint8_t *)icon_bits);
|
display->drawXbm(x + 32, y, icon_width, icon_height, (const uint8_t *)icon_bits);
|
||||||
|
|
||||||
display->setFont(ArialMT_Plain_10);
|
display->setFont(ArialMT_Plain_16);
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
display->drawString(64 + x, SCREEN_HEIGHT - FONT_HEIGHT, APP_NAME " " APP_VERSION);
|
display->drawString(64 + x, SCREEN_HEIGHT - FONT_HEIGHT_16, "meshtastic.org");
|
||||||
|
|
||||||
ui.disableIndicator();
|
ui.disableIndicator();
|
||||||
}
|
}
|
||||||
|
@ -261,11 +261,20 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
||||||
static char signalStr[20];
|
static char signalStr[20];
|
||||||
snprintf(signalStr, sizeof(signalStr), "Signal: %d", node->snr);
|
snprintf(signalStr, sizeof(signalStr), "Signal: %d", node->snr);
|
||||||
|
|
||||||
|
uint32_t agoSecs = sinceLastSeen(node);
|
||||||
|
static char lastStr[20];
|
||||||
|
if (agoSecs < 120) // last 2 mins?
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "%d seconds ago", agoSecs);
|
||||||
|
else if (agoSecs < 120 * 60) // last 2 hrs
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "%d minutes ago", agoSecs / 60);
|
||||||
|
else
|
||||||
|
snprintf(lastStr, sizeof(lastStr), "%d hours ago", agoSecs / 60 / 60);
|
||||||
|
|
||||||
const char *fields[] = {
|
const char *fields[] = {
|
||||||
username,
|
username,
|
||||||
"2.1 mi",
|
"2.1 mi",
|
||||||
signalStr,
|
signalStr,
|
||||||
"12 minutes ago",
|
lastStr,
|
||||||
NULL};
|
NULL};
|
||||||
drawColumns(display, x, y, fields);
|
drawColumns(display, x, y, fields);
|
||||||
|
|
||||||
|
@ -464,7 +473,7 @@ uint32_t screen_loop()
|
||||||
wakeScreen = false;
|
wakeScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!screenOn) // If we didn't just wake and the screen is still off, then bail
|
if (!screenOn) // If we didn't just wake and the screen is still off, then bail
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
|
|
||||||
static bool showingBootScreen = true; // start by showing the bootscreen
|
static bool showingBootScreen = true; // start by showing the bootscreen
|
||||||
|
@ -494,7 +503,8 @@ uint32_t screen_loop()
|
||||||
screen_set_frames();
|
screen_set_frames();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(millis() - lastPressMs > SCREEN_SLEEP_MS) {
|
if (millis() - lastPressMs > SCREEN_SLEEP_MS)
|
||||||
|
{
|
||||||
DEBUG_MSG("screen timeout, turn it off for now...\n");
|
DEBUG_MSG("screen timeout, turn it off for now...\n");
|
||||||
screen_off();
|
screen_off();
|
||||||
}
|
}
|
||||||
|
@ -541,8 +551,6 @@ void screen_set_frames()
|
||||||
showingBluetooth = false;
|
showingBluetooth = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// handle press of the button
|
/// handle press of the button
|
||||||
void screen_press()
|
void screen_press()
|
||||||
{
|
{
|
||||||
|
@ -552,6 +560,6 @@ void screen_press()
|
||||||
wakeScreen = true;
|
wakeScreen = true;
|
||||||
|
|
||||||
// If screen was off, just wake it, otherwise advance to next frame
|
// If screen was off, just wake it, otherwise advance to next frame
|
||||||
if(screenOn)
|
if (screenOn)
|
||||||
ui.nextFrame();
|
ui.nextFrame();
|
||||||
}
|
}
|
Ładowanie…
Reference in New Issue