Files
esp32-web/src/esp32_web/models/device.py
user a676136f5d 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
2026-02-05 20:56:52 +01:00

38 lines
1.5 KiB
Python

"""Device model."""
from datetime import datetime, UTC
from ..extensions import db
class Device(db.Model):
"""Discovered BLE/WiFi device."""
__tablename__ = 'devices'
id: db.Mapped[int] = db.mapped_column(primary_key=True)
mac: db.Mapped[str] = db.mapped_column(db.String(17), unique=True, index=True)
device_type: db.Mapped[str] = db.mapped_column(db.String(8)) # 'ble' or 'wifi'
vendor: db.Mapped[str | None] = db.mapped_column(db.String(64), nullable=True)
name: db.Mapped[str | None] = db.mapped_column(db.String(64), nullable=True)
first_seen: db.Mapped[datetime] = db.mapped_column(default=lambda: datetime.now(UTC))
last_seen: db.Mapped[datetime] = db.mapped_column(default=lambda: datetime.now(UTC))
# BLE-specific fields
company_id: db.Mapped[int | None] = db.mapped_column(nullable=True)
tx_power: db.Mapped[int | None] = db.mapped_column(nullable=True)
# Relationships
sightings = db.relationship('Sighting', back_populates='device', lazy='dynamic')
probes = db.relationship('Probe', back_populates='device', lazy='dynamic')
def to_dict(self):
return {
'id': self.id,
'mac': self.mac,
'type': self.device_type,
'vendor': self.vendor,
'name': self.name,
'first_seen': self.first_seen.isoformat(),
'last_seen': self.last_seen.isoformat(),
'company_id': self.company_id,
'tx_power': self.tx_power,
}