@mytec: iter1.5.1 start
This commit is contained in:
229
RFCP-Iteration-1.5.1-Fixes-Boundaries.md
Normal file
229
RFCP-Iteration-1.5.1-Fixes-Boundaries.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# RFCP Iteration 1.5.1: Fixes & Boundaries
|
||||
|
||||
**Date:** January 31, 2025
|
||||
**Type:** Bugfix & Polish
|
||||
**Estimated:** 2-3 hours
|
||||
**Location:** `/opt/rfcp/frontend/` + `/opt/rfcp/backend/`
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Goal
|
||||
|
||||
Fix Fresnel endpoint 500 error, restore coverage boundary visualization, minor polish.
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Issues to Fix
|
||||
|
||||
### 1. Fresnel Endpoint 500 Error
|
||||
|
||||
**Symptom:**
|
||||
```bash
|
||||
curl "/api/terrain/fresnel?tx_lat=48.46&tx_lon=35.05&tx_height=30&rx_lat=48.47&rx_lon=35.06&rx_height=1.5&frequency=1800"
|
||||
# Returns: 500 Internal Server Error
|
||||
```
|
||||
|
||||
**Location:** `backend/app/api/routes/terrain.py`
|
||||
|
||||
**Likely cause:** Missing `rx_height` default or async issue in `los_service.check_fresnel_clearance()`
|
||||
|
||||
**Fix:**
|
||||
```python
|
||||
@router.get("/fresnel")
|
||||
async def check_fresnel(
|
||||
tx_lat: float,
|
||||
tx_lon: float,
|
||||
tx_height: float,
|
||||
rx_lat: float,
|
||||
rx_lon: float,
|
||||
rx_height: float = 1.5, # Default receiver height
|
||||
frequency: float = 1800 # Default frequency MHz
|
||||
):
|
||||
try:
|
||||
result = await los_service.check_fresnel_clearance(
|
||||
tx_lat, tx_lon, tx_height,
|
||||
rx_lat, rx_lon, rx_height,
|
||||
frequency
|
||||
)
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(500, f"Fresnel calculation error: {str(e)}")
|
||||
```
|
||||
|
||||
**Debug:** Check backend logs for actual error:
|
||||
```bash
|
||||
journalctl -u rfcp-backend -n 50 | grep -i error
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Coverage Boundary Not Showing
|
||||
|
||||
**Symptom:** Boundary contour line (-100 dBm) not visible on map after API integration
|
||||
|
||||
**Location:** `frontend/src/components/map/CoverageBoundary.tsx`
|
||||
|
||||
**Likely cause:** Component expecting old data format, not new API response
|
||||
|
||||
**Check:**
|
||||
1. Is `CoverageBoundary` still mounted in map?
|
||||
2. Does it receive `points` from coverage store?
|
||||
3. Is boundary calculation using correct field (`rsrp` vs old field name)?
|
||||
|
||||
**Fix approach:**
|
||||
```typescript
|
||||
// CoverageBoundary.tsx
|
||||
import { useCoverageStore } from '../../store/coverage';
|
||||
|
||||
export function CoverageBoundary() {
|
||||
const { points, settings } = useCoverageStore();
|
||||
|
||||
// Generate boundary from API points
|
||||
const boundaryPoints = useMemo(() => {
|
||||
if (!points.length) return [];
|
||||
|
||||
// Filter points near threshold
|
||||
const threshold = settings.min_signal; // -100 dBm
|
||||
const tolerance = 5; // ±5 dBm
|
||||
|
||||
return points
|
||||
.filter(p => Math.abs(p.rsrp - threshold) < tolerance)
|
||||
.map(p => [p.lat, p.lon] as [number, number]);
|
||||
}, [points, settings.min_signal]);
|
||||
|
||||
// ... rest of boundary rendering
|
||||
}
|
||||
```
|
||||
|
||||
**Alternative:** Use convex hull or marching squares for proper contour:
|
||||
```typescript
|
||||
import { concaveman } from 'concaveman';
|
||||
|
||||
const boundaryPolygon = useMemo(() => {
|
||||
const edgePoints = points
|
||||
.filter(p => p.rsrp >= settings.min_signal && p.rsrp < settings.min_signal + 10)
|
||||
.map(p => [p.lon, p.lat]);
|
||||
|
||||
if (edgePoints.length < 3) return null;
|
||||
|
||||
return concaveman(edgePoints, 2); // concavity factor
|
||||
}, [points, settings.min_signal]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Minor Polish
|
||||
|
||||
**a) Stats panel — show models used:**
|
||||
```typescript
|
||||
// StatsPanel.tsx
|
||||
{lastCalculation && (
|
||||
<div className="models-used">
|
||||
<span className="label">Models:</span>
|
||||
<div className="model-tags">
|
||||
{lastCalculation.models.map(m => (
|
||||
<span key={m} className="model-tag">{m}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
```
|
||||
|
||||
**b) Loading state during long calculations:**
|
||||
```typescript
|
||||
// Show elapsed time during calculation
|
||||
const [elapsed, setElapsed] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isCalculating) {
|
||||
setElapsed(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const start = Date.now();
|
||||
const interval = setInterval(() => {
|
||||
setElapsed(Math.floor((Date.now() - start) / 1000));
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [isCalculating]);
|
||||
|
||||
// In render:
|
||||
{isCalculating && (
|
||||
<div className="calculating-status">
|
||||
Calculating... {elapsed}s
|
||||
</div>
|
||||
)}
|
||||
```
|
||||
|
||||
**c) Error toast for API failures:**
|
||||
```typescript
|
||||
// In coverage store calculateCoverage()
|
||||
catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Calculation failed';
|
||||
toast.error(message); // If using toast library
|
||||
set({ error: message, isCalculating: false });
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Tasks
|
||||
|
||||
- [ ] Fix Fresnel endpoint (backend)
|
||||
- [ ] Debug and check logs for actual error
|
||||
- [ ] Restore CoverageBoundary with API points
|
||||
- [ ] Test boundary renders correctly
|
||||
- [ ] Add elapsed time counter during calculation
|
||||
- [ ] Add model tags to stats panel
|
||||
- [ ] Test all presets still work
|
||||
- [ ] Run integration test — should be 21/21
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
```bash
|
||||
# 1. Test Fresnel fix
|
||||
curl "https://api.rfcp.eliah.one/api/terrain/fresnel?tx_lat=48.46&tx_lon=35.05&tx_height=30&rx_lat=48.47&rx_lon=35.06&rx_height=1.5&frequency=1800"
|
||||
# Should return: {"clearance_percent": ..., "has_adequate_clearance": ...}
|
||||
|
||||
# 2. Run integration test
|
||||
./rfcp-integration-test.sh
|
||||
# Should be 21/21
|
||||
|
||||
# 3. Visual test
|
||||
# - Calculate coverage
|
||||
# - Verify boundary line appears at -100 dBm edge
|
||||
# - Verify elapsed time shows during calculation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Files to Modify
|
||||
|
||||
```
|
||||
backend/app/
|
||||
├── api/routes/terrain.py # Fresnel fix
|
||||
└── services/los_service.py # Check fresnel method
|
||||
|
||||
frontend/src/
|
||||
├── components/
|
||||
│ ├── map/CoverageBoundary.tsx # Fix boundary rendering
|
||||
│ └── panels/
|
||||
│ ├── CoverageStats.tsx # Add model tags
|
||||
│ └── StatsPanel.tsx # Elapsed time
|
||||
└── store/coverage.ts # Error handling
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- Boundary can use simple edge detection or proper contour algorithm
|
||||
- `concaveman` is lightweight (~2KB) for concave hull
|
||||
- Elapsed time helps user know calculation is progressing
|
||||
|
||||
---
|
||||
|
||||
**Quick iteration — should be fast** 🚀
|
||||
Reference in New Issue
Block a user