diff --git a/TODO.md b/TODO.md index a1ffd2e5..68f446f4 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,6 @@ # 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) * make debug info screen show real data (including battery level & charging) * make real implementation of getNumOnlineNodes diff --git a/src/NodeDB.cpp b/src/NodeDB.cpp index 5891ca50..4ceaba56 100644 --- a/src/NodeDB.cpp +++ b/src/NodeDB.cpp @@ -173,6 +173,32 @@ const NodeInfo *NodeDB::readNextInfo() 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 /// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw void NodeDB::updateFrom(const MeshPacket &mp) @@ -188,7 +214,7 @@ void NodeDB::updateFrom(const MeshPacket &mp) if (oldNumNodes != *numNodes) 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) { diff --git a/src/NodeDB.h b/src/NodeDB.h index eea55b0b..c8eba85d 100644 --- a/src/NodeDB.h +++ b/src/NodeDB.h @@ -11,6 +11,9 @@ extern RadioConfig &radioConfig; extern ChannelSettings &channelSettings; 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 { // 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]; } /// 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: diff --git a/src/configuration.h b/src/configuration.h index 46ef06b6..2d892018 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -38,11 +38,11 @@ along with this program. If not, see . // 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 -#define T_BEAM_V10 // AKA Rev1 (second board released) +//#define T_BEAM_V10 // AKA Rev1 (second board released) //#endif //#ifdef ARDUINO_HELTEC_WIFI_LORA_32_V2 -//#define HELTEC_LORA32 +#define HELTEC_LORA32 //#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) diff --git a/src/mesh.pb.h b/src/mesh.pb.h index 01bbd63d..9a92854c 100644 --- a/src/mesh.pb.h +++ b/src/mesh.pb.h @@ -34,8 +34,8 @@ typedef enum _ChannelSettings_ModemConfig { typedef enum _DeviceState_Version { DeviceState_Version_Unset = 0, - DeviceState_Version_Minimum = 6, - DeviceState_Version_Current = 6 + DeviceState_Version_Minimum = 7, + DeviceState_Version_Current = 7 } DeviceState_Version; /* Struct definitions */ @@ -86,7 +86,7 @@ typedef struct _NodeInfo { User user; bool has_position; Position position; - uint64_t last_seen; + uint32_t last_seen; int32_t snr; int32_t frequency_error; } NodeInfo; @@ -311,7 +311,7 @@ X(a, STATIC, SINGULAR, BOOL, promiscuous_mode, 101) X(a, STATIC, SINGULAR, INT32, num, 1) \ X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ 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, frequency_error, 6) #define NodeInfo_CALLBACK NULL @@ -391,9 +391,9 @@ extern const pb_msgdesc_t ToRadio_msg; #define ChannelSettings_size 50 #define RadioConfig_size 72 #define RadioConfig_UserPreferences_size 18 -#define NodeInfo_size 162 +#define NodeInfo_size 157 #define MyNodeInfo_size 13 -#define DeviceState_size 13349 +#define DeviceState_size 13189 #define FromRadio_size 253 #define ToRadio_size 247 diff --git a/src/screen.cpp b/src/screen.cpp index b6881911..edd015f3 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -32,7 +32,7 @@ along with this program. If not, see . #include "NodeDB.h" #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_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 #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 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->setFont(ArialMT_Plain_10); + display->setFont(ArialMT_Plain_16); 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(); } @@ -261,11 +261,20 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in static char signalStr[20]; 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[] = { username, "2.1 mi", signalStr, - "12 minutes ago", + lastStr, NULL}; drawColumns(display, x, y, fields); @@ -464,7 +473,7 @@ uint32_t screen_loop() 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; static bool showingBootScreen = true; // start by showing the bootscreen @@ -494,7 +503,8 @@ uint32_t screen_loop() 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"); screen_off(); } @@ -541,8 +551,6 @@ void screen_set_frames() showingBluetooth = false; } - - /// handle press of the button void screen_press() { @@ -552,6 +560,6 @@ void screen_press() wakeScreen = true; // If screen was off, just wake it, otherwise advance to next frame - if(screenOn) + if (screenOn) ui.nextFrame(); } \ No newline at end of file