From 58bf8763edc74949367d4ce7efe4bd138b3bedcf Mon Sep 17 00:00:00 2001 From: tck Date: Thu, 19 Mar 2026 09:26:48 +0800 Subject: [PATCH] Added a few MDs, update README --- EXAMPLE_CODE.md | 76 +++++++++++++++++++++++++++++++++++++++++++ INTEGRATION.md | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ flip_display.sh | 13 ++++++++ start.sh | 10 ++++++ 4 files changed, 185 insertions(+) create mode 100644 EXAMPLE_CODE.md create mode 100644 INTEGRATION.md create mode 100755 flip_display.sh diff --git a/EXAMPLE_CODE.md b/EXAMPLE_CODE.md new file mode 100644 index 000000000..3c7992e5a --- /dev/null +++ b/EXAMPLE_CODE.md @@ -0,0 +1,76 @@ +# Example Code/Flow/Design + +## ๐Ÿ”’ Securing the communication + +### 1. Restrict to localhost for kiosk + +* The kiosk UI (`:8080`) should only talk to the backend via `ws://127.0.0.1:12345` (or `wss://` if you enable TLS). +* This ensures the touchscreen browser cannot be hijacked remotely. + +### 2. TLS for remote UI + +* For the remote UI (`:9090`), expose a WebSocket server with TLS (`wss://Pi_IP:12346`). +* Generate a selfโ€‘signed certificate or use Letโ€™s Encrypt if the Pi is reachable externally. +* Qt supports `QWebSocketServer::SecureMode` with SSL certificates. + +```cpp +server = new QWebSocketServer("SecureServer", + QWebSocketServer::SecureMode, this); +QSslConfiguration sslConfig; +sslConfig.setLocalCertificate(QSslCertificate::fromPath("server.crt")); +sslConfig.setPrivateKey(QSslKey(QFile("server.key"), QSsl::Rsa)); +server->setSslConfiguration(sslConfig); +server->listen(QHostAddress::Any, 12346); + +``` + +### 3. Authentication + +* Require a token or password for remote clients. +* On connection, the client must send `{ "auth":"secret123" }` before other commands. +* Backend rejects unauthenticated clients. + +*** + +## ๐Ÿ–ฅ๏ธ Serving two UIs + +### Option A: Two web servers + +* Run a lightweight HTTP server (e.g. `QtHttpServer` or `nginx`) on the Pi. +* Serve `dashboard_kiosk.html` at port 8080. +* Serve `dashboard_full.html` at port 9090. +* Both connect to the same backend WebSocket, but kiosk uses localhost only. + +### Option B: One server, two routes + +* Serve both UIs from one server, but separate routes: + * `http://Pi_IP:8080/kiosk` + * `http://Pi_IP:8080/full` +* Use Chromium kiosk mode on the Pi to open `/kiosk`. + +*** + +## ๐Ÿ”„ Communication flow + +* **Kiosk UI (touchscreen)** + โ†’ Connects to `ws://127.0.0.1:12345` (no TLS, local only). + โ†’ Sends commands like `toggleSiren`. + โ†’ Receives sensor updates every few seconds. +* **Remote UI (PC browser)** + โ†’ Connects to `wss://Pi_IP:12346` (TLS). + โ†’ Authenticates with token. + โ†’ Can send commands and receive updates, but with richer navigation. + +*** + +## ๐Ÿš€ Next Steps + +1. Generate TLS certs (`openssl req -new -x509 -days 365 -keyout server.key -out server.crt`). +2. Configure Qt WebSocket server with `SecureMode` for remote clients. +3. Serve two HTML versions (kiosk vs full) via nginx or QtHttpServer. +4. Add authentication handshake for remote connections. + +*** + + + diff --git a/INTEGRATION.md b/INTEGRATION.md new file mode 100644 index 000000000..744f35944 --- /dev/null +++ b/INTEGRATION.md @@ -0,0 +1,86 @@ +# HTML FRONTEND + C++ HOOKS + +You can definitely run your HTML dashboard in **Chromium kiosk mode** and still have it talk to your existing **C++/Qt backend**. The trick is to bridge the browser UI with your native code. Here are the main approaches: + +[Example Code](EXAMPLE_CODE.md) + +*** + +### ๐Ÿ”— Integration Options + +#### 1. **Local WebSocket / TCP server** + +* Run a lightweight server inside your C++ app (e.g. using `QtWebSockets` or `QTcpServer`). +* Your HTML buttons call JavaScript functions that send JSON messages over WebSocket. +* Example: + ```javascript + function sendCommand(cmd, payload={}) { + socket.send(JSON.stringify({command: cmd, data: payload})); + } + + ``` + ```cpp + // Qt side + connect(webSocketServer, &QWebSocketServer::newConnection, this, [=](){ + auto client = webSocketServer->nextPendingConnection(); + connect(client, &QWebSocket::textMessageReceived, this, [=](const QString &msg){ + QJsonDocument doc = QJsonDocument::fromJson(msg.toUtf8()); + QString cmd = doc["command"].toString(); + // handle command + }); + }); + + ``` + +#### 2. **REST API (HTTP server)** + +* Expose endpoints in your C++ app (`/setRainfall`, `/getStatus`, etc.). +* HTML buttons use `fetch()` to call these endpoints. +* Example: + ```javascript + fetch("http://localhost:8080/setRainfall", { + method: "POST", + body: JSON.stringify({value: 12.4}), + headers: {"Content-Type":"application/json"} + }); + + ``` + +#### 3. **Native Messaging (Chromium extension)** + +* If you need tighter integration, you can build a Chromium extension that talks to your C++ app via **Native Messaging**. +* More complex, but allows secure communication without opening a server port. + +*** + +### ๐Ÿ–ฅ๏ธ Kiosk Mode Setup + +* Launch Chromium with flags: + ```shellscript + chromium --kiosk --app=file:///home/user/dashboard.html + + ``` +* This runs fullscreen, hides controls, and loads your HTML UI. + +*** + +### โš™๏ธ Recommended Path + +For your case (Qt backend + kiosk UI), the **WebSocket approach** is usually the cleanest: + +* Qt has built-in WebSocket support. +* Easy to send structured JSON messages both ways. +* Works offline, no need for external servers. + +*** + +### ๐Ÿš€ Next Step + +Would you like me to sketch out a **minimal working example** where: + +* A button in the HTML dashboard sends a command (`"toggleSiren"`) +* Your Qt app receives it and prints/logs the action? + +That way youโ€™ll see the full round-trip between Chromium kiosk and your C++ backend. + +[Example Code/Flow/Design](https://notes.tck.com.my/workspace/06083e3a-3e03-4e37-8857-6bd2c292ef33/U2XWNlmCHW-UKuJpwMkwK) diff --git a/flip_display.sh b/flip_display.sh new file mode 100755 index 000000000..cc4d20e01 --- /dev/null +++ b/flip_display.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Flip screen +# C-Fu for TCK + +# Flip the display +DISPLAY=:0 xrandr --output HDMI-1 --reflect x + +# Flip the touch input (using ID 7 for your specific device) +DISPLAY=:0 xinput set-prop 7 'Coordinate Transformation Matrix' -1 0 1 0 1 0 0 0 1 + +# Change reso +DISPLAY=:0 xrandr --output HDMI-1 --mode 1024x600 diff --git a/start.sh b/start.sh index fb2f901b9..1e1b0886d 100755 --- a/start.sh +++ b/start.sh @@ -3,6 +3,16 @@ # TCK RTU - Start Script # Interactive menu for common development commands +# Flip the display horizontally, and maaaybe flip the mouse cursor+touchscreen as well +# NOW JUST RUN ./flip_display.sh + +# Flip the display +#DISPLAY=:0 xrandr --output HDMI-1 --reflect x + +# Flip the touch input (using ID 7 for your specific device) +#DISPLAY=:0 xinput set-prop 7 'Coordinate Transformation Matrix' -1 0 1 0 1 0 0 0 1 + + set -e # Colors