# TCK RTU - Technical Documentation ## 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 | ### 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 8080) - Fixed resolution: 1024x600 - Optimized for 7" touchscreen - Compact layouts with 44px+ touch targets - No scrollbars - navigation buttons instead ### Remote Mode (Port 9090) - Responsive layout for any screen size - Full HD optimized - Expanded information display - Standard scrollbars ## 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 ``` ## 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 Serve the `dist` folder with any static file server: ```bash # Python python -m http.server 8080 # Node npx serve dist ``` ## 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 ### Development Tools - React DevTools - Vite HMR - Vitest test runner