From 8ea35221ed8636c3b3dd600267f3227221a0f8d8 Mon Sep 17 00:00:00 2001 From: Mooneer Salem Date: Fri, 26 Jul 2024 15:59:23 -0700 Subject: [PATCH] Add System Status tab and display basic FreeDV stats. --- firmware/main/audio/FreeDVMessage.h | 4 +- firmware/main/audio/FreeDVTask.cpp | 6 ++- firmware/main/http_server_files/index.html.in | 14 ++++++ .../main/http_server_files/localscript.js | 13 +++++ firmware/main/network/HttpServerTask.cpp | 48 +++++++++++++++++++ firmware/main/network/HttpServerTask.h | 8 ++++ 6 files changed, 91 insertions(+), 2 deletions(-) diff --git a/firmware/main/audio/FreeDVMessage.h b/firmware/main/audio/FreeDVMessage.h index 675f4882..b0cf90c3 100644 --- a/firmware/main/audio/FreeDVMessage.h +++ b/firmware/main/audio/FreeDVMessage.h @@ -51,13 +51,15 @@ enum FreeDVMessageTypes class FreeDVSyncStateMessage : public DVTaskMessageBase { public: - FreeDVSyncStateMessage(bool syncStateProvided = false) + FreeDVSyncStateMessage(bool syncStateProvided = false, int freqOffsetProvided = 0) : DVTaskMessageBase(FREEDV_MESSAGE) , syncState(syncStateProvided) + , freqOffset(freqOffsetProvided) {} virtual ~FreeDVSyncStateMessage() = default; bool syncState; + int freqOffset; }; enum FreeDVMode diff --git a/firmware/main/audio/FreeDVTask.cpp b/firmware/main/audio/FreeDVTask.cpp index a0713579..3a0dadd2 100644 --- a/firmware/main/audio/FreeDVTask.cpp +++ b/firmware/main/audio/FreeDVTask.cpp @@ -94,6 +94,7 @@ void FreeDVTask::onTaskTick_() if (!isActive_) return; bool syncLed = false; + int freqOffset = 0; //ESP_LOGI(CURRENT_LOG_TAG, "timer tick"); @@ -201,11 +202,14 @@ void FreeDVTask::onTaskTick_() } syncLed = freedv_get_sync(dv_) > 0; + + freedv_get_modem_extended_stats(dv_, stats_); + freqOffset = stats_->foff; } } // Broadcast current sync state - FreeDVSyncStateMessage* message = new FreeDVSyncStateMessage(syncLed); + FreeDVSyncStateMessage* message = new FreeDVSyncStateMessage(syncLed, freqOffset); publish(message); delete message; } diff --git a/firmware/main/http_server_files/index.html.in b/firmware/main/http_server_files/index.html.in index 8bddd2bc..5780d46a 100644 --- a/firmware/main/http_server_files/index.html.in +++ b/firmware/main/http_server_files/index.html.in @@ -59,6 +59,9 @@ + @@ -253,6 +256,17 @@
 
+
+
+ + + + + + +
FreeDV Signal
SyncedNo
Frequency offset0
+
+
diff --git a/firmware/main/http_server_files/localscript.js b/firmware/main/http_server_files/localscript.js index a7fbd681..7552e2c8 100644 --- a/firmware/main/http_server_files/localscript.js +++ b/firmware/main/http_server_files/localscript.js @@ -523,6 +523,19 @@ function wsConnect() $("#startVoiceKeyer").removeClass("btn-danger"); } } + else if (json.type == "freedvStatus") + { + if (json.sync) + { + $("#syncState").text("Yes"); + } + else + { + $("#syncState").text("No"); + } + + $("#freqOffset").text(json.freqOffset); + } }; ws.onclose = function(e) diff --git a/firmware/main/network/HttpServerTask.cpp b/firmware/main/network/HttpServerTask.cpp index 40b2c2cd..bf503881 100644 --- a/firmware/main/network/HttpServerTask.cpp +++ b/firmware/main/network/HttpServerTask.cpp @@ -53,6 +53,7 @@ extern "C" #define JSON_WIFI_SAVED_TYPE "wifiSaved" #define JSON_RADIO_STATUS_TYPE "radioInfo" #define JSON_RADIO_SAVED_TYPE "radioSaved" +#define JSON_FREEDV_STATUS_TYPE "freedvStatus" #define JSON_VOICE_KEYER_STATUS_TYPE "voiceKeyerInfo" #define JSON_VOICE_KEYER_SAVED_TYPE "voiceKeyerSaved" @@ -86,6 +87,8 @@ HttpServerTask::HttpServerTask() : ezdv::task::DVTask("HttpServerTask", 4, 4096, tskNO_AFFINITY, 256) , firmwareUploadInProgress_(false) , isRunning_(false) + , currFreqOffset_(0) + , freqOffsetCount_(0) { registerMessageHandler(this, &HttpServerTask::onBatteryStateMessage_); @@ -121,6 +124,8 @@ HttpServerTask::HttpServerTask() registerMessageHandler(this, &HttpServerTask::onWifiNetworkListMessage_); registerMessageHandler(this, &HttpServerTask::onHttpServeStaticFileMessage_); + + registerMessageHandler(this, &HttpServerTask::onFreeDVSyncStateMessage_); } HttpServerTask::~HttpServerTask() @@ -888,6 +893,49 @@ void HttpServerTask::onHttpWebsocketDisconnectedMessage_(DVTask* origin, HttpWeb } } +void HttpServerTask::onFreeDVSyncStateMessage_(DVTask* origin, audio::FreeDVSyncStateMessage* message) +{ + const int NUM_OFFSETS_TO_AVERAGE = 25; + + // Calculate average offset (enough samples so we report ~4x/sec, ensuring we don't + // overwhelm any web clients. + freqOffsets_.push_back(message->freqOffset); + if (freqOffsets_.size() > NUM_OFFSETS_TO_AVERAGE) + { + freqOffsets_.pop_front(); + } + + int sum = 0; + for (auto& val : freqOffsets_) + { + sum += val; + } + currFreqOffset_ = sum / freqOffsets_.size(); + + freqOffsetCount_++; + if (freqOffsetCount_ >= NUM_OFFSETS_TO_AVERAGE) + { + freqOffsetCount_ = 0; + + // Report running average of the offset and sync state to web interace + cJSON *root = cJSON_CreateObject(); + if (root != nullptr) + { + cJSON_AddStringToObject(root, "type", JSON_FREEDV_STATUS_TYPE); + cJSON_AddNumberToObject(root, "freqOffset", currFreqOffset_); + cJSON_AddBoolToObject(root, "sync", message->syncState); + + // Note: below is responsible for cleanup. + sendJSONMessage_(root, activeWebSockets_); + } + else + { + // HTTP isn't 100% critical but we really should see what's leaking memory. + ESP_LOGE(CURRENT_LOG_TAG, "Could not create JSON object for codec status!"); + } + } +} + void HttpServerTask::onBatteryStateMessage_(DVTask* origin, driver::BatteryStateMessage* message) { cJSON *root = cJSON_CreateObject(); diff --git a/firmware/main/network/HttpServerTask.h b/firmware/main/network/HttpServerTask.h index 7cef45ed..fc16a581 100644 --- a/firmware/main/network/HttpServerTask.h +++ b/firmware/main/network/HttpServerTask.h @@ -19,6 +19,7 @@ #define HTTP_SERVER_TASK_H #include +#include #include "esp_event.h" #include "esp_http_server.h" @@ -140,6 +141,10 @@ class HttpServerTask : public DVTask WebSocketList activeWebSockets_; bool isRunning_; + std::deque freqOffsets_; + int currFreqOffset_; + int freqOffsetCount_; + void onHttpWebsocketConnectedMessage_(DVTask* origin, HttpWebsocketConnectedMessage* message); void onHttpWebsocketDisconnectedMessage_(DVTask* origin, HttpWebsocketDisconnectedMessage* message); @@ -169,6 +174,9 @@ class HttpServerTask : public DVTask void onStartWifiScanMessage_(DVTask* origin, HttpServerTask::StartWifiScanMessage* message); void onStopWifiScanMessage_(DVTask* origin, HttpServerTask::StopWifiScanMessage* message); void onWifiNetworkListMessage_(DVTask* origin, WifiNetworkListMessage* message); + + // FreeDV sync state reporting + void onFreeDVSyncStateMessage_(DVTask* origin, audio::FreeDVSyncStateMessage* message); // Helper to asynchronously serve static files. void onHttpServeStaticFileMessage_(DVTask* origin, HttpServeStaticFileMessage* message);