Lejer-selvaflæsning og EU EED 2027 månedlige data
Lejer-selvaflæsning via portal: EU EED 2023/1791 artikel 9d krav, mobil aflæsningsindberetning, valideringsregler mod automatisk fjernaflæsning, konfliktresolution og platform-implementering.
Af M-Bus Gateway
EU EED 2023/1791 artikel 9d kræver at lejere kan tilgå eget forbrug månedligt fra 2027. Selvaflæsningsportalen er brobyggeren til ejendomme uden fuldt fjernaflæsning.
EU EED artikel 9d — månedlige data til lejere
EU EED 2023/1791 artikel 9d (gælder fra 2027):
Hvad lejere har ret til:
→ Månedlig forbrugsdata (faktisk eller estimeret)
→ Sammenligning med forrige periode
→ Sammenligning med gennemsnitslejer i ejendommen (anonymiseret)
→ Graddage-normaliseret forbrug for klimakorrektion
→ CO2-intensitet for opvarmningskilden
Hvem er forpligtet:
→ Udlejere med fjernaflæsbare målere: Platform-automatik
→ Udlejere med manuelle aflæsninger: Selvaflæsningsportal
Sanktioner (DK — forventet implementering):
→ Manglende efterlevelse: Huslejenævn kan pålægge udlejer
→ EU-Kommissionen: Kan indlede traktatbrudssag mod DK
Platform-compliance:
→ Fjernaflæsning (wM-Bus): Automatisk månedlige data ✅
→ Selvaflæsning: Lejer-portal med månedlig indberetning
→ Begge kanaler: Lejer-dashboard med historik og sammenligning
Selvaflæsningsportal — brugerflow
Lejer-selvaflæsningsflow (EU EED 2027 compliant):
1. Udlejer aktiverer selvaflæsning for ejendom
→ Property.self_reading_enabled = True
→ Udlejer definerer aflæsningsvindue (f.eks. 25.–31. i måneden)
2. Lejer modtager SMS/email-påmindelse
→ "Husk at aflæse din måler inden 31. maj"
→ Link til lejer-portal (magic link eller password)
3. Lejer indberetter via mobil:
→ Fotograferer måler-display
→ Indtaster aflæsning manuelt
→ System validerer mod forrige aflæsning + forventet forbrug
4. Validering:
→ Under minimumsgrænse: "Lavere end forrige måned — korrekt?"
→ Over maksimum: "Usædvanlig høj — bekræft venligst"
→ Foto påkrævet ved afvigelse > 50% fra forventet
5. Konfliktresolution (selvaflæsning vs. fjernaflæsning):
→ Fjernaflæsning altid prioriteret (MID-certificeret)
→ Selvaflæsning bruges kun ved manglende fjernaflæsning
→ Afregning markerer tydeligt: "Faktisk aflæsning" vs. "Selvaflæsning"
API endpoint — indberetning
# server/src/readings/self_reading_router.py
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form
from sqlmodel import Session
from datetime import datetime, date
from decimal import Decimal
from server.src.auth.deps import get_current_user
router = APIRouter(prefix="/api/v1/self-readings", tags=["self-readings"])
@router.post("/")
async def submit_self_reading(
meter_installation_id: str = Form(...),
reading_value: Decimal = Form(...),
reading_date: date = Form(...),
photo: UploadFile | None = File(None),
current_user=Depends(get_current_user),
db=Depends(get_db),
) -> dict:
"""
Lejer indberetter manuel aflæsning.
Valideres mod seneste automatiske aflæsning og historisk forbrug.
"""
# Verificer at lejer ejer denne installation
installation = await _verify_tenant_installation(
meter_installation_id, current_user, db
)
# Validér mod forventet forbrug
validation = await _validate_reading(
meter_installation_id, reading_value, reading_date, db
)
if validation["status"] == "rejected":
raise HTTPException(
status_code=422,
detail=f"Aflæsning afvist: {validation['reason']}",
)
# Gem fotos i Hetzner Object Storage hvis medfølger
photo_key = None
if photo:
photo_key = await _upload_reading_photo(
photo, meter_installation_id, reading_date
)
# Gem selvaflæsning
reading = await _save_self_reading(
meter_installation_id=meter_installation_id,
value_kwh=reading_value,
timestamp=datetime.combine(reading_date, datetime.min.time()),
source="self_reading",
photo_s3_key=photo_key,
submitted_by=current_user.id,
db=db,
)
return {
"reading_id": str(reading.id),
"status": validation["status"], # "accepted" eller "warning"
"validation_message": validation.get("message"),
"photo_uploaded": photo_key is not None,
}
Valideringslogik
# server/src/readings/validation.py
from decimal import Decimal
from datetime import date
from sqlalchemy import text
async def _validate_reading(
meter_installation_id: str,
value: Decimal,
reading_date: date,
db,
) -> dict:
"""
Validér selvaflæsning mod historisk forbrug.
Returns: {"status": "accepted"|"warning"|"rejected", "reason": str}
"""
# Hent seneste 3 faktiske aflæsninger
result = await db.execute(
text("""
SELECT value_kwh, timestamp
FROM readings
WHERE meter_installation_id = :mi_id
AND source != 'self_reading'
ORDER BY timestamp DESC
LIMIT 3
"""),
{"mi_id": meter_installation_id},
)
recent = result.fetchall()
if not recent:
return {"status": "accepted", "message": "Ingen historik — aflæsning accepteret"}
latest = recent[0]
latest_value = Decimal(str(latest.value_kwh))
# Afvisning: Aflæsning lavere end seneste (tæller aldrig bagud)
if value < latest_value:
return {
"status": "rejected",
"reason": f"Aflæsning ({value}) lavere end seneste ({latest_value:.1f}). Målertæller kan ikke gå baglæns.",
}
# Beregn forventet dagsforbrug fra historik
if len(recent) >= 2:
days_between = (recent[0].timestamp - recent[1].timestamp).days or 1
delta = Decimal(str(recent[0].value_kwh)) - Decimal(str(recent[1].value_kwh))
daily_rate = delta / Decimal(days_between)
days_since_last = (reading_date - latest.timestamp.date()).days or 1
expected = latest_value + daily_rate * Decimal(days_since_last)
deviation = abs(value - expected) / expected if expected > 0 else Decimal("0")
if deviation > Decimal("0.5"): # > 50% afvigelse
return {
"status": "warning",
"message": f"Aflæsning afviger {deviation:.0%} fra forventet ({expected:.1f}). Foto påkrævet.",
"requires_photo": True,
}
return {"status": "accepted", "message": "Aflæsning accepteret"}
Lejer-dashboard — EU EED 2027 månedsoverblik
Lejer-portal EU EED 2027 compliant:
Månedsoverblik (ArticLe 9d data):
┌─────────────────────────────────────────────┐
│ Dit forbrug — maj 2026 │
│ │
│ Varme: 234 kWh (forrige md: 198 kWh) │
│ Vand: 3,2 m³ (forrige md: 2,9 m³) │
│ │
│ Sammenlignet med gennemsnit i ejendommen: │
│ Du bruger 12% MINDRE end gennemsnittet │
│ │
│ Klimakorrigeret (graddage): │
│ Normaliseret: 218 kWh (maj er varm) │
│ │
│ CO2: 23 kg (fjernvarme: 98 g/kWh) │
└─────────────────────────────────────────────┘
Historik (12 måneder):
[BarChart: månedligt forbrug + gennemsnitslinje]
Datatype-indikator:
🔵 Automatisk aflæsning (wM-Bus)
🟡 Selvaflæsning (dig)
⚪ Estimeret (§ 13)
Årsafregning:
→ Link til seneste PDF-afregning
→ Indsigelsesformular (6-ugers frist)
Konklusion
EU EED 2023/1791 artikel 9d kræver månedlige forbrugsdata til lejere fra 2027. For ejendomme med wM-Bus fjernaflæsning leverer platformen dette automatisk. For manuelle ejendomme er selvaflæsningsportalen svaret — lejer fotograferer og indberetter, systemet validerer mod historisk forbrug og prioriterer altid fjernaflæsning ved konflikt. Valideringslogik afviser umulige aflæsninger (bagudgående tæller) og flagger usædvanlige afvigelser med fotokrav. Lejer-dashboardet viser månedsoverblik, klimakorrektion og CO2-intensitet — fuldt EU EED 2027 compliant.
Se EU 2027 fjernaflæsning lovkrav eller hvad kan lejer se guide.