README.md: - Update Essential files section with dual-mode default behavior - Update dual-mode display section with port 9999 as Remote HD - Update Display Modes table to include port 9999 and dual-mode note WIKI.md: - Add Remote HD Mode (Port 9999) section with full HD details - Update Start Script Options table with dev:9999 and dual-mode - Clarify port usage (8888 kiosk, 9090 legacy remote, 9999 remote HD) install_everything.sh: - Add dual-mode server information to startup message
589 lines
18 KiB
Markdown
589 lines
18 KiB
Markdown
# TCK RTU - Technical Documentation
|
|
|
|
## Table of Contents
|
|
|
|
- [Overview](#overview)
|
|
- [System Architecture](#system-architecture)
|
|
- [Hardware Requirements](#hardware-requirements)
|
|
- [Software Architecture](#software-architecture)
|
|
- [Components](#components)
|
|
- [Dashboard Components](#dashboard-components)
|
|
- [View Components](#view-components)
|
|
- [Data Flow](#data-flow)
|
|
- [API Client](#api-client)
|
|
- [Endpoint](#endpoint)
|
|
- [Response Format](#response-format)
|
|
- [Mock Data](#mock-data)
|
|
- [Display Modes](#display-modes)
|
|
- [Kiosk Mode (Port 8888)](#kiosk-mode-port-8888)
|
|
- [Remote Mode (Port 9090)](#remote-mode-port-9090)
|
|
- [Navigation](#navigation)
|
|
- [Menu Structure](#menu-structure)
|
|
- [View Components List](#view-components-list)
|
|
- [State Management](#state-management)
|
|
- [Zustand Store Structure](#zustand-store-structure)
|
|
- [Usage](#usage)
|
|
- [Testing](#testing)
|
|
- [Test Infrastructure](#test-infrastructure)
|
|
- [Running Tests](#running-tests)
|
|
- [Test Structure](#test-structure)
|
|
- [Performance](#performance)
|
|
- [Bundle Size Targets](#bundle-size-targets)
|
|
- [Optimizations](#optimizations)
|
|
- [Performance Tips](#performance-tips)
|
|
- [Deployment](#deployment)
|
|
- [Build](#build)
|
|
- [Output](#output)
|
|
- [Production Server](#production-server)
|
|
- [Start Script](#start-script)
|
|
- [Usage](#start-script-usage)
|
|
- [Options](#start-script-options)
|
|
- [Installation Script](#installation-script)
|
|
- [Quick Install](#quick-install)
|
|
- [Web Server Setup](#web-server-setup)
|
|
- [Manual Install](#manual-install)
|
|
- [UI Design Decisions](#ui-design-decisions)
|
|
- [Layout Principles](#layout-principles)
|
|
- [Touch Targets](#touch-targets)
|
|
- [Color Scheme](#color-scheme)
|
|
- [User Flow](#user-flow)
|
|
- [Kiosk Mode Flow](#kiosk-mode-flow)
|
|
- [Navigation Buttons](#navigation-buttons)
|
|
- [Future Phases](#future-phases)
|
|
- [Phase 2: Settings Framework](#phase-2-settings-framework)
|
|
- [Phase 3: Data Management & Network Stack](#phase-3-data-management--network-stack)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [Common Issues](#common-issues)
|
|
- [Development Tools](#development-tools)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
TCKRTUIYO is a web-based interface for Base Station/Real-Time Unit (RTU) monitoring rainfall and related sensors. The system is designed to run on Raspberry Pi Zero 2 W with a 7" capacitive touchscreen display.
|
|
|
|
## System Architecture
|
|
|
|
### Hardware Requirements
|
|
|
|
- **Raspberry Pi**: Zero 2 W or 3B
|
|
- **Display**: 7" capacitive touchscreen, 1024x600 resolution
|
|
- **Storage**: MicroSD card for OS and data
|
|
- **Network**: Ethernet or WiFi for data transmission
|
|
|
|
### Software Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Web Browser (Chromium) │
|
|
│ Kiosk Mode / Remote │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ React Application │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
│ │Dashboard │ │ Settings │ │Calibration│ │ Memory │ │
|
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ State Management (Zustand) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ API Client (with Mock Fallback) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Python Backend (TBD) │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Components
|
|
|
|
### Dashboard Components
|
|
|
|
| Component | File | Description |
|
|
|-----------|------|-------------|
|
|
| RainfallCard | `RainfallCard.tsx` | Displays rainfall metrics with color coding |
|
|
| ClockDisplay | `ClockDisplay.tsx` | Real-time clock and date |
|
|
| CommStatus | `CommStatus.tsx` | Communication signal status |
|
|
| VoltageDisplay | `VoltageDisplay.tsx` | Solar voltage display |
|
|
| BatteryStatus | `BatteryStatus.tsx` | Battery voltage with status indicator |
|
|
| LoginIndicator | `LoginIndicator.tsx` | Login status display |
|
|
|
|
### View Components
|
|
|
|
| View | File | Description |
|
|
|------|------|-------------|
|
|
| Dashboard | `DashboardView.tsx` | Main rainfall monitoring display |
|
|
| Graph | `GraphView.tsx` | Data visualization with charts |
|
|
| Utility | `UtilityView.tsx` | Additional utility functions |
|
|
| Calibration | `CalibrationView.tsx` | Sensor calibration interface |
|
|
| FlashMemory | `FlashMemoryView.tsx` | Data storage management |
|
|
| Setting | `SettingView.tsx` | Main settings hub |
|
|
| Login | `LoginView.tsx` | Authentication interface |
|
|
|
|
### Settings Sub-Views
|
|
|
|
| Setting | File | Description |
|
|
|---------|------|-------------|
|
|
| Station Info | `StationInfoView.tsx` | Station ID, version info |
|
|
| Date/Time | `DateTimeSettingView.tsx` | Date, time, timezone configuration |
|
|
| Mobile | `MobileSettingView.tsx` | Mobile network (SIM) settings |
|
|
| ADC | `ADCSettingView.tsx` | ADC calibration |
|
|
| Rainfall | `RainfallSettingView.tsx` | Rainfall sensor settings |
|
|
| EVAP | `EVAPSettingView.tsx` | Evaporation sensor settings |
|
|
| GPRS | `GPRSSettingView.tsx` | GPRS configuration |
|
|
| Level | `LevelSettingView.tsx` | Water level sensor settings |
|
|
| Siren | `SirenSettingView.tsx` | Alarm/siren configuration |
|
|
| Network | `NetworkSettingView.tsx` | WiFi/Ethernet settings |
|
|
|
|
### Data Flow
|
|
|
|
1. **Sensor Data Collection**
|
|
- API client fetches data from backend
|
|
- Falls back to mock data if API unavailable
|
|
- Polling interval: 5 seconds (configurable)
|
|
|
|
2. **State Management**
|
|
- Zustand store holds all sensor data
|
|
- Components subscribe to relevant slices
|
|
- Changes trigger re-renders
|
|
|
|
3. **Display Updates**
|
|
- Real-time updates via polling
|
|
- Page Visibility API pauses polling when hidden
|
|
- Proper cleanup on unmount
|
|
|
|
## API Client
|
|
|
|
### Endpoint
|
|
|
|
```
|
|
GET /api/sensor-data
|
|
```
|
|
|
|
### Response Format
|
|
|
|
```json
|
|
{
|
|
"rainfall": {
|
|
"today": 12.5,
|
|
"hourly": 2.3,
|
|
"monthlyAcc": 156.8,
|
|
"yearlyAcc": 1847.2
|
|
},
|
|
"voltage": {
|
|
"solar": 12.4,
|
|
"battery": 12.8,
|
|
"batteryStatus": "HIGH"
|
|
},
|
|
"station": {
|
|
"id": "D007",
|
|
"version": "v4.0.4"
|
|
},
|
|
"communication": {
|
|
"asu": 15,
|
|
"dBm": -75,
|
|
"percentage": 50
|
|
},
|
|
"timestamp": "2026-03-13T12:00:00Z"
|
|
}
|
|
```
|
|
|
|
### Mock Data
|
|
|
|
When the API is unavailable, mock data is automatically generated with realistic values:
|
|
- Rainfall: Random values 0-25mm
|
|
- Battery: Random values 11.5-13.5V
|
|
- Signal: Random ASU 0-31
|
|
|
|
## Display Modes
|
|
|
|
### Kiosk Mode (Port 8888)
|
|
|
|
- Fixed resolution: 1024x600
|
|
- Optimized for 7" touchscreen
|
|
- Compact layouts with 44px+ touch targets
|
|
- No scrollbars - navigation buttons instead
|
|
- **Primary mode for local touchscreen display**
|
|
|
|
### 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)
|
|
- 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.
|
|
|
|
## Navigation
|
|
|
|
### Menu Structure
|
|
|
|
```
|
|
├── HOME (Rainfall Dashboard)
|
|
├── GRAPH (Data Visualization)
|
|
├── UTILITY (Settings)
|
|
│ ├── Station Info
|
|
│ ├── Date / Time
|
|
│ ├── Mobile
|
|
│ ├── ADC
|
|
│ ├── Rainfall
|
|
│ ├── EVAP
|
|
│ ├── GPRS
|
|
│ ├── Level
|
|
│ ├── SIREN
|
|
│ └── Network
|
|
├── CALIBRATION
|
|
├── FLASH MEMORY
|
|
├── SETTING
|
|
└── LOGIN
|
|
```
|
|
|
|
### View Components List
|
|
|
|
All views are located in `sample_interface/src/app/components/views/`:
|
|
|
|
- `DashboardView.tsx` - Main rainfall dashboard
|
|
- `GraphView.tsx` - Data visualization with chart
|
|
- `UtilityView.tsx` - Utility functions hub
|
|
- `CalibrationView.tsx` - Sensor calibration
|
|
- `FlashMemoryView.tsx` - File management
|
|
- `SettingView.tsx` - Settings hub (side-by-side Display & System settings)
|
|
- `LoginView.tsx` - Login interface
|
|
- Settings sub-views (StationInfo, DateTime, Mobile, ADC, Rainfall, EVAP, GPRS, Level, Siren, Network)
|
|
|
|
## State Management
|
|
|
|
### Zustand Store Structure
|
|
|
|
```typescript
|
|
interface SensorState {
|
|
data: SensorData;
|
|
pollingInterval: number;
|
|
isPolling: boolean;
|
|
lastError: string | null;
|
|
setSensorData: (data: Partial<SensorData>) => void;
|
|
updatePollingInterval: (interval: number) => void;
|
|
setIsPolling: (polling: boolean) => void;
|
|
setError: (error: string | null) => void;
|
|
}
|
|
```
|
|
|
|
### Usage
|
|
|
|
```typescript
|
|
import { useSensorStore } from './stores/sensorStore';
|
|
|
|
// Get all data
|
|
const { data } = useSensorStore();
|
|
|
|
// Get specific slice
|
|
const rainfall = useSensorStore(state => state.data.rainfall);
|
|
|
|
// Update data
|
|
const setSensorData = useSensorStore(state => state.setSensorData);
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Test Infrastructure
|
|
|
|
- **Framework**: Vitest
|
|
- **Testing Library**: @testing-library/react
|
|
- **Environment**: jsdom
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
npm test # Run once
|
|
npm run test:watch # Watch mode
|
|
```
|
|
|
|
### Test Structure
|
|
|
|
```
|
|
src/
|
|
├── app/
|
|
│ ├── stores/
|
|
│ │ └── __tests__/
|
|
│ │ └── sensorStore.test.ts
|
|
│ ├── api/
|
|
│ │ └── __tests__/
|
|
│ │ └── client.test.ts
|
|
│ └── components/
|
|
│ └── __tests__/
|
|
│ ├── Header.test.tsx
|
|
│ └── RainfallCard.test.tsx
|
|
└── test/
|
|
└── setup.ts
|
|
```
|
|
|
|
## Performance
|
|
|
|
### Bundle Size Targets
|
|
|
|
| Metric | Target | Current |
|
|
|--------|--------|---------|
|
|
| JS (gzip) | < 170KB | ~100KB |
|
|
| CSS (gzip) | < 20KB | ~15KB |
|
|
|
|
### Optimizations
|
|
|
|
- Code splitting for routes
|
|
- Tree shaking for unused code
|
|
- Image optimization
|
|
- CSS purging (Tailwind)
|
|
|
|
### Performance Tips
|
|
|
|
1. **Lazy Loading**: Routes are lazy-loaded
|
|
2. **Memoization**: Heavy computations memoized
|
|
3. **Virtualization**: Long lists virtualized
|
|
4. **Polling Control**: Pauses when tab hidden
|
|
|
|
## Deployment
|
|
|
|
### Build
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
### Output
|
|
|
|
```
|
|
dist/
|
|
├── index.html
|
|
└── assets/
|
|
├── index-xxxx.js
|
|
└── index-xxxx.css
|
|
```
|
|
|
|
### Production Server
|
|
|
|
Automagically: Just run `./start.sh` to serve the app.
|
|
|
|
Manually: Serve the `dist` folder with any static file server:
|
|
|
|
```bash
|
|
# Python
|
|
python -m http.server 8080
|
|
|
|
# Node
|
|
npx serve dist
|
|
```
|
|
|
|
## Start Script
|
|
|
|
The `start.sh` script provides an interactive menu for common development commands.
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
./start.sh [option]
|
|
```
|
|
|
|
### Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `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 |
|
|
| `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.
|
|
|
|
## Installation Script
|
|
|
|
The `install_everything.sh` script automates the entire installation process including:
|
|
- Installing system dependencies (curl, git, nginx)
|
|
- Installing Node.js 20.x
|
|
- Cloning the repository
|
|
- Installing npm dependencies
|
|
- Starting the application
|
|
|
|
### Quick Install
|
|
|
|
```bash
|
|
# Option 1: Clone and run locally
|
|
git clone https://github.com/your-repo/tck_rtu.git /opt/tck_rtu
|
|
cd /opt/tck_rtu
|
|
./install_everything.sh
|
|
|
|
# Option 2: From web server (see below)
|
|
curl -sL http://tckrtuiyo:3000/tck/tck_rtu/install_everything.sh | bash
|
|
|
|
# Option 3: From GitHub raw
|
|
curl -sL https://raw.githubusercontent.com/your-repo/main/install_everything.sh | bash
|
|
```
|
|
|
|
### Web Server Setup
|
|
|
|
To serve the install script from a local web server for Option 2:
|
|
|
|
```bash
|
|
# Method 1: Using Python (simple)
|
|
sudo mkdir -p /var/www/html/tck/tck_rtu
|
|
sudo cp install_everything.sh /var/www/html/tck/tck_rtu/
|
|
cd /var/www/html/tck/tck_rtu
|
|
sudo python3 -m http.server 3000
|
|
|
|
# Method 2: Using nginx
|
|
sudo cp install_everything.sh /var/www/html/tck/tck_rtu/
|
|
sudo systemctl start nginx
|
|
|
|
# Access via:
|
|
# http://<server-ip>:3000/tck/tck_rtu/install_everything.sh
|
|
# or
|
|
# http://tckrtuiyo:80/tck/tck_rtu/install_everything.sh
|
|
```
|
|
|
|
### Manual Install
|
|
|
|
If you prefer to install manually:
|
|
|
|
```bash
|
|
# 1. Install system dependencies (as root)
|
|
sudo apt-get update
|
|
sudo apt-get install -y curl git nginx
|
|
|
|
# 2. Install Node.js 20.x
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
|
|
sudo apt-get install -y nodejs
|
|
|
|
# 3. Clone repository
|
|
sudo mkdir -p /opt
|
|
sudo git clone https://github.com/your-repo/tck_rtu.git /opt/tck_rtu
|
|
|
|
# 4. Install dependencies
|
|
cd /opt/tck_rtu/sample_interface
|
|
sudo npm install
|
|
|
|
# 5. Run
|
|
cd /opt/tck_rtu
|
|
sudo ./start.sh
|
|
```
|
|
|
|
## UI Design Decisions
|
|
|
|
### Layout Principles
|
|
|
|
1. **Vertical Stacking**: Information flows top-to-bottom
|
|
2. **Controls at Bottom**: Interactive elements (buttons, inputs) placed at bottom for easy thumb access
|
|
3. **Summary at Top**: Key metrics and visualizations at top
|
|
4. **No Scrolling**: All content fits within 1024x600 viewport
|
|
|
|
### Touch Targets
|
|
|
|
- Minimum touch target: 44x44px
|
|
- Spacing between targets: 8px minimum
|
|
- Navigation buttons placed next to titles (not just in header)
|
|
|
|
### Color Scheme
|
|
|
|
- **Background**: Dark gray (#1a1a2e, #16213e)
|
|
- **Cards**: Slightly lighter gray (#0f3460, #1f4068)
|
|
- **Primary Accent**: Blue (#4d96ff, #3a86ff)
|
|
- **Text**: White/light gray for contrast
|
|
- **Status Colors**:
|
|
- Green: Good/normal
|
|
- Yellow/Orange: Warning
|
|
- Red: Critical/alert
|
|
|
|
## User Flow
|
|
|
|
### Kiosk Mode Flow
|
|
|
|
1. **Boot**: System starts, Chromium launches in kiosk mode
|
|
2. **Load**: App loads at http://localhost:8888
|
|
3. **Dashboard**: Shows rainfall data, clock, battery, signal
|
|
4. **Navigate**: Use side buttons to switch views
|
|
5. **Interact**: Touch screen for settings/siren tests
|
|
|
|
### Navigation Buttons
|
|
|
|
- **Horizontal placement**: Next to view titles (not just in header)
|
|
- **Clear labeling**: Icon + text for clarity
|
|
- **Consistent position**: Same location across all views
|
|
|
|
**Graph View Layout** (example):
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ [Icon] Graph View [↑] [↓] │ <- Header with nav buttons
|
|
├─────────────────────────────────────┤
|
|
│ Time Range | Data Pts | Avg Value │ <- Summary at top
|
|
├─────────────────────────────────────┤
|
|
│ │
|
|
│ Data Visualization │ <- Chart at bottom
|
|
│ │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
**Settings View Layout** (example):
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ [Icon] Setting [←] [→] │
|
|
├─────────────────────────────────────┤
|
|
│ Display Settings │ System Settings│ <- Side-by-side
|
|
├─────────────────────────────────────┤
|
|
│ Date │ Time │ Timezone │ <- Horizontal
|
|
├─────────────────────────────────────┤
|
|
│ Phone Number │ APN │ <- Horizontal (Mobile)
|
|
├─────────────────────────────────────┤
|
|
│ Enable EVAP │ Pan Coef │ Interval │ <- Horizontal (EVAP)
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
## Future Phases
|
|
|
|
### Phase 2: Settings Framework
|
|
- Station configuration
|
|
- Sensor calibration settings
|
|
- Network settings
|
|
- Mobile/GPRS configuration
|
|
|
|
### Phase 3: Data Management & Network Stack
|
|
- CSV file management
|
|
- Data export
|
|
- Network protocol support (FTP/SCP/SFTP/WEBDAV)
|
|
- TIEDA data transmission
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Build fails**
|
|
- Check Node.js version (18+ required)
|
|
- Clear node_modules and reinstall
|
|
|
|
2. **Bundle too large**
|
|
- Check for unused imports
|
|
- Verify tree shaking enabled
|
|
|
|
3. **API not connecting**
|
|
- Check backend is running
|
|
- Verify CORS settings
|
|
|
|
4. **Dev server wrong port**
|
|
- Use `--port` flag: `npm run dev -- --port 8888`
|
|
- Not `VITE_PORT=8888` (doesn't work with npm)
|
|
|
|
### Development Tools
|
|
|
|
- React DevTools
|
|
- Vite HMR
|
|
- Vitest test runner
|