M8-T08: add WarmteLink reading schema
This commit is contained in:
@@ -4,10 +4,12 @@ from __future__ import annotations
|
||||
|
||||
import uuid as _uuid
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
CheckConstraint,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Index,
|
||||
@@ -93,12 +95,48 @@ class MeterSourceChannel(Base):
|
||||
bindings: Mapped[list["MeterSourceBinding"]] = relationship(
|
||||
back_populates="channel", cascade="save-update, merge"
|
||||
)
|
||||
warmtelink_readings: Mapped[list["WarmteLinkReading"]] = relationship(
|
||||
back_populates="channel", cascade="save-update, merge"
|
||||
)
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint("source_id", "channel_key", name="uq_meter_source_channel_source_key"),
|
||||
)
|
||||
|
||||
|
||||
class WarmteLinkReading(Base):
|
||||
"""One accepted scalar cumulative reading from a WarmteLink channel."""
|
||||
|
||||
__tablename__ = "warmtelink_reading"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
channel_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("meter_source_channel.id", ondelete="RESTRICT"), nullable=False
|
||||
)
|
||||
# These timestamps retain their UTC-aware application semantics. SQLite
|
||||
# stores them without an offset, so callers must always supply aware UTC.
|
||||
recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
received_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
# SQLite's ORM Numeric path can exactly round-trip this 12-integer-digit
|
||||
# range at scale 3. That is ample for a long-lived cumulative meter while
|
||||
# retaining the protocol's 0.001 resolution without float conversion.
|
||||
value: Mapped[Decimal] = mapped_column(Numeric(15, 3), nullable=False)
|
||||
unit: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
quality: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
equipment_fingerprint: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
|
||||
channel: Mapped["MeterSourceChannel"] = relationship(back_populates="warmtelink_readings")
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint(
|
||||
"quality IN ('valid', 'invalid', 'unverifiable')",
|
||||
name="ck_warmtelink_reading_quality",
|
||||
),
|
||||
UniqueConstraint("channel_id", "recorded_at", name="uq_warmtelink_reading_channel_recorded_at"),
|
||||
Index("ix_warmtelink_reading_recorded_at", "recorded_at"),
|
||||
)
|
||||
|
||||
|
||||
class MeterSourceBinding(Base):
|
||||
"""Connect one source channel to one physical meter for a half-open window."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user