feat: Initial project scaffold
Flask API backend for ESP32 sensor fleet: - App factory pattern with blueprints - SQLAlchemy 2.x models (Sensor, Device, Sighting, Alert, Event, Probe) - UDP collector for sensor data streams - REST API endpoints for sensors, devices, alerts, events, probes, stats - pytest setup with fixtures - Containerfile for podman deployment - Makefile for common tasks
This commit is contained in:
42
src/esp32_web/api/devices.py
Normal file
42
src/esp32_web/api/devices.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""Device endpoints."""
|
||||
from flask import request
|
||||
from . import bp
|
||||
from ..models import Device, Sighting
|
||||
from ..extensions import db
|
||||
|
||||
|
||||
@bp.route('/devices')
|
||||
def list_devices():
|
||||
"""List all devices."""
|
||||
device_type = request.args.get('type') # 'ble' or 'wifi'
|
||||
limit = min(int(request.args.get('limit', 100)), 1000)
|
||||
offset = int(request.args.get('offset', 0))
|
||||
|
||||
query = db.select(Device).order_by(Device.last_seen.desc())
|
||||
if device_type:
|
||||
query = query.where(Device.device_type == device_type)
|
||||
query = query.limit(limit).offset(offset)
|
||||
|
||||
devices = db.session.scalars(query).all()
|
||||
return {'devices': [d.to_dict() for d in devices], 'limit': limit, 'offset': offset}
|
||||
|
||||
|
||||
@bp.route('/devices/<mac>')
|
||||
def get_device(mac):
|
||||
"""Get device by MAC."""
|
||||
mac = mac.lower()
|
||||
device = db.session.scalar(db.select(Device).where(Device.mac == mac))
|
||||
if not device:
|
||||
return {'error': 'Device not found'}, 404
|
||||
|
||||
# Include recent sightings
|
||||
sightings = db.session.scalars(
|
||||
db.select(Sighting)
|
||||
.where(Sighting.device_id == device.id)
|
||||
.order_by(Sighting.timestamp.desc())
|
||||
.limit(20)
|
||||
).all()
|
||||
|
||||
result = device.to_dict()
|
||||
result['sightings'] = [s.to_dict() for s in sightings]
|
||||
return result
|
||||
Reference in New Issue
Block a user