v0.1.1 update
This commit is contained in:
215
README.md
215
README.md
@@ -1,12 +1,16 @@
|
||||
# Seismo Fleet Manager - Backend v0.1
|
||||
# Seismo Fleet Manager v0.1.1
|
||||
|
||||
Backend API for managing seismograph fleet status. Track multiple seismographs calling in data from remote deployments, monitor their status, and manage your fleet through a unified database.
|
||||
Backend API and web interface for managing seismograph fleet status. Track multiple seismographs calling in data from remote deployments, monitor their status, and manage your fleet through a unified database.
|
||||
|
||||
## Features
|
||||
|
||||
- **Web Dashboard**: Modern, responsive UI with dark/light mode support
|
||||
- **Fleet Monitoring**: Track all seismograph units in one place
|
||||
- **Roster Management**: Full CRUD operations via API or CSV import *(New in v0.1.1)*
|
||||
- **Status Management**: Automatically mark units as OK, Pending (>12h), or Missing (>24h)
|
||||
- **Data Ingestion**: Accept reports from emitter scripts via REST API
|
||||
- **Photo Management**: Upload and view photos for each unit
|
||||
- **Interactive Maps**: Leaflet-based maps showing unit locations
|
||||
- **SQLite Storage**: Lightweight, file-based database for easy deployment
|
||||
|
||||
## Tech Stack
|
||||
@@ -14,6 +18,10 @@ Backend API for managing seismograph fleet status. Track multiple seismographs c
|
||||
- **FastAPI**: Modern, fast web framework
|
||||
- **SQLAlchemy**: SQL toolkit and ORM
|
||||
- **SQLite**: Lightweight database
|
||||
- **HTMX**: Dynamic updates without heavy JavaScript frameworks
|
||||
- **TailwindCSS**: Utility-first CSS framework
|
||||
- **Leaflet**: Interactive maps
|
||||
- **Jinja2**: Server-side templating
|
||||
- **uvicorn**: ASGI server
|
||||
- **Docker**: Containerization for easy deployment
|
||||
|
||||
@@ -39,11 +47,14 @@ Backend API for managing seismograph fleet status. Track multiple seismographs c
|
||||
docker compose down
|
||||
```
|
||||
|
||||
The API will be available at `http://localhost:8000`
|
||||
The application will be available at:
|
||||
- **Web Interface**: http://localhost:8001
|
||||
- **API Documentation**: http://localhost:8001/docs
|
||||
- **Health Check**: http://localhost:8001/health
|
||||
|
||||
### Data Persistence
|
||||
|
||||
The SQLite database is stored in the `./data` directory, which is mounted as a volume. Your data will persist even if you restart or rebuild the container.
|
||||
The SQLite database and photos are stored in the `./data` directory, which is mounted as a volume. Your data will persist even if you restart or rebuild the container.
|
||||
|
||||
## Local Development (Without Docker)
|
||||
|
||||
@@ -60,65 +71,67 @@ The SQLite database is stored in the `./data` directory, which is mounted as a v
|
||||
|
||||
2. **Run the server:**
|
||||
```bash
|
||||
python main.py
|
||||
uvicorn backend.main:app --host 0.0.0.0 --port 8001 --reload
|
||||
```
|
||||
|
||||
Or with auto-reload:
|
||||
```bash
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
The API will be available at `http://localhost:8000`
|
||||
The application will be available at http://localhost:8001
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Root
|
||||
- **GET** `/` - Health check
|
||||
### Web Pages
|
||||
- **GET** `/` - Dashboard home page
|
||||
- **GET** `/roster` - Fleet roster page
|
||||
- **GET** `/unit/{unit_id}` - Unit detail page
|
||||
|
||||
### Emitter Report
|
||||
- **POST** `/emitters/report`
|
||||
- Submit status report from a seismograph unit
|
||||
- **Request Body:**
|
||||
```json
|
||||
{
|
||||
"unit": "SEISMO-001",
|
||||
"unit_type": "series3",
|
||||
"timestamp": "2025-11-20T10:30:00",
|
||||
"file": "event_20251120_103000.dat",
|
||||
"status": "OK"
|
||||
}
|
||||
### Fleet Status & Monitoring
|
||||
- **GET** `/api/status-snapshot` - Complete fleet status snapshot
|
||||
- **GET** `/api/roster` - List of all units with metadata
|
||||
- **GET** `/api/unit/{unit_id}` - Detailed unit information
|
||||
- **GET** `/health` - Health check endpoint
|
||||
|
||||
### Roster Management *(New in v0.1.1)*
|
||||
- **POST** `/api/roster/add` - Add new unit to roster
|
||||
```bash
|
||||
curl -X POST http://localhost:8001/api/roster/add \
|
||||
-F "id=BE1234" \
|
||||
-F "unit_type=series3" \
|
||||
-F "deployed=true" \
|
||||
-F "note=Main site sensor"
|
||||
```
|
||||
- **Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Emitter report received",
|
||||
"unit": "SEISMO-001",
|
||||
"status": "OK"
|
||||
}
|
||||
- **POST** `/api/roster/set-deployed/{unit_id}` - Toggle deployment status
|
||||
- **POST** `/api/roster/set-retired/{unit_id}` - Toggle retired status
|
||||
- **POST** `/api/roster/set-note/{unit_id}` - Update unit notes
|
||||
- **POST** `/api/roster/import-csv` - Bulk import from CSV
|
||||
```bash
|
||||
curl -X POST http://localhost:8001/api/roster/import-csv \
|
||||
-F "file=@roster.csv" \
|
||||
-F "update_existing=true"
|
||||
```
|
||||
|
||||
### Fleet Status
|
||||
- **GET** `/fleet/status`
|
||||
- Retrieve status of all seismograph units
|
||||
- **Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "SEISMO-001",
|
||||
"unit_type": "series3",
|
||||
"last_seen": "2025-11-20T10:30:00",
|
||||
"last_file": "event_20251120_103000.dat",
|
||||
"status": "OK",
|
||||
"notes": null
|
||||
}
|
||||
]
|
||||
```
|
||||
### CSV Import Format
|
||||
Create a CSV file with the following columns (only `unit_id` is required):
|
||||
```csv
|
||||
unit_id,unit_type,deployed,retired,note,project_id,location
|
||||
BE1234,series3,true,false,Primary sensor,PROJ-001,San Francisco CA
|
||||
BE5678,series3,true,false,Backup sensor,PROJ-001,Los Angeles CA
|
||||
```
|
||||
|
||||
See [sample_roster.csv](sample_roster.csv) for a working example.
|
||||
|
||||
### Emitter Reporting
|
||||
- **POST** `/emitters/report` - Submit status report from a seismograph unit
|
||||
- **POST** `/api/series3/heartbeat` - Series3 multi-unit telemetry payload
|
||||
- **GET** `/fleet/status` - Retrieve status of all seismograph units (legacy)
|
||||
|
||||
### Photo Management
|
||||
- **GET** `/api/unit/{unit_id}/photos` - List photos for a unit
|
||||
- **GET** `/api/unit/{unit_id}/photo/{filename}` - Serve specific photo file
|
||||
|
||||
## API Documentation
|
||||
|
||||
Once running, interactive API documentation is available at:
|
||||
- **Swagger UI**: http://localhost:8000/docs
|
||||
- **ReDoc**: http://localhost:8000/redoc
|
||||
- **Swagger UI**: http://localhost:8001/docs
|
||||
- **ReDoc**: http://localhost:8001/redoc
|
||||
|
||||
## Testing the API
|
||||
|
||||
@@ -126,7 +139,7 @@ Once running, interactive API documentation is available at:
|
||||
|
||||
**Submit a report:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/emitters/report \
|
||||
curl -X POST http://localhost:8001/emitters/report \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"unit": "SEISMO-001",
|
||||
@@ -139,7 +152,14 @@ curl -X POST http://localhost:8000/emitters/report \
|
||||
|
||||
**Get fleet status:**
|
||||
```bash
|
||||
curl http://localhost:8000/fleet/status
|
||||
curl http://localhost:8001/api/roster
|
||||
```
|
||||
|
||||
**Import roster from CSV:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8001/api/roster/import-csv \
|
||||
-F "file=@sample_roster.csv" \
|
||||
-F "update_existing=true"
|
||||
```
|
||||
|
||||
### Using Python
|
||||
@@ -150,7 +170,7 @@ from datetime import datetime
|
||||
|
||||
# Submit report
|
||||
response = requests.post(
|
||||
"http://localhost:8000/emitters/report",
|
||||
"http://localhost:8001/emitters/report",
|
||||
json={
|
||||
"unit": "SEISMO-001",
|
||||
"unit_type": "series3",
|
||||
@@ -162,13 +182,37 @@ response = requests.post(
|
||||
print(response.json())
|
||||
|
||||
# Get fleet status
|
||||
response = requests.get("http://localhost:8000/fleet/status")
|
||||
response = requests.get("http://localhost:8001/api/roster")
|
||||
print(response.json())
|
||||
|
||||
# Import CSV
|
||||
with open('roster.csv', 'rb') as f:
|
||||
files = {'file': f}
|
||||
data = {'update_existing': 'true'}
|
||||
response = requests.post(
|
||||
"http://localhost:8001/api/roster/import-csv",
|
||||
files=files,
|
||||
data=data
|
||||
)
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
## Data Model
|
||||
|
||||
### Emitters Table
|
||||
### RosterUnit Table (Your Fleet Roster)
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| id | string | Unit identifier (primary key) |
|
||||
| unit_type | string | Type of seismograph (default: "series3") |
|
||||
| deployed | boolean | Whether unit is deployed in field |
|
||||
| retired | boolean | Whether unit is retired from service |
|
||||
| note | string | Notes about the unit |
|
||||
| project_id | string | Associated project identifier |
|
||||
| location | string | Deployment location description |
|
||||
| last_updated | datetime | Last modification timestamp |
|
||||
|
||||
### Emitter Table (Device Check-ins)
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
@@ -183,15 +227,34 @@ print(response.json())
|
||||
|
||||
```
|
||||
seismo-fleet-manager/
|
||||
├── main.py # FastAPI app entry point
|
||||
├── database.py # SQLAlchemy database configuration
|
||||
├── models.py # Database models
|
||||
├── routes.py # API endpoints
|
||||
├── requirements.txt # Python dependencies
|
||||
├── Dockerfile # Docker container definition
|
||||
├── docker-compose.yml # Docker Compose configuration
|
||||
├── .dockerignore # Docker ignore rules
|
||||
└── data/ # SQLite database directory (created at runtime)
|
||||
├── backend/
|
||||
│ ├── main.py # FastAPI app entry point
|
||||
│ ├── database.py # SQLAlchemy database configuration
|
||||
│ ├── models.py # Database models (RosterUnit, Emitter)
|
||||
│ ├── routes.py # Legacy API endpoints
|
||||
│ ├── routers/ # Modular API routers
|
||||
│ │ ├── roster.py # Fleet status endpoints
|
||||
│ │ ├── roster_edit.py # Roster management & CSV import
|
||||
│ │ ├── units.py # Unit detail endpoints
|
||||
│ │ ├── photos.py # Photo management
|
||||
│ │ ├── dashboard.py # Dashboard partials
|
||||
│ │ └── dashboard_tabs.py # Dashboard tab endpoints
|
||||
│ ├── services/
|
||||
│ │ └── snapshot.py # Fleet status snapshot logic
|
||||
│ └── static/ # Static assets (CSS, etc.)
|
||||
├── templates/ # Jinja2 HTML templates
|
||||
│ ├── base.html # Base layout with sidebar
|
||||
│ ├── dashboard.html # Main dashboard
|
||||
│ ├── roster.html # Fleet roster table
|
||||
│ ├── unit_detail.html # Unit detail page
|
||||
│ └── partials/ # HTMX partial templates
|
||||
├── data/ # SQLite database & photos (persisted)
|
||||
├── requirements.txt # Python dependencies
|
||||
├── Dockerfile # Docker container definition
|
||||
├── docker-compose.yml # Docker Compose configuration
|
||||
├── CHANGELOG.md # Version history
|
||||
├── FRONTEND_README.md # Frontend documentation
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Docker Commands
|
||||
@@ -221,6 +284,11 @@ docker compose logs -f seismo-backend
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
**Rebuild and restart:**
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
**Stop and remove containers:**
|
||||
```bash
|
||||
docker compose down
|
||||
@@ -231,14 +299,25 @@ docker compose down
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
## What's New in v0.1.1
|
||||
|
||||
- **Roster Editing API**: Full CRUD operations for managing your fleet roster
|
||||
- **CSV Import**: Bulk upload roster data from CSV files
|
||||
- **Enhanced Data Model**: Added project_id and location fields to roster
|
||||
- **Bug Fixes**: Improved database session management and error handling
|
||||
- **Dashboard Improvements**: Separate views for Active, Benched, and Retired units
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for complete version history.
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- Automated status updates based on last_seen timestamps
|
||||
- Web-based dashboard for fleet monitoring
|
||||
- Email/SMS alerts for missing units
|
||||
- Historical data tracking and reporting
|
||||
- Multi-user authentication
|
||||
- PostgreSQL support for larger deployments
|
||||
- Advanced filtering and search
|
||||
- Export roster to various formats
|
||||
- Automated backup and restore
|
||||
|
||||
## License
|
||||
|
||||
@@ -246,4 +325,6 @@ MIT
|
||||
|
||||
## Version
|
||||
|
||||
0.1.0 - Initial Release
|
||||
**Current: 0.1.1** - Roster Management & CSV Import (2025-12-02)
|
||||
|
||||
Previous: 0.1.0 - Initial Release (2024-11-20)
|
||||
|
||||
Reference in New Issue
Block a user