# 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) => 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://: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