305 lines
7.7 KiB
Markdown
305 lines
7.7 KiB
Markdown
# 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<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
|
|
```
|
|
|
|
## 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
|