Compare commits
1 Commits
d94d3278fa
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 357e30af66 |
@@ -105,16 +105,15 @@ None - ready to begin Phase 1 planning.
|
||||
| 1 | Create start.sh script with menu for test, dev, etc. | 2026-03-13 | b474f70 | [1-create-start-sh-script-with-menu-for-tes](./quick/1-create-start-sh-script-with-menu-for-tes/) |
|
||||
| 2 | Update start.sh for network access and port configuration | 2026-03-13 | e327ab9 | [2-update-start-sh-for-network-access-and-p](./quick/2-update-start-sh-for-network-access-and-p/) |
|
||||
| 3 | Fix UI feedback: header, navigation, and layout issues | 2026-03-13 | - | [3-fix-ui-feedback-header-navigation-and-la](./quick/3-fix-ui-feedback-header-navigation-and-la/) |
|
||||
| 4 | Create Full Remote HD Web Interface at Port 9999 | 2026-03-19 | 0f281567, 3b1ece0e, 9f29b51c | [4-create-full-remote-hd-web-interface-at-p](./quick/4-create-full-remote-hd-web-interface-at-p/) |
|
||||
|
||||
---
|
||||
|
||||
## Session Continuity
|
||||
|
||||
### Last Session
|
||||
- **Action:** Quick task 4 execution
|
||||
- **Outcome:** Port 9999 added as remote HD mode, dual-mode default startup implemented
|
||||
- **Artifacts:** useDisplayMode.ts, start.sh, README.md, WIKI.md, install_everything.sh updated
|
||||
- **Action:** Roadmap creation
|
||||
- **Outcome:** 3-phase roadmap created with 35/35 requirements mapped
|
||||
- **Artifacts:** ROADMAP.md, STATE.md, REQUIREMENTS.md updated
|
||||
|
||||
### Next Expected Session
|
||||
- **Action:** `/gsd-plan-phase 1`
|
||||
@@ -135,4 +134,4 @@ None - ready to begin Phase 1 planning.
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2026-03-19 - Completed quick task 4: Full Remote HD Web Interface at Port 9999*
|
||||
*Last updated: 2026-03-13 - Completed quick task 1: start.sh script*
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
---
|
||||
phase: quick
|
||||
plan: 4
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- start.sh
|
||||
- install_everything.sh
|
||||
- README.md
|
||||
- WIKI.md
|
||||
- sample_interface/src/app/hooks/useDisplayMode.ts
|
||||
autonomous: true
|
||||
requirements:
|
||||
- QUICK-04-01
|
||||
- QUICK-04-02
|
||||
- QUICK-04-03
|
||||
- QUICK-04-04
|
||||
- QUICK-04-05
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- Port 9999 recognized as "remote HD" display mode
|
||||
- start.sh runs both 8888 (kiosk) and 9999 (remote HD) by default when no args
|
||||
- start.sh menu includes option for dev:9999
|
||||
- All documentation updated with port 9999 and dual-mode default behavior
|
||||
artifacts:
|
||||
- path: "start.sh"
|
||||
provides: "Dual-mode default execution and dev:9999 menu option"
|
||||
- path: "install_everything.sh"
|
||||
provides: "Dual-mode installation documentation"
|
||||
- path: "README.md"
|
||||
provides: "Port 9999 and dual-mode documentation"
|
||||
- path: "WIKI.md"
|
||||
provides: "Port 9999 and dual-mode technical documentation"
|
||||
- path: "sample_interface/src/app/hooks/useDisplayMode.ts"
|
||||
provides: "Port 9999 recognized as remote HD mode"
|
||||
key_links:
|
||||
- from: "start.sh"
|
||||
to: "dev server on ports 8888 and 9999"
|
||||
via: "concurrent process spawning"
|
||||
- from: "useDisplayMode.ts"
|
||||
to: "port 9999"
|
||||
via: "window.location.port check"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Add port 9999 as a new "remote HD" display mode and update scripts/documentation for dual-mode default startup.
|
||||
|
||||
Purpose: Provide a dedicated Full HD remote interface port (9999) alongside the kiosk port (8888), with both servers starting by default for seamless local touchscreen and remote desktop access.
|
||||
Output: Updated scripts, documentation, and display mode detection supporting port 9999.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@./.opencode/get-shit-done/workflows/execute-plan.md
|
||||
@./.opencode/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@./sample_interface/src/app/hooks/useDisplayMode.ts
|
||||
@./start.sh
|
||||
@./README.md
|
||||
@./WIKI.md
|
||||
|
||||
<!-- Display mode detection currently only recognizes port 9090 as "remote"; all other ports default to "kiosk" mode -->
|
||||
<!-- Current ports documented: 8888 (kiosk), 9090 (remote), 5173 (dev) -->
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>task 1: Update useDisplayMode hook for port 9999</name>
|
||||
<files>sample_interface/src/app/hooks/useDisplayMode.ts</files>
|
||||
<action>
|
||||
Update the DisplayMode type to include 'remote-hd' as a third option.
|
||||
Modify useDisplayMode() and getDisplayMode() functions to recognize port '9999' and return 'remote-hd'.
|
||||
Port 9090 should continue to return 'remote'.
|
||||
All other ports should continue to return 'kiosk'.
|
||||
|
||||
Export type DisplayMode = 'kiosk' | 'remote' | 'remote-hd';
|
||||
</action>
|
||||
<verify>
|
||||
<automated>grep -q "remote-hd" sample_interface/src/app/hooks/useDisplayMode.ts && echo "PASS: remote-hd type added" || echo "FAIL: remote-hd not found"</automated>
|
||||
<automated>grep -q "port === '9999'" sample_interface/src/app/hooks/useDisplayMode.ts && echo "PASS: port 9999 check added" || echo "FAIL: port 9999 check not found"</automated>
|
||||
</verify>
|
||||
<done>DisplayMode type includes 'remote-hd', port 9999 returns 'remote-hd' mode</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>task 2: Update start.sh for dual-mode default and dev:9999 option</name>
|
||||
<files>start.sh</files>
|
||||
<action>
|
||||
1. Add new menu option "4) dev:9999" after dev:9090 (renumber existing options 4-10 to 5-11)
|
||||
2. Add case handler for "4|dev:9999" that runs dev server on port 9999
|
||||
3. Modify the script to detect when NO arguments are provided (interactive menu mode is already handled by the while loop at the end)
|
||||
4. When no arguments provided AND not in interactive mode, default to starting BOTH servers:
|
||||
- Start dev server on port 8888 in background
|
||||
- Start dev server on port 9999 in background
|
||||
- Show connection info for both ports
|
||||
- Wait for both processes
|
||||
5. Update the show_menu() function to include the new option and renumber others
|
||||
|
||||
The key change is in the argument parsing section - when $# -eq 0, instead of going to the interactive menu, it should start both servers. Add a check at the beginning for a "--dual" flag or similar to trigger dual mode.
|
||||
|
||||
Actually, simpler approach: When run with no arguments, start both servers in background and show info for both.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>grep -q "dev:9999" start.sh && echo "PASS: dev:9999 menu option exists" || echo "FAIL: dev:9999 not found"</automated>
|
||||
<automated>grep -q "9999" start.sh && grep -q "8888" start.sh && echo "PASS: Both ports referenced" || echo "FAIL: Missing port reference"</automated>
|
||||
<automated>bash -n start.sh && echo "PASS: start.sh syntax valid" || echo "FAIL: Syntax error in start.sh"</automated>
|
||||
</verify>
|
||||
<done>start.sh has dev:9999 menu option, starts both 8888 and 9999 by default when run without arguments</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>task 3: Update documentation (README.md, WIKI.md, install_everything.sh)</name>
|
||||
<files>README.md, WIKI.md, install_everything.sh</files>
|
||||
<action>
|
||||
Update all three files to document:
|
||||
1. Port 9999 as "remote HD" mode for Full HD desktop interface
|
||||
2. Dual-mode default behavior (8888 + 9999 both start when running ./start.sh without arguments)
|
||||
3. Update port tables to include 9999
|
||||
|
||||
README.md changes:
|
||||
- Add port 9999 to the "Display Modes" table
|
||||
- Update "Essential files to run" section to mention dual-mode default
|
||||
- Add note that ./start.sh without args starts both servers
|
||||
|
||||
WIKI.md changes:
|
||||
- Add "Remote HD Mode (Port 9999)" section after Remote Mode
|
||||
- Update Display Modes section with port 9999 info
|
||||
- Update Start Script Options table to include dev:9999
|
||||
- Update Installation Script section to mention dual-mode
|
||||
|
||||
install_everything.sh changes:
|
||||
- Update final message to mention both ports will be available
|
||||
- Add comments about dual-mode behavior
|
||||
</action>
|
||||
<verify>
|
||||
<automated>grep -q "9999" README.md && echo "PASS: README.md mentions port 9999" || echo "FAIL: README.md missing port 9999"</automated>
|
||||
<automated>grep -q "9999" WIKI.md && echo "PASS: WIKI.md mentions port 9999" || echo "FAIL: WIKI.md missing port 9999"</automated>
|
||||
<automated>grep -qi "dual" README.md && echo "PASS: README.md mentions dual mode" || echo "FAIL: README.md missing dual mode"</automated>
|
||||
</verify>
|
||||
<done>All documentation files updated with port 9999 and dual-mode default behavior</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- useDisplayMode.ts recognizes port 9999 as 'remote-hd'
|
||||
- start.sh runs both 8888 and 9999 when invoked without arguments
|
||||
- start.sh menu includes dev:9999 option
|
||||
- README.md, WIKI.md, and install_everything.sh document the new port and dual-mode behavior
|
||||
- All scripts have valid bash syntax
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Port 9999 is recognized as 'remote-hd' display mode in useDisplayMode hook
|
||||
- ./start.sh without arguments starts both 8888 and 9999 servers concurrently
|
||||
- ./start.sh dev:9999 starts server on port 9999
|
||||
- Documentation in README.md, WIKI.md, and install_everything.sh is updated with port 9999 and dual-mode info
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/quick/4-create-full-remote-hd-web-interface-at-p/4-SUMMARY.md`
|
||||
</output>
|
||||
@@ -1,126 +0,0 @@
|
||||
---
|
||||
phase: quick
|
||||
plan: 4
|
||||
subsystem: display-modes
|
||||
tags: [port-9999, remote-hd, dual-mode, start-script]
|
||||
dependency_graph:
|
||||
requires: []
|
||||
provides:
|
||||
- port-9999-remote-hd-mode
|
||||
- dual-mode-default-startup
|
||||
- dev-9999-menu-option
|
||||
affects:
|
||||
- useDisplayMode hook
|
||||
- start.sh
|
||||
- README.md
|
||||
- WIKI.md
|
||||
- install_everything.sh
|
||||
tech_stack:
|
||||
added: []
|
||||
patterns:
|
||||
- Dual-mode concurrent server startup (background processes)
|
||||
- Port-based display mode detection
|
||||
key_files:
|
||||
created: []
|
||||
modified:
|
||||
- sample_interface/src/app/hooks/useDisplayMode.ts
|
||||
- start.sh
|
||||
- README.md
|
||||
- WIKI.md
|
||||
- install_everything.sh
|
||||
decisions:
|
||||
- "Port 9999 = Remote HD display mode (Full HD responsive for desktop)"
|
||||
- "Port 8888 = Kiosk display mode (1024x600 fixed for touchscreen)"
|
||||
- "Port 9090 = Legacy Remote mode (kept for compatibility)"
|
||||
- "No arguments to start.sh = dual-mode (both 8888 + 9999)"
|
||||
- "dev:9999 menu option for single remote HD mode"
|
||||
metrics:
|
||||
duration: "<1 min"
|
||||
completed: "2026-03-19"
|
||||
---
|
||||
|
||||
# Quick Task 4: Create Full Remote HD Web Interface at Port 9999 Summary
|
||||
|
||||
## One-liner
|
||||
|
||||
Added port 9999 as "remote HD" display mode with dual-mode default startup (8888 kiosk + 9999 remote HD).
|
||||
|
||||
## Completed Tasks
|
||||
|
||||
| task | Name | Commit | Files |
|
||||
|------|------|--------|-------|
|
||||
| 1 | Update useDisplayMode hook for port 9999 | 0f281567 | useDisplayMode.ts |
|
||||
| 2 | Update start.sh for dual-mode default and dev:9999 option | 3b1ece0e | start.sh |
|
||||
| 3 | Update documentation (README.md, WIKI.md, install_everything.sh) | 9f29b51c | README.md, WIKI.md, install_everything.sh |
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. useDisplayMode.ts
|
||||
- Added `remote-hd` to `DisplayMode` type: `'kiosk' | 'remote' | 'remote-hd'`
|
||||
- Updated `useDisplayMode()` to return `'remote-hd'` when port is `'9999'`
|
||||
- Updated `getDisplayMode()` to return `'remote-hd'` when port is `'9999'`
|
||||
- Port 9090 continues to return `'remote'`
|
||||
- All other ports return `'kiosk'` (default)
|
||||
|
||||
### 2. start.sh
|
||||
- Added menu option `4) dev:9999` for remote HD mode
|
||||
- Renumbered menu options 5-11 to accommodate
|
||||
- Added `run_dual_mode()` function that:
|
||||
- Starts kiosk server on port 8888 (background)
|
||||
- Starts remote HD server on port 9999 (background)
|
||||
- Shows connection info for both modes
|
||||
- Waits for both processes
|
||||
- Modified script to call `run_dual_mode()` when run without arguments (replaced interactive menu)
|
||||
|
||||
### 3. Documentation Updates
|
||||
|
||||
**README.md:**
|
||||
- Updated "Essential files to run" section with dual-mode default behavior
|
||||
- Updated dual-mode display section to show port 9999 as Remote HD
|
||||
- Updated Display Modes table to include port 9999 and dual-mode note
|
||||
|
||||
**WIKI.md:**
|
||||
- Added "Remote HD Mode (Port 9999)" section with full HD details
|
||||
- Updated Start Script Options table with dev:9999 option and dual-mode
|
||||
- Clarified port usage across modes
|
||||
|
||||
**install_everything.sh:**
|
||||
- Added dual-mode server information to startup message
|
||||
- Shows both ports (8888 kiosk, 9999 remote HD) in success message
|
||||
|
||||
## Verification
|
||||
|
||||
All automated checks passed:
|
||||
- ✅ `remote-hd` type added to useDisplayMode.ts
|
||||
- ✅ Port 9999 check added to useDisplayMode.ts
|
||||
- ✅ `dev:9999` menu option exists in start.sh
|
||||
- ✅ Both ports 8888 and 9999 referenced in start.sh
|
||||
- ✅ start.sh syntax valid (bash -n passed)
|
||||
- ✅ README.md mentions port 9999
|
||||
- ✅ WIKI.md mentions port 9999
|
||||
- ✅ README.md mentions dual mode
|
||||
|
||||
## Success Criteria Met
|
||||
|
||||
- [x] Port 9999 is recognized as 'remote-hd' display mode in useDisplayMode hook
|
||||
- [x] `./start.sh` without arguments starts both 8888 and 9999 servers concurrently
|
||||
- [x] `./start.sh dev:9999` starts server on port 9999
|
||||
- [x] Documentation in README.md, WIKI.md, and install_everything.sh is updated with port 9999 and dual-mode info
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - plan executed exactly as written.
|
||||
|
||||
## Commits
|
||||
|
||||
```
|
||||
0f281567 feat(quick-4): add remote-hd display mode for port 9999
|
||||
3b1ece0e feat(quick-4): update start.sh for dual-mode and dev:9999
|
||||
9f29b51c docs(quick-4): update documentation for port 9999 and dual-mode
|
||||
```
|
||||
|
||||
## Self-Check
|
||||
|
||||
- [x] Files created/modified exist at specified paths
|
||||
- [x] Commit hashes verified in git log
|
||||
- [x] All verification commands passed
|
||||
@@ -1,76 +0,0 @@
|
||||
# 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.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
# 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)
|
||||
43
README.md
43
README.md
@@ -1,40 +1,13 @@
|
||||
# TCK RTU - Rainfall Monitoring Web Interface
|
||||
|
||||
A modern, web-based interface for Base Station/Real-Time Unit (RTU) monitoring rainfall and related sensors. Designed for 7" capacitive touchscreen display (1024x600) on Raspberry Pi CM5, Zero 2 W/3B, running via Chromium Kiosk Mode.
|
||||
|
||||
## QUICKSTART
|
||||
A modern, web-based interface for Base Station/Real-Time Unit (RTU) monitoring rainfall and related sensors. Designed for 7" capacitive touchscreen display (1024x600) on Raspberry Pi Zero 2 W/3B, running via Chromium Kiosk Mode.
|
||||
|
||||
```bash
|
||||
# ONE LINE INSTALL & RUN
|
||||
curl -sL http://gitck:3000/admin/sp80/install_everything.sh | bash
|
||||
curl -sL http://tckrtuiyo:3000/tck/tck_rtu/install_everything.sh | bash
|
||||
```
|
||||
|
||||
# Essential files to run
|
||||
```bash
|
||||
# Start both servers (kiosk 8888 + remote HD 9999) - DEFAULT BEHAVIOR
|
||||
./start.sh
|
||||
|
||||
# Or start just kiosk mode on port 8888
|
||||
./start.sh dev:8888
|
||||
|
||||
# Or start just remote HD mode on port 9999
|
||||
./start.sh dev:9999
|
||||
|
||||
# Flip the display, a bug in Waveshare 1024x600 7" Touchscreen HDMI (c) LCD
|
||||
# Prerequisite: apt install -y xrandr xinput
|
||||
./flip_display.sh
|
||||
|
||||
# Run during (after) boot as systemd service
|
||||
cp rtu-dev.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
systemctl enable rtu-dev.service
|
||||
systemctl start rtu-dev.service
|
||||
|
||||
# Check status of rtu-dev
|
||||
journalctl -u rtu-dev.service -f
|
||||
```
|
||||
|
||||
[View Full Wiki](WIKI.md) | [Integration with C++](INTEGRATION.md) | [Example Code](EXAMPLE_CODE.md)
|
||||
[View full Wiki](WIKI.md)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -42,9 +15,8 @@ journalctl -u rtu-dev.service -f
|
||||
- Solar and battery voltage monitoring with status indicators
|
||||
- Station information display (ID, version, communication status)
|
||||
- Dual-mode display:
|
||||
- **Kiosk mode** (port 8888): 1024x600 for local 7" touchscreen
|
||||
- **Remote HD mode** (port 9999): Full HD responsive for PC access
|
||||
- **Remote mode** (port 9090): Standard remote access
|
||||
- **Kiosk mode** (port 8080): 1024x600 for local 7" touchscreen
|
||||
- **Remote mode** (port 9090): Full HD responsive for PC access
|
||||
- Touch-friendly UI with 44px+ touch targets
|
||||
- Modern React/TypeScript architecture with Zustand state management
|
||||
|
||||
@@ -202,12 +174,9 @@ The app detects display mode by port:
|
||||
| Port | Mode | Resolution |
|
||||
|------|------|------------|
|
||||
| 8888 | Kiosk | 1024x600 (fixed, for 7" touchscreen) |
|
||||
| 9090 | Remote | Standard remote access |
|
||||
| 9999 | Remote HD | Full HD (responsive, for PC access) |
|
||||
| 9090 | Remote | Full HD (responsive, for PC access) |
|
||||
| 5173 | Dev | Development server |
|
||||
|
||||
**Note:** Running `./start.sh` without arguments starts both kiosk (8888) and remote HD (9999) servers.
|
||||
|
||||
## Bundle Size
|
||||
|
||||
- **Target**: < 170KB gzipped
|
||||
|
||||
30
WIKI.md
30
WIKI.md
@@ -204,18 +204,10 @@ When the API is unavailable, mock data is automatically generated with realistic
|
||||
### Remote Mode (Port 9090)
|
||||
|
||||
- Responsive layout for any screen size
|
||||
- Standard remote access
|
||||
- **For legacy remote access via network**
|
||||
|
||||
### Remote HD Mode (Port 9999)
|
||||
|
||||
- Full HD responsive layout (1920x1080 optimized)
|
||||
- Full HD optimized
|
||||
- Expanded information display
|
||||
- Standard scrollbars
|
||||
- **For remote desktop access with high-resolution displays**
|
||||
- **Recommended for remote monitoring via PC browser**
|
||||
|
||||
**Note:** Running `./start.sh` without arguments starts both Kiosk (8888) and Remote HD (9999) servers simultaneously.
|
||||
- **For remote access via network**
|
||||
|
||||
## Navigation
|
||||
|
||||
@@ -392,19 +384,17 @@ The `start.sh` script provides an interactive menu for common development comman
|
||||
| `1` or `dev` | Start dev server (port 5173) |
|
||||
| `2` or `dev:8888` | Start dev server on port 8888 (kiosk mode) |
|
||||
| `3` or `dev:9090` | Start dev server on port 9090 (remote mode) |
|
||||
| `4` or `dev:9999` | Start dev server on port 9999 (remote HD mode) |
|
||||
| `5` or `test` | Run tests |
|
||||
| `6` or `test:watch` | Run tests in watch mode |
|
||||
| `7` or `build` | Build for production |
|
||||
| `8` or `preview` | Preview production (port 4173) |
|
||||
| `9` or `lint` | Run linter |
|
||||
| `10` or `clean` | Clean build artifacts |
|
||||
| `11` or `install` | Install dependencies |
|
||||
| `4` or `test` | Run tests |
|
||||
| `5` or `test:watch` | Run tests in watch mode |
|
||||
| `6` or `build` | Build for production |
|
||||
| `7` or `preview` | Preview production (port 4173) |
|
||||
| `8` or `lint` | Run linter |
|
||||
| `9` or `clean` | Clean build artifacts |
|
||||
| `10` or `install` | Install dependencies |
|
||||
| `p` or `port` | Change default ports |
|
||||
| `0` or `exit` | Exit |
|
||||
| (no args) | Start both 8888 and 9999 (dual-mode) |
|
||||
|
||||
**Note**: Port 8888 is for kiosk mode (7" touchscreen), port 9090 for legacy remote, port 9999 for remote HD desktop access. Running without arguments starts dual-mode.
|
||||
**Note**: Port 8888 is recommended for kiosk mode (7" touchscreen), port 9090 for remote access.
|
||||
|
||||
## Installation Script
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/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
|
||||
@@ -150,16 +150,10 @@ start_app() {
|
||||
echo -e "${GREEN}Installation complete!${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN} Dual-mode servers will be available:${NC}"
|
||||
echo -e "${GREEN} - Kiosk (port 8888): 7\" touchscreen display${NC}"
|
||||
echo -e "${GREEN} - Remote HD (port 9999): Full HD desktop access${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo -e "Starting TCK RTU in dual-mode..."
|
||||
echo -e "Starting TCK RTU menu..."
|
||||
echo ""
|
||||
|
||||
# Run start.sh (starts dual-mode by default)
|
||||
# Run start.sh
|
||||
./start.sh
|
||||
}
|
||||
|
||||
|
||||
@@ -7,37 +7,37 @@
|
||||
},
|
||||
"agent": {
|
||||
"gsd-planner": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-plan-checker": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-phase-researcher": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-roadmapper": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-project-researcher": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-research-synthesizer": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-codebase-mapper": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/kimi-k2.5"
|
||||
},
|
||||
"gsd-executor": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/minimax-m2.5"
|
||||
},
|
||||
"gsd-debugger": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/minimax-m2.5"
|
||||
},
|
||||
"gsd-verifier": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/glm-5"
|
||||
},
|
||||
"gsd-integration-checker": {
|
||||
"model": "zai-coding-plan/glm-5"
|
||||
"model": "opencode-go/glm-5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ export function HelpView() {
|
||||
const element = document.getElementById(id);
|
||||
const panel = document.getElementById("details-panel");
|
||||
if (element && panel) {
|
||||
panel.scrollTo({
|
||||
top: element.offsetTop - panel.offsetTop - 16,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
const panelRect = panel.getBoundingClientRect();
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
const offset = elementRect.top - panelRect.top + panel.scrollTop;
|
||||
panel.scrollTop = offset;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@ export function HelpView() {
|
||||
|
||||
return (
|
||||
<div className="h-full overflow-y-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[1fr_3fr] gap-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<div className="bg-gray-900 border border-gray-700 rounded-lg p-4 sticky top-0">
|
||||
<h2 className="text-xl font-bold text-white mb-4">Table of Contents</h2>
|
||||
<nav className="space-y-2">
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
import { Components } from 'react-markdown';
|
||||
import React from 'react';
|
||||
|
||||
function getTextContent(children: React.ReactNode): string {
|
||||
if (typeof children === 'string') return children;
|
||||
if (Array.isArray(children)) return children.map(getTextContent).join('');
|
||||
if (React.isValidElement(children) && children.props.children) {
|
||||
return getTextContent(children.props.children);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export const components: Components = {
|
||||
h1: ({ children, ...props }) => {
|
||||
const text = getTextContent(children);
|
||||
h1: ({ node, children, ...props }) => {
|
||||
const text = Array.isArray(children) ? children.join('') : String(children);
|
||||
const id = text.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
||||
return <h1 id={id} {...props}>{children}</h1>;
|
||||
},
|
||||
h2: ({ children, ...props }) => {
|
||||
const text = getTextContent(children);
|
||||
h2: ({ node, children, ...props }) => {
|
||||
const text = Array.isArray(children) ? children.join('') : String(children);
|
||||
const id = text.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
||||
return <h2 id={id} {...props}>{children}</h2>;
|
||||
},
|
||||
h3: ({ children, ...props }) => {
|
||||
const text = getTextContent(children);
|
||||
h3: ({ node, children, ...props }) => {
|
||||
const text = Array.isArray(children) ? children.join('') : String(children);
|
||||
const id = text.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
||||
return <h3 id={id} {...props}>{children}</h3>;
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export type DisplayMode = 'kiosk' | 'remote' | 'remote-hd';
|
||||
export type DisplayMode = 'kiosk' | 'remote';
|
||||
|
||||
export function useDisplayMode(): DisplayMode {
|
||||
return useMemo(() => {
|
||||
@@ -10,10 +10,6 @@ export function useDisplayMode(): DisplayMode {
|
||||
|
||||
const port = window.location.port;
|
||||
|
||||
if (port === '9999') {
|
||||
return 'remote-hd';
|
||||
}
|
||||
|
||||
if (port === '9090') {
|
||||
return 'remote';
|
||||
}
|
||||
@@ -29,10 +25,6 @@ export function getDisplayMode(): DisplayMode {
|
||||
|
||||
const port = window.location.port;
|
||||
|
||||
if (port === '9999') {
|
||||
return 'remote-hd';
|
||||
}
|
||||
|
||||
if (port === '9090') {
|
||||
return 'remote';
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ After=network.target
|
||||
#Before=nextcloud-web.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/root/rtu_v5/start.sh dev:8888
|
||||
ExecStart=/root/rtu_v4/start.sh dev:8888
|
||||
#ExecReload=/root/rtu_v4/start.sh dev:8888
|
||||
Type=simple
|
||||
Restart=always
|
||||
86
start.sh
86
start.sh
@@ -3,16 +3,6 @@
|
||||
# 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
|
||||
@@ -40,17 +30,16 @@ echo -e "${NC}"
|
||||
show_menu() {
|
||||
echo -e "${BOLD}Select an option:${NC}"
|
||||
echo ""
|
||||
echo -e " ${GREEN}1)${NC} dev Start dual-mode (8888 kiosk + 9999 remote HD)"
|
||||
echo -e " ${GREEN}1)${NC} dev Start development server (port $DEV_PORT)"
|
||||
echo -e " ${GREEN}2)${NC} dev:8888 Start dev server on port 8888 (kiosk mode)"
|
||||
echo -e " ${GREEN}3)${NC} dev:9090 Start dev server on port 9090 (remote mode)"
|
||||
echo -e " ${GREEN}4)${NC} dev:9999 Start dev server on port 9999 (remote HD mode)"
|
||||
echo -e " ${GREEN}5)${NC} test Run tests"
|
||||
echo -e " ${GREEN}6)${NC} test:watch Run tests in watch mode"
|
||||
echo -e " ${GREEN}7)${NC} build Build for production"
|
||||
echo -e " ${GREEN}8)${NC} preview Preview production (port $PREVIEW_PORT)"
|
||||
echo -e " ${GREEN}9)${NC} lint Run linter"
|
||||
echo -e " ${GREEN}10)${NC} clean Clean build artifacts"
|
||||
echo -e " ${GREEN}11)${NC} install Install dependencies"
|
||||
echo -e " ${GREEN}4)${NC} test Run tests"
|
||||
echo -e " ${GREEN}5)${NC} test:watch Run tests in watch mode"
|
||||
echo -e " ${GREEN}6)${NC} build Build for production"
|
||||
echo -e " ${GREEN}7)${NC} preview Preview production (port $PREVIEW_PORT)"
|
||||
echo -e " ${GREEN}8)${NC} lint Run linter"
|
||||
echo -e " ${GREEN}9)${NC} clean Clean build artifacts"
|
||||
echo -e " ${GREEN}10)${NC} install Install dependencies"
|
||||
echo -e " ${GREEN}p)${NC} port Change default port"
|
||||
echo ""
|
||||
echo -e " ${RED}0)${NC} Exit"
|
||||
@@ -107,44 +96,6 @@ run_preview_server() {
|
||||
wait $PREVIEW_PID
|
||||
}
|
||||
|
||||
run_dual_mode() {
|
||||
local IP=$(get_ip_address)
|
||||
echo -e "${CYAN}${BOLD}"
|
||||
echo "╔══════════════════════════════════════════════════════╗"
|
||||
echo "║ TCK RTU - Dual Mode (Kiosk + Remote HD) ║"
|
||||
echo "╚══════════════════════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
echo -e "${BLUE}Starting servers on ports 8888 and 9999...${NC}"
|
||||
echo -e "${YELLOW}(Press Ctrl+C to stop both servers)${NC}"
|
||||
echo ""
|
||||
|
||||
# Start kiosk server on port 8888
|
||||
cd "$PROJECT_DIR"
|
||||
npm run dev -- --host --port 8888 &
|
||||
KIOSK_PID=$!
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN} Kiosk Server (8888) started (PID: $KIOSK_PID)${NC}"
|
||||
|
||||
# Start remote HD server on port 9999
|
||||
npm run dev -- --host --port 9999 &
|
||||
REMOTE_PID=$!
|
||||
echo -e "${GREEN} Remote HD Server (9999) started (PID: $REMOTE_PID)${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN} Dual-mode servers running:${NC}"
|
||||
echo -e "${GREEN} - Kiosk (local touchscreen): http://localhost:8888${NC}"
|
||||
echo -e "${GREEN} - Remote HD (desktop): http://localhost:9999${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN} - Network Kiosk: http://$IP:8888${NC}"
|
||||
echo -e "${GREEN} - Network Remote HD: http://$IP:9999${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
|
||||
# Wait for both processes
|
||||
wait $KIOSK_PID $REMOTE_PID
|
||||
}
|
||||
|
||||
change_port() {
|
||||
echo -e "${BOLD}Change Default Port${NC}"
|
||||
echo ""
|
||||
@@ -172,7 +123,7 @@ run_command() {
|
||||
|
||||
case $option in
|
||||
1|dev)
|
||||
run_dual_mode
|
||||
run_dev_server $DEV_PORT
|
||||
;;
|
||||
2|dev:8888)
|
||||
run_dev_server 8888
|
||||
@@ -180,36 +131,33 @@ run_command() {
|
||||
3|dev:9090)
|
||||
run_dev_server 9090
|
||||
;;
|
||||
4|dev:9999)
|
||||
run_dev_server 9999
|
||||
;;
|
||||
5|test)
|
||||
4|test)
|
||||
echo -e "${BLUE}Running tests...${NC}"
|
||||
npm test
|
||||
;;
|
||||
6|test:watch)
|
||||
5|test:watch)
|
||||
echo -e "${BLUE}Running tests in watch mode...${NC}"
|
||||
npm run test:watch
|
||||
;;
|
||||
7|build)
|
||||
6|build)
|
||||
echo -e "${BLUE}Building for production...${NC}"
|
||||
npm run build
|
||||
echo -e "${GREEN}Build complete!${NC}"
|
||||
;;
|
||||
8|preview)
|
||||
7|preview)
|
||||
run_preview_server $PREVIEW_PORT
|
||||
;;
|
||||
9|lint)
|
||||
8|lint)
|
||||
echo -e "${BLUE}Running linter...${NC}"
|
||||
npm run lint
|
||||
;;
|
||||
10|clean)
|
||||
9|clean)
|
||||
echo -e "${YELLOW}Cleaning build artifacts...${NC}"
|
||||
rm -rf "$PROJECT_DIR/dist"
|
||||
rm -rf "$PROJECT_DIR/node_modules/.vite"
|
||||
echo -e "${GREEN}Clean complete!${NC}"
|
||||
;;
|
||||
11|install)
|
||||
10|install)
|
||||
echo -e "${BLUE}Installing dependencies...${NC}"
|
||||
npm install
|
||||
echo -e "${GREEN}Dependencies installed!${NC}"
|
||||
@@ -255,7 +203,7 @@ fi
|
||||
# Interactive menu
|
||||
while true; do
|
||||
show_menu
|
||||
echo -n -e "${BOLD}Enter your choice (0-11 or p): ${NC}"
|
||||
echo -n -e "${BOLD}Enter your choice (0-10 or p): ${NC}"
|
||||
read -r choice
|
||||
echo ""
|
||||
run_command "$choice"
|
||||
|
||||
Reference in New Issue
Block a user