Files
bambuddy/backend/app/models/printer_sensor_history.py
T
maziggy 090c180ebf feat(heater-history): track nozzle / bed / chamber readings + per-tile chart-icon overlay opens history modal
New PrinterSensorHistory table + 60s recorder + GET/DELETE /printer-sensor-history
  route gated behind a new PRINTER_SENSOR_HISTORY_READ scope (separate from AMS). UI
  adds a 10x10 LineChart icon on each heater tile - click body opens the existing
  target-temp popover unchanged, click icon opens a HeaterHistoryModal mirroring the
  AMSHistoryModal shape (kind toggle + 6h/24h/48h/7d range + current/avg/min/max +
  recharts line for value + dashed target). Read-only X1C/P2S chamber tile finally
  gets an interaction. Retention configurable via printer_sensor_history_retention_days
  (default 30, sibling of ams_history_retention_days). 8 new i18n keys translated in
  all 11 locales, parity green. 4 backend + 6 frontend tests added; full pytest -n 30
  6226/6226, vitest 2176/2176, ruff/eslint/build all clean.
2026-06-20 12:55:24 +02:00

41 lines
1.5 KiB
Python

from datetime import datetime
from sqlalchemy import DateTime, Float, ForeignKey, Index, String, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from backend.app.core.database import Base
class PrinterSensorHistory(Base):
"""Historical heater readings (nozzle / nozzle_2 / bed / chamber).
Parallel to AMSSensorHistory, but per-(printer, sensor_kind) rather
than per-(printer, ams_id). Sensor counts vary by model (single vs
dual nozzle, presence of chamber heater), so a long-format row per
sensor reads cleanly and leaves room for future kinds (cpu, motor)
without another migration.
"""
__tablename__ = "printer_sensor_history"
id: Mapped[int] = mapped_column(primary_key=True)
printer_id: Mapped[int] = mapped_column(ForeignKey("printers.id", ondelete="CASCADE"))
sensor_kind: Mapped[str] = mapped_column(String(32)) # nozzle | nozzle_2 | bed | chamber
value: Mapped[float | None] = mapped_column(Float) # current temperature, Celsius
target: Mapped[float | None] = mapped_column(Float) # target temperature when set, Celsius
recorded_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), index=True)
__table_args__ = (
Index(
"ix_printer_sensor_history_printer_kind_time",
"printer_id",
"sensor_kind",
"recorded_at",
),
)
printer: Mapped["Printer"] = relationship(back_populates="sensor_history")
from backend.app.models.printer import Printer # noqa: E402