310 lines
9.6 KiB
Markdown
310 lines
9.6 KiB
Markdown
# SolarBank IoT Dashboard
|
|
|
|
A full-stack Docker-based IoT dashboard system for monitoring LILYGO T-A7670G and SIM7000E NB-IoT + GPS modules. This system provides a comprehensive solution for tracking and managing IoT devices, with features for real-time monitoring, data visualization, and device management.
|
|
|
|
## Features
|
|
|
|
- **Real-time Device Monitoring**: Track GPS coordinates, signal strength, battery levels, and device status
|
|
- **LILYGO T-A7670G Support**: Native support for LILYGO T-A7670G devices with specialized data endpoints
|
|
- **Environmental Monitoring**: Temperature, humidity, and solar voltage monitoring
|
|
- **Interactive Map View**: Visualize device locations using Leaflet.js with GPS fix status
|
|
- **Comprehensive Dashboard**: View device metrics and system status at a glance
|
|
- **Device Management**: Search, filter, and manage your IoT devices
|
|
- **Logging System**: Track and analyze device logs and events
|
|
- **REST API**: FastAPI backend for device data ingestion and retrieval
|
|
- **Containerized Architecture**: Docker-based deployment for easy setup and scaling
|
|
|
|
## Technology Stack
|
|
|
|
### Frontend
|
|
- React.js with WindSurf UI (Tailwind CSS)
|
|
- Leaflet.js for map visualization
|
|
- Chart.js for data visualization
|
|
- Axios for API communication
|
|
|
|
### Backend
|
|
- FastAPI (Python) for REST API
|
|
- SQLAlchemy ORM for database operations
|
|
- PostgreSQL for data storage
|
|
- Redis for caching and background tasks
|
|
|
|
### Infrastructure
|
|
- Docker and Docker Compose for containerization
|
|
- Nginx as reverse proxy with HTTPS support
|
|
- Let's Encrypt for SSL certificates
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
solarbank/
|
|
├── backend/ # FastAPI backend application
|
|
│ ├── app/ # Application code
|
|
│ │ ├── api/ # API endpoints
|
|
│ │ ├── core/ # Core functionality
|
|
│ │ ├── db/ # Database models and session
|
|
│ │ ├── models/ # SQLAlchemy models
|
|
│ │ └── services/ # Business logic
|
|
│ ├── Dockerfile # Backend Docker configuration
|
|
│ ├── requirements.txt # Python dependencies
|
|
│ └── migrate_iot_fields.py # Database migration for IoT fields
|
|
├── frontend/ # React frontend application
|
|
│ ├── public/ # Static files
|
|
│ ├── src/ # Source code
|
|
│ │ ├── components/ # React components
|
|
│ │ ├── pages/ # Page components
|
|
│ │ ├── services/ # API services
|
|
│ │ └── utils/ # Utility functions
|
|
│ ├── Dockerfile # Frontend Docker configuration
|
|
│ └── package.json # Node.js dependencies
|
|
├── nginx/ # Nginx configuration
|
|
│ ├── conf/ # Nginx config files
|
|
│ └── Dockerfile # Nginx Docker configuration
|
|
├── test_iot_device.py # IoT device testing script
|
|
├── .env.example # Example environment variables
|
|
└── docker-compose.yml # Docker Compose configuration
|
|
```
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
- Docker and Docker Compose
|
|
- Git
|
|
|
|
### Installation
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone https://github.com/yourusername/solarbank.git
|
|
cd solarbank
|
|
```
|
|
|
|
2. Create environment files:
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
3. Start the application:
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
4. Access the dashboard:
|
|
- Frontend: http://localhost
|
|
- API Documentation: http://localhost/api/docs
|
|
|
|
5. (Optional) Run database migration for existing databases:
|
|
```bash
|
|
cd backend
|
|
python migrate_iot_fields.py
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
The following environment variables can be configured in the `.env` file:
|
|
|
|
#### Backend Settings
|
|
- `API_PREFIX`: Prefix for API endpoints
|
|
- `DEBUG`: Enable debug mode
|
|
- `PROJECT_NAME`: Name of the project
|
|
- `SECRET_KEY`: Secret key for security
|
|
- `BACKEND_CORS_ORIGINS`: List of allowed CORS origins
|
|
|
|
#### Database Settings
|
|
- `POSTGRES_SERVER`: PostgreSQL server hostname
|
|
- `POSTGRES_USER`: PostgreSQL username
|
|
- `POSTGRES_PASSWORD`: PostgreSQL password
|
|
- `POSTGRES_DB`: PostgreSQL database name
|
|
|
|
#### Redis Settings
|
|
- `REDIS_HOST`: Redis server hostname
|
|
- `REDIS_PORT`: Redis server port
|
|
|
|
#### JWT Settings
|
|
- `JWT_SECRET_KEY`: Secret key for JWT tokens
|
|
- `JWT_ALGORITHM`: Algorithm for JWT tokens
|
|
- `ACCESS_TOKEN_EXPIRE_MINUTES`: Token expiration time
|
|
|
|
#### Frontend Settings
|
|
- `REACT_APP_API_URL`: URL of the backend API
|
|
- `REACT_APP_MAPBOX_TOKEN`: Mapbox API token for maps
|
|
|
|
#### Nginx Settings
|
|
- `DOMAIN_NAME`: Domain name for SSL certificate
|
|
- `EMAIL`: Email for Let's Encrypt
|
|
|
|
## API Endpoints
|
|
|
|
### Device Endpoints
|
|
- `GET /api/devices`: Get all devices
|
|
- `POST /api/devices`: Create a new device
|
|
- `GET /api/devices/{device_id}`: Get a specific device
|
|
- `PUT /api/devices/{device_id}`: Update a device
|
|
- `DELETE /api/devices/{device_id}`: Delete a device
|
|
|
|
### Telemetry Endpoints
|
|
- `POST /api/data`: Create new telemetry data (standard format)
|
|
- `POST /api/data/iot`: Create new telemetry data (LILYGO format)
|
|
- `GET /api/data/device/{device_id}`: Get telemetry for a specific device
|
|
- `GET /api/data/latest`: Get latest telemetry across all devices
|
|
|
|
### Log Endpoints
|
|
- `GET /api/logs`: Get all logs
|
|
- `POST /api/logs`: Create a new log
|
|
- `GET /api/logs/{log_id}`: Get a specific log
|
|
- `DELETE /api/logs/{log_id}`: Delete a log
|
|
|
|
### Status Endpoints
|
|
- `GET /api/status`: Get system status
|
|
- `GET /api/status/devices`: Get status of all devices
|
|
|
|
## LILYGO T-A7670G Device Integration
|
|
|
|
### Device Data Format
|
|
|
|
LILYGO T-A7670G devices should send telemetry data to the `/api/data/iot` endpoint in the following format:
|
|
|
|
```json
|
|
{
|
|
"device_id": "LILYGO_001",
|
|
"device_name": "Zurich_Station_1",
|
|
"firmware": "1.1.0",
|
|
"temp": 24.5,
|
|
"hum": 65.2,
|
|
"solar_volt": 12.8,
|
|
"battery_volt": 3.8,
|
|
"signal": -65,
|
|
"gps_fixed": true,
|
|
"latitude": 47.3769,
|
|
"longitude": 8.5417,
|
|
"altitude": 408.5,
|
|
"satellites": 8,
|
|
"timestamp": 1234567890
|
|
}
|
|
```
|
|
|
|
### Arduino/ESP32 Code Example
|
|
|
|
```cpp
|
|
// Build JSON payload for LILYGO device
|
|
String buildJsonPayload() {
|
|
String json = "{";
|
|
json += "\"device_id\":\"" + String(DEVICE_ID) + "\",";
|
|
json += "\"device_name\":\"" + String(DEVICE_NAME) + "\",";
|
|
json += "\"firmware\":\"" + String(FIRMWARE_VERSION) + "\",";
|
|
json += "\"temp\":" + String(temperature, 1) + ",";
|
|
json += "\"hum\":" + String(humidity, 1) + ",";
|
|
json += "\"solar_volt\":" + String(voltageSolar, 2) + ",";
|
|
json += "\"battery_volt\":" + String(voltageBattery, 2) + ",";
|
|
json += "\"signal\":" + String(signalStrength) + ",";
|
|
json += "\"gps_fixed\":" + String(gpsFixed ? "true" : "false") + ",";
|
|
json += "\"latitude\":" + String(latitude, 6) + ",";
|
|
json += "\"longitude\":" + String(longitude, 6) + ",";
|
|
json += "\"altitude\":" + String(altitude, 1) + ",";
|
|
json += "\"satellites\":" + String(satellites) + ",";
|
|
json += "\"timestamp\":" + String(millis() / 1000);
|
|
json += "}";
|
|
return json;
|
|
}
|
|
|
|
// Send data to server
|
|
bool sendData() {
|
|
String json = buildJsonPayload();
|
|
String http = "POST /api/data/iot HTTP/1.1\r\n";
|
|
http += "Host: " + String(SERVER_IP) + "\r\n";
|
|
http += "Content-Type: application/json\r\n";
|
|
http += "Content-Length: " + String(json.length()) + "\r\n";
|
|
http += "Connection: close\r\n\r\n";
|
|
http += json;
|
|
|
|
// Send via TCP/HTTP
|
|
return sendDataViaTCP(http);
|
|
}
|
|
```
|
|
|
|
### Field Descriptions
|
|
|
|
- **device_id**: Unique device identifier (required)
|
|
- **device_name**: Human-readable device name (optional)
|
|
- **firmware**: Device firmware version (optional)
|
|
- **temp**: Temperature in Celsius (optional)
|
|
- **hum**: Humidity percentage (optional)
|
|
- **solar_volt**: Solar panel voltage (optional)
|
|
- **battery_volt**: Battery voltage - automatically converted to percentage (optional)
|
|
- **signal**: Cellular signal strength in dBm (optional)
|
|
- **gps_fixed**: GPS fix status boolean (optional)
|
|
- **latitude/longitude**: GPS coordinates (optional)
|
|
- **altitude**: Elevation in meters (optional)
|
|
- **satellites**: Number of GPS satellites (optional)
|
|
- **timestamp**: Unix timestamp from device (optional)
|
|
|
|
### Testing IoT Device Integration
|
|
|
|
Use the provided test script to verify your setup:
|
|
|
|
```bash
|
|
python test_iot_device.py
|
|
```
|
|
|
|
This script simulates LILYGO device data and tests various scenarios including:
|
|
- Basic data submission
|
|
- Multiple device simulation
|
|
- Edge cases (no GPS, low battery)
|
|
- Continuous monitoring
|
|
|
|
## Standard Device Data Format (Legacy)
|
|
|
|
For non-LILYGO devices, use the standard `/api/data` endpoint with this format:
|
|
|
|
```json
|
|
{
|
|
"device_id": "device-001",
|
|
"latitude": 47.3769,
|
|
"longitude": 8.5417,
|
|
"altitude": 408,
|
|
"speed": 0,
|
|
"heading": 0,
|
|
"satellites": 8,
|
|
"battery_level": 85,
|
|
"signal_strength": -65,
|
|
"temperature": 24.5,
|
|
"extra_data": {
|
|
"humidity": 45,
|
|
"pressure": 1013
|
|
}
|
|
}
|
|
```
|
|
|
|
## Database Migration
|
|
|
|
For existing installations, run the migration script to add new IoT fields:
|
|
|
|
```bash
|
|
cd backend
|
|
python migrate_iot_fields.py
|
|
```
|
|
|
|
This adds the following fields to the telemetry table:
|
|
- `gps_fixed`: GPS fix status
|
|
- `battery_voltage`: Raw battery voltage
|
|
- `humidity`: Humidity percentage
|
|
- `solar_voltage`: Solar panel voltage
|
|
- `device_timestamp`: Device timestamp
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
|
## License
|
|
|
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
|
|
## Acknowledgements
|
|
|
|
- [FastAPI](https://fastapi.tiangolo.com/)
|
|
- [React](https://reactjs.org/)
|
|
- [Tailwind CSS](https://tailwindcss.com/)
|
|
- [Leaflet.js](https://leafletjs.com/)
|
|
- [Docker](https://www.docker.com/)
|
|
- [LILYGO T-A7670G](https://github.com/Xinyuan-LilyGO/LilyGO-T-A76XX)
|