mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2025-12-18 15:17:42 +03:00
Add basic webserver
This commit is contained in:
parent
f365ba6ff0
commit
e4f7327719
199
src/CrossPointWebServer.cpp
Normal file
199
src/CrossPointWebServer.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
#include "CrossPointWebServer.h"
|
||||
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
// Global instance
|
||||
CrossPointWebServer crossPointWebServer;
|
||||
|
||||
// HTML page template
|
||||
static const char* HTML_PAGE = R"rawliteral(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CrossPoint Reader</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
h1 {
|
||||
color: #2c3e50;
|
||||
border-bottom: 2px solid #3498db;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 15px 0;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.info-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.label {
|
||||
font-weight: 600;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
.value {
|
||||
color: #2c3e50;
|
||||
}
|
||||
.status {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
background-color: #27ae60;
|
||||
color: white;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.coming-soon {
|
||||
color: #95a5a6;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>📚 CrossPoint Reader</h1>
|
||||
|
||||
<div class="card">
|
||||
<h2>Device Status</h2>
|
||||
<div class="info-row">
|
||||
<span class="label">Version</span>
|
||||
<span class="value">%VERSION%</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="label">WiFi Status</span>
|
||||
<span class="status">Connected</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="label">IP Address</span>
|
||||
<span class="value">%IP_ADDRESS%</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="label">Free Memory</span>
|
||||
<span class="value">%FREE_HEAP% bytes</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>File Management</h2>
|
||||
<p class="coming-soon">📁 File upload functionality coming soon...</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<p style="text-align: center; color: #95a5a6; margin: 0;">
|
||||
CrossPoint E-Reader • Open Source
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
)rawliteral";
|
||||
|
||||
CrossPointWebServer::CrossPointWebServer() {}
|
||||
|
||||
CrossPointWebServer::~CrossPointWebServer() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void CrossPointWebServer::begin() {
|
||||
if (running) {
|
||||
Serial.printf("[%lu] [WEB] Web server already running\n", millis());
|
||||
return;
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.printf("[%lu] [WEB] Cannot start webserver - WiFi not connected\n", millis());
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.printf("[%lu] [WEB] Creating web server on port %d...\n", millis(), port);
|
||||
server = new WebServer(port);
|
||||
|
||||
if (!server) {
|
||||
Serial.printf("[%lu] [WEB] Failed to create WebServer!\n", millis());
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup routes
|
||||
Serial.printf("[%lu] [WEB] Setting up routes...\n", millis());
|
||||
server->on("/", HTTP_GET, [this]() { handleRoot(); });
|
||||
server->on("/status", HTTP_GET, [this]() { handleStatus(); });
|
||||
server->onNotFound([this]() { handleNotFound(); });
|
||||
|
||||
server->begin();
|
||||
running = true;
|
||||
|
||||
Serial.printf("[%lu] [WEB] Web server started on port %d\n", millis(), port);
|
||||
Serial.printf("[%lu] [WEB] Access at http://%s/\n", millis(), WiFi.localIP().toString().c_str());
|
||||
}
|
||||
|
||||
void CrossPointWebServer::stop() {
|
||||
if (!running || !server) {
|
||||
return;
|
||||
}
|
||||
|
||||
server->stop();
|
||||
delete server;
|
||||
server = nullptr;
|
||||
running = false;
|
||||
|
||||
Serial.printf("[%lu] [WEB] Web server stopped\n", millis());
|
||||
}
|
||||
|
||||
void CrossPointWebServer::handleClient() {
|
||||
static unsigned long lastDebugPrint = 0;
|
||||
if (running && server) {
|
||||
// Print debug every 10 seconds to confirm handleClient is being called
|
||||
if (millis() - lastDebugPrint > 10000) {
|
||||
Serial.printf("[%lu] [WEB] handleClient active, server running on port %d\n", millis(), port);
|
||||
lastDebugPrint = millis();
|
||||
}
|
||||
server->handleClient();
|
||||
}
|
||||
}
|
||||
|
||||
void CrossPointWebServer::handleRoot() {
|
||||
String html = HTML_PAGE;
|
||||
|
||||
// Replace placeholders with actual values
|
||||
html.replace("%VERSION%", CROSSPOINT_VERSION);
|
||||
html.replace("%IP_ADDRESS%", WiFi.localIP().toString());
|
||||
html.replace("%FREE_HEAP%", String(ESP.getFreeHeap()));
|
||||
|
||||
server->send(200, "text/html", html);
|
||||
Serial.printf("[%lu] [WEB] Served root page\n", millis());
|
||||
}
|
||||
|
||||
void CrossPointWebServer::handleNotFound() {
|
||||
String message = "404 Not Found\n\n";
|
||||
message += "URI: " + server->uri() + "\n";
|
||||
server->send(404, "text/plain", message);
|
||||
}
|
||||
|
||||
void CrossPointWebServer::handleStatus() {
|
||||
String json = "{";
|
||||
json += "\"version\":\"" + String(CROSSPOINT_VERSION) + "\",";
|
||||
json += "\"ip\":\"" + WiFi.localIP().toString() + "\",";
|
||||
json += "\"rssi\":" + String(WiFi.RSSI()) + ",";
|
||||
json += "\"freeHeap\":" + String(ESP.getFreeHeap()) + ",";
|
||||
json += "\"uptime\":" + String(millis() / 1000);
|
||||
json += "}";
|
||||
|
||||
server->send(200, "application/json", json);
|
||||
}
|
||||
39
src/CrossPointWebServer.h
Normal file
39
src/CrossPointWebServer.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <WebServer.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
class CrossPointWebServer {
|
||||
public:
|
||||
CrossPointWebServer();
|
||||
~CrossPointWebServer();
|
||||
|
||||
// Start the web server (call after WiFi is connected)
|
||||
void begin();
|
||||
|
||||
// Stop the web server
|
||||
void stop();
|
||||
|
||||
// Call this periodically to handle client requests
|
||||
void handleClient();
|
||||
|
||||
// Check if server is running
|
||||
bool isRunning() const { return running; }
|
||||
|
||||
// Get the port number
|
||||
uint16_t getPort() const { return port; }
|
||||
|
||||
private:
|
||||
WebServer* server = nullptr;
|
||||
bool running = false;
|
||||
uint16_t port = 80;
|
||||
|
||||
// Request handlers
|
||||
void handleRoot();
|
||||
void handleNotFound();
|
||||
void handleStatus();
|
||||
};
|
||||
|
||||
// Global instance
|
||||
extern CrossPointWebServer crossPointWebServer;
|
||||
@ -5,6 +5,7 @@
|
||||
#include <InputManager.h>
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
#include <WiFi.h>
|
||||
#include <builtinFonts/bookerly_2b.h>
|
||||
#include <builtinFonts/bookerly_bold_2b.h>
|
||||
#include <builtinFonts/bookerly_bold_italic_2b.h>
|
||||
@ -16,6 +17,7 @@
|
||||
#include "Battery.h"
|
||||
#include "CrossPointSettings.h"
|
||||
#include "CrossPointState.h"
|
||||
#include "CrossPointWebServer.h"
|
||||
#include "config.h"
|
||||
#include "screens/BootLogoScreen.h"
|
||||
#include "screens/EpubReaderScreen.h"
|
||||
@ -244,6 +246,11 @@ void loop() {
|
||||
lastMemPrint = millis();
|
||||
}
|
||||
|
||||
// Handle web server clients if WiFi is connected
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
crossPointWebServer.handleClient();
|
||||
}
|
||||
|
||||
inputManager.update();
|
||||
if (inputManager.wasReleased(InputManager::BTN_POWER) && inputManager.getHeldTime() > POWER_BUTTON_WAKEUP_MS) {
|
||||
enterDeepSleep();
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <GfxRenderer.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "CrossPointWebServer.h"
|
||||
#include "config.h"
|
||||
|
||||
void WifiScreen::taskTrampoline(void* param) {
|
||||
@ -164,6 +165,10 @@ void WifiScreen::checkConnectionStatus() {
|
||||
connectedIP = ipStr;
|
||||
state = WifiScreenState::CONNECTED;
|
||||
updateRequired = true;
|
||||
|
||||
// Start the web server
|
||||
crossPointWebServer.begin();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -434,18 +439,22 @@ void WifiScreen::renderConnected() const {
|
||||
const auto pageWidth = GfxRenderer::getScreenWidth();
|
||||
const auto pageHeight = GfxRenderer::getScreenHeight();
|
||||
const auto height = renderer.getLineHeight(UI_FONT_ID);
|
||||
const auto top = (pageHeight - height * 3) / 2;
|
||||
const auto top = (pageHeight - height * 4) / 2;
|
||||
|
||||
renderer.drawCenteredText(READER_FONT_ID, top - 20, "Connected!", true, BOLD);
|
||||
renderer.drawCenteredText(READER_FONT_ID, top - 30, "Connected!", true, BOLD);
|
||||
|
||||
std::string ssidInfo = "Network: " + selectedSSID;
|
||||
if (ssidInfo.length() > 28) {
|
||||
ssidInfo = ssidInfo.substr(0, 25) + "...";
|
||||
}
|
||||
renderer.drawCenteredText(UI_FONT_ID, top + 20, ssidInfo.c_str(), true, REGULAR);
|
||||
renderer.drawCenteredText(UI_FONT_ID, top + 10, ssidInfo.c_str(), true, REGULAR);
|
||||
|
||||
std::string ipInfo = "IP Address: " + connectedIP;
|
||||
renderer.drawCenteredText(UI_FONT_ID, top + 50, ipInfo.c_str(), true, REGULAR);
|
||||
renderer.drawCenteredText(UI_FONT_ID, top + 40, ipInfo.c_str(), true, REGULAR);
|
||||
|
||||
// Show web server info
|
||||
std::string webInfo = "Web: http://" + connectedIP + "/";
|
||||
renderer.drawCenteredText(UI_FONT_ID, top + 70, webInfo.c_str(), true, REGULAR);
|
||||
|
||||
renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Press any button to continue", true, REGULAR);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user