Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard/MQTT: Current Month/Year Totals kloppen (tijdelijk) niet na middernacht #1811

Open
RichieB2B opened this issue Feb 16, 2023 · 14 comments
Labels

Comments

@RichieB2B
Copy link
Contributor

Description

Ik gebruik de standaard (Data Source) Current Month/Year Totals: Json definitie om berichten naar MQTT te sturen. De totalen zoals current_month_electricity1, current_month_electricity1 en current_month_gas hebben in het eerste bericht JSON van de dag de waarde van een dag eerder (dus 24 geleden).

In het screenshot zitten de dips op 23:00 uur omdat de grafiek in GMT is.
Screenshot 2023-02-16 at 22 54 14

DSMR-reader version

5.10.3

DSMR-reader platform

Native (e.g. manual installation)

Debug info dump

No response

@RichieB2B RichieB2B added the bug label Feb 16, 2023
@RichieB2B
Copy link
Contributor Author

Wanneer worden de dagtotalen weggeschreven in de database? Want ik vermoed dat de als range_statistics() de maand/jaar totalen gaat berekenen vlak na middernacht dat het dagtotaal van de net afgelopen dag nog niet wordt meegeteld.

@RichieB2B
Copy link
Contributor Author

Het probleem zit 'm denk ik in de vertraging van minimaal 5 minuten voor het berekenen van de dagtotalen als je een gas meter hebt. Wat is de juiste oplossing? Het MQTT bericht laten wachten totdat de dagtotalen beschikbaar zijn?

@dennissiemensma
Copy link
Member

dennissiemensma commented Feb 19, 2023 via email

@RichieB2B
Copy link
Contributor Author

De oorzaak is mij duidelijk: het eerste MQTT van de dag wordt verstuurd om 00:02 uur. Maar dan is het eerste P1 datagram voor gas nog niet binnen (die komen elke 5 minuten). Daardoor heeft de stats scheduled task de dagtotalen nog niet gemaakt. Die wacht namelijk op het eerste gas P1 telegram van de dag. Het is dus een race condition tussen range_statistics() en de daily stats scheduled task.

Wat er dus gebeurt in het eerste MQTT bericht van de dag om 00:02 uur: omdat de dagtotalen van gisteren nog niet klaar zijn wordt die dag niet meegeteld.

@dennissiemensma
Copy link
Member

Ik heb er nu voor je naar kunnen kijken en de oorzaak zit iets verderop.

Zowel het dashboard als die MQTT-databron gebruiken dezelfde gegevens om het huidige verbruik in te zien, ook al zijn daar nog geen dagtotalen voor.
Om te compenseren voor de missende dagstatistieken voor de huidige dag/maand, wordt alles samengevoegd met de tussenstand van de huidige dag.

Echter is de "huidige dag" na middernacht strikt gezien een andere dag en zie je dus tijdelijk die terugval. Vermoedelijk is dat nooit iemand eerder opgevallen (of niet willen melden), want voor oudere v4-meters is dat gat zelfs niet 5 minuten, maar meer dan een uur.

Gezien de aard van deze databron (wat het moet doen) ga ik het bericht niet vertragen, maar zal ik ooit een keertje kijken of ik een extra check erin kan doen die situationeel de vorige dag erbij optelt. Of het gewoon baseert op de meterstanden, maar dat vereist wat rework.

@dennissiemensma dennissiemensma added this to the Some future release milestone Feb 20, 2023
@dennissiemensma dennissiemensma changed the title 🚨Verkeerde waardes in eerste MQTT bericht van de dag Dashboard/MQTT: Current Month/Year Totals kloppen (tijdelijk) niet na middernacht Feb 20, 2023
dennissiemensma added a commit that referenced this issue Feb 20, 2023
RichieB2B added a commit to RichieB2B/dsmr-reader that referenced this issue Feb 22, 2023
RichieB2B added a commit to RichieB2B/dsmr-reader that referenced this issue Feb 22, 2023
RichieB2B added a commit to RichieB2B/dsmr-reader that referenced this issue Feb 23, 2023
RichieB2B added a commit to RichieB2B/dsmr-reader that referenced this issue Feb 23, 2023
@RichieB2B
Copy link
Contributor Author

RichieB2B commented Feb 24, 2023

Bedankt voor de uitleg, het is me gelukt om dit op te lossen voor de current_(month|year)_electricity* maar voor gas is er meer aan de hand. De terugval is groter dan het laatste uur en die komt er ook niet meer bij. current_(month|year)_gas lijkt dus aan het eind van elke dag structureel iets te verliezen:

image

image

@RichieB2B
Copy link
Contributor Author

RichieB2B commented Feb 24, 2023

Het probleem met het gas dagtotaal is waarschijnlijk ontstaan door e684b6e mbt #1770
De som van de HourStatistics is niet gelijk aan day_consumption()

Dat komt denk ik door deze code:

def create_hourly_statistics(hour_start: timezone.datetime) -> Optional[HourStatistics]:
"""Calculates and returns an hour summary, when applicable. Persists it as well."""
logger.debug("Stats: Creating hour statistics for: %s", hour_start)
hour_end = hour_start + timezone.timedelta(hours=1)
electricity_readings, gas_readings = dsmr_consumption.services.consumption_by_range(
start=hour_start, end=hour_end
)
if not electricity_readings.exists():
return
creation_kwargs = {"hour_start": hour_start}
if HourStatistics.objects.filter(**creation_kwargs).exists():
logger.debug("Stats: Skipping duplicate hour statistics for: %s", hour_start)
return
electricity_start = electricity_readings.first()
electricity_end = electricity_readings.last()
creation_kwargs["electricity1"] = (
electricity_end.delivered_1 - electricity_start.delivered_1
)
creation_kwargs["electricity2"] = (
electricity_end.delivered_2 - electricity_start.delivered_2
)
creation_kwargs["electricity1_returned"] = (
electricity_end.returned_1 - electricity_start.returned_1
)
creation_kwargs["electricity2_returned"] = (
electricity_end.returned_2 - electricity_start.returned_2
)
# DSMR v4.
if len(gas_readings) == 1:
creation_kwargs["gas"] = gas_readings[0].currently_delivered
# DSMR v5
elif len(gas_readings) > 1:
gas_readings = list(gas_readings)
creation_kwargs["gas"] = gas_readings[-1].delivered - gas_readings[0].delivered
return HourStatistics.objects.create(**creation_kwargs)

Stel, je hebt voor gas elk uur 4 tellerstanden:

0:05 1
0:20 2
0:35 3
0:50 4
1:05 5
1:20 6
1:35 7
1:50 8
2:05 9

Als je dan alle samples van een uur opvraagt krijg je er 4:

1:05 5
1:20 6
1:35 7
1:50 8

Trek je dan de eerste tellerstand van de laatste af dan mis je elk uur een sample. In dit voorbeeld krijg je elk uur als uurtotaal 3 terwijl het 4 moet zijn. De correcte manier is: vraag de samples op van uur x en uur x+1 en trek de tellerstand van het eerste sample in uur x af van de tellerstand van het eerste sample in uur x+1.

Ik heb dit opgelost in de 2e commit van PR #1814

day_consumption() heeft trouwens hetzelfde off-by-one probleem dat op dezelfde manier kan worden opgelost (laatste sample van de dag wordt niet meegeteld). Laat maar weten als ik hiervoor ook een PR moet maken.

@dennissiemensma
Copy link
Member

Bedankt voor je uitgebreide onderzoek! Ik moet hier veel dieper naar kijken, want het is helaas niet een kwestie van een codewijziging om dit te fixen, maar eerder een complete refactoring.

Het zit vrij diep en via #1770 was al de conclusie dat een deel op de kop moet, zoals in day_consumption() al gemarkeerd was. De uiteindelijke oplossing wordt simpelweg naar meterstanden kijken van de initiele data, ipv de huidige tussenlaag. Dat maakt de berekeningen ook veel makkelijker.
Daarnaast is er een gebrek aan integratietests voor de dataverwerking van begin tot eind, zodat zulke bugs ook niet meer voor gaan komen. Dit project heeft redelijk wat tests, alleen telkens op kleine delen en niet het hele plaatje.

Voor het 1-off probleem zal ik verder ook nog onderscheid moeten maken tussen gas en elektra, want in de happy-flow is een uur verder kijken prima, maar bij onderbreking van data rond een uur- of dagwisseling, kan dat weer andersom zorgen voor foute data.
Eigenlijk nog een extra reden om gewoon naar meterstanden te gaan kijken ipv de huidige manier van DSMR-reader via day_consumption().

@RichieB2B
Copy link
Contributor Author

RichieB2B commented Feb 25, 2023

Ik snap dat er een refactoring nodig is. Dit begon voor mij als een poging om de getallen in de MQTT berichten consequent te maken. Dat is met PR #1814 gelukt. Ik sla die getallen voor langere tijd op dus dan wil ik wel dat ze kloppen. Maar ik realiseer me nu dat de dagtotalen die DSMR-Reader opslaat ook niet juist zijn. Voor elektriciteit valt de afwijking wel mee (er mist 1 minuut per dag) maar voor DSMRv5 gas is het al erger. Dit verklaart meteen de verschillen die ik zie tussen de gasmeter in mijn CV ketel en DSMR-Reader (we koken elektrisch). Voorlopig zal ik dus moeten vertrouwen op de MQTT data ipv de dagtotalen van DSMR-Reader.

@dennissiemensma dennissiemensma modified the milestones: Some future release, DSMR-reader v5.11 Feb 26, 2023
@Roukie686868
Copy link

Hi ik ben in het weekend van 5/6 februari van version 4.2 naar 5 overgestapt en zie nu grote verschillen van ongeveer 8% per uur bij het gas. Na wat dieper zoeken kom ik erachter dat van de 12 gaswaarden per uur in de dsmr_consumption_gasconsumption tabel elke keer de laatste waarde ontbreekt bij het uurtotaal in de dsmr_stats_hourstatistics tabel.

Figure 1 - dsmr_stats_hourstatistics
image

Figure 2 - dsmr_consumption_gasconsumption
image

Is hier een oplossing voor zodat DSMR weer de juiste waarde aangeeft in de grafieken?

@dennissiemensma
Copy link
Member

dennissiemensma commented Mar 10, 2023

@Roukie686868 bedankt voor je aanvulling. Er is nog momenteel geen oplossing voor omdat een structurele fix relatief veel werk is, waarbij ik vermoedelijk een paar avonden achter elkaar ermee bezig ben. Mijn voornemens was al wel om dat deze maand te doen.

@Roukie686868
Copy link

Roukie686868 commented Mar 11, 2023 via email

@RichieB2B
Copy link
Contributor Author

Steeds meer DSMR-Reader gebruikers merken dat de dag/maand/jaar totalen niet juist zijn. De refactoring die nodig blijkt is natuurlijk een grote opgave. Als je hierbij hulp nodig hebt (bijv. voor het schrijven van integratie tests) hebt dan werk ik er graag aan mee.

@dennissiemensma
Copy link
Member

Het is helaas een tweeledig probleem. Normaal heb ik in de wintermaanden veel tijd om in de avond aan dit project te werken, maar dat valt dit seizoen nog flink tegen.

Anderzijds ben ik er nog niet over uit. Ik neig steeds meer naar teruggaan naar de situatie van anderhalfjaar geleden of langer. Waarbij een andere bug welliswaar speelt, maar die tenminste niet zorgt voor de dusdanige grote afwijkingen op maandbasis.

Een complete refactor vereist namelijk zoveel tijd, dat ik niet weet of dat realistisch is

@dennissiemensma dennissiemensma removed this from the DSMR-reader v5.11 milestone Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants