feat(mcp): restore MCP service with display charging toggle
- Restore MCP system (McpSystem 1900+ LOC, McpHandler, McpScreensaver, McpSettings, McpOverride apps) - Use audio-stream instead of direct I2S for MP3 playback (fixes fast playback, uses native resampler) - Register McpSettings + McpOverride in Tactility.cpp so Settings shows MCP Screen - DisplaySettings: add ScreensaverType::McpScreen and disableScreensaverWhenCharging flag - Display app: add 'Disable on charging' toggle, handles McpScreen screensaver type - DisplayIdle: skip screensaver while charging, support McpScreen screensaver, isDeviceCharging check via PowerDevice - WebServer: coexistence with MCP (McpHandler) - Avoid formatting churn from previous commits Squashed from range eaa248b0..8970143f (6 commits) into single clean commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/audio_stream.h>
|
||||
|
||||
namespace tt::mcp {
|
||||
|
||||
struct McpSystemState {
|
||||
std::mutex mutex;
|
||||
bool overrideActive = false;
|
||||
|
||||
// UI elements when McpOverrideApp is active
|
||||
lv_obj_t* drawArea = nullptr;
|
||||
uint16_t* framebuffer = nullptr;
|
||||
size_t framebufferSize = 0;
|
||||
uint16_t displayWidth = 320;
|
||||
uint16_t displayHeight = 240;
|
||||
uint16_t drawWidth = 320;
|
||||
uint16_t drawHeight = 240;
|
||||
int drawColor = 1; // 0 = white, 1 = black
|
||||
|
||||
// Audio device status
|
||||
Device* i2sDevice = nullptr;
|
||||
Device* audioStreamDevice = nullptr;
|
||||
AudioStreamHandle audioHandle = nullptr;
|
||||
volatile bool audioBusy = false;
|
||||
volatile bool audioRunning = false; // Used to abort play/record loop
|
||||
|
||||
// Video streaming state
|
||||
volatile bool streamRunning = false;
|
||||
void* streamTaskHandle = nullptr; // use void* to avoid freertos header inclusion dependency
|
||||
uint32_t framesDrawn = 0;
|
||||
uint32_t tcpBytesReceived = 0;
|
||||
uint32_t lastDrawMs = 0;
|
||||
double lastFps = 0.0;
|
||||
};
|
||||
|
||||
McpSystemState& getState();
|
||||
|
||||
bool clearScreen(int color);
|
||||
bool drawText(const std::string& text, int x, int y, int size);
|
||||
bool drawRgb565(const uint8_t* data, size_t size, int x, int y, int w, int h);
|
||||
bool drawBmp(const uint8_t* data, size_t size, int x, int y);
|
||||
bool drawPbm(const uint8_t* data, size_t size, int x, int y);
|
||||
std::string getScreenshotPbmBase64();
|
||||
|
||||
bool playTone(int frequency, int durationMs, int volume, std::string& error);
|
||||
bool recordVoice(int durationSec, const std::string& filename, size_t& recordedBytes, std::string& error);
|
||||
bool playAudioFile(const std::string& filename, int volume, std::string& error);
|
||||
bool playWavMemory(const uint8_t* data, size_t size, int volume, std::string& error);
|
||||
bool playMp3File(const std::string& filename, int volume, std::string& error);
|
||||
bool playMp3Memory(const uint8_t* data, size_t size, int volume, std::string& error);
|
||||
|
||||
bool getBatteryStatus(double& voltage_v, int& percentage_pct, std::string& error);
|
||||
bool setLedColor(int r, int g, int b, const std::string& mode, std::string& error);
|
||||
bool getSensors(double& temp_c, double& hum_pct, std::string& imu_json, std::string& error);
|
||||
bool scanBleDevices(int duration_ms, std::string& devices_json, std::string& error);
|
||||
bool writeSdFile(const std::string& filename, const std::string& content, std::string& error);
|
||||
bool readSdFile(const std::string& filename, std::string& content, std::string& error);
|
||||
bool downloadSdFile(const std::string& url, const std::string& filename, std::string& error);
|
||||
|
||||
bool startVideoStreamServer();
|
||||
void stopVideoStreamServer();
|
||||
bool getVideoStreamStats(std::string& stats_json);
|
||||
|
||||
bool listApps(std::string& apps_json, std::string& error);
|
||||
bool runApp(const std::string& appId, std::string& error);
|
||||
bool listSdFiles(const std::string& directory, std::string& files_json, std::string& error);
|
||||
|
||||
} // namespace tt::mcp
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ class DisplayIdleService final : public Service {
|
||||
bool backlightOff = false;
|
||||
|
||||
static void stopScreensaverCb(lv_event_t* e);
|
||||
void stopScreensaverLocked();
|
||||
|
||||
/** @pre Caller must hold LVGL lock */
|
||||
void activateScreensaver();
|
||||
@@ -63,6 +64,7 @@ public:
|
||||
* arbitrary threads while the timer is running.
|
||||
*/
|
||||
void stopScreensaver();
|
||||
void startMcpScreensaver();
|
||||
|
||||
/**
|
||||
* Check if the screensaver is currently active.
|
||||
|
||||
@@ -76,6 +76,8 @@ private:
|
||||
static esp_err_t handleApiAppsInstall(httpd_req_t* request);
|
||||
static esp_err_t handleApiWifi(httpd_req_t* request);
|
||||
static esp_err_t handleApiScreenshot(httpd_req_t* request);
|
||||
static esp_err_t handleApiMcp(httpd_req_t* request);
|
||||
static esp_err_t handleApiScreenRaw(httpd_req_t* request);
|
||||
|
||||
// Dynamic asset serving
|
||||
static esp_err_t handleAssets(httpd_req_t* request);
|
||||
|
||||
Reference in New Issue
Block a user