Hilfe! Problem mit der Aggregation?

@cicoub13 Ich kann deinen « Maximum Call Stack » reproduzieren, wenn ich versuche, ein Array mit 150.000 Sensorwerten zu chunken :o Das bedeutet, dass du einen Sensor hast, der mehr als 150.000 Werte gesendet hat. Aha, so einen Fall hatten wir sogar bei @Terdious nicht, interessant

Gut, ich habe eine leistungsfähigere Implementierung gefunden als die, die wir derzeit haben, und die « slice » statt « splice » verwendet, was es ermöglicht, das Array nicht vorher klonen zu müssen, da das Array nicht mutiert wird.

Ich habe mich auf Folgendes gestützt:

https://stackoverflow.com/questions/52750661/fast-array-chunking-in-node-js

Ein Leistungstest bestätigt, dass die alte Implementierung 69,6 % langsamer ist als die neue, und vor allem hat die neue keine Probleme mit dem Maximum Call Stack, da das Array nicht geklont wird.

Hier ist der PR für alle, die interessiert sind:

Ich habe den PR gemerged und einen Build auf dem Tag « dev » gestartet, damit wir sehen können, ob das dein Problem löst @cicoub13 :slight_smile: (auf Docker wird es wie gewohnt unter gladysassistant/gladys:dev verfügbar sein)

Der Build ist hier:

https://github.com/GladysAssistant/Gladys/actions/runs/1397530669

Das wird etwa eine Stunde dauern :slight_smile:

792K deviceFeatureState
5 Features mit 124K Einträgen - Sie sind alle mit einer Steckdose verbunden :scream: (es ist dieses Modell Tuya TS0121_plug control via MQTT | Zigbee2MQTT)
5 Features mit 15K Einträgen - Verbunden mit einem Bewegungsmelder (der auch das Licht misst)

Die Anzahl der Einträge pro Tag ist recht regelmäßig und ich habe nur 3 Monate gleitend gespeichert.

Ich teste das heute

Hier ist, was die API für dieses Problem zurückgibt:

[{"id":"c5bac8c2-5a49-4f7c-9ad8-0e367b427df8","type":"hourly-device-state-aggregate","status":"failed","progress":52,"data":{"error_type":"purged-when-restarted"},"created_at":"2021-10-28 09:14:48.379 +00:00","updated_at":"2021-10-29 06:03:07.825 +00:00"},{"id":"83bca935-43d3-4177-ba38-e51a16c36ff6","type":"monthly-device-state-aggregate","status":"success","progress":97,"data":{},"created_at":"2021-10-28 09:04:14.845 +00:00","updated_at":"2021-10-28 09:04:16.830 +00:00"},{"id":"6f15c4b3-5acb-4747-88b3-730af6fdecc4","type":"daily-device-state-aggregate","status":"success","progress":97,"data":{},"created_at":"2021-10-28 09:04:12.809 +00:00","updated_at":"2021-10-28 09:04:14.837 +00:00"},{"id":"2e0b5f3e-bf82-4a8c-a4c5-d601a209a10b","type":"hourly-device-state-aggregate","status":"failed","progress":52,"data":{"error_type":"unknown-error","error":"Error: RangeError: Maximum call stack size exceeded\n at chunk (/src/server/utils/chunks.js:11:26)\n at /src/server/lib/device/device.calculcateAggregateChildProcess.js:147:22\n"},"created_at":"2021-10-28 09:03:22.151 +00:00","updated_at":"2021-10-28 09:04:12.802 +00:00"}]

Sollte man die Zigbee2Mqtt-Integration so ändern, dass sie den Wert nicht speichert, wenn er sich nicht geändert hat? Das wäre schade, denn man könnte Informationen verlieren (keine Veränderung ist auch eine Information).

Konntest du es am Ende testen? :slight_smile:

Sehr seltsam, das sieht gut aus!

Ich denke nicht, tatsächlich ist es wichtig, die Werte auch dann zu behalten, wenn sie sich nicht geändert haben.

Andererseits könnte man in der UI das Attribut « keep_history » jedes Features anzeigen (in Form eines Schaltknopfes), um dem Benutzer eventuell die Möglichkeit zu geben, den Verlauf bestimmter zu ausführlicher Geräte nicht zu speichern und/oder wo sie den Verlauf nicht interessiert:

Ja, aber die Aggregation bleibt bei 52% stecken (anschließend verliere ich die Kontrolle über meinen RPI 3B+).
Der CPU läuft auf 100% und der RAM ist voll. Und es endet nie.

Ich habe es versucht, indem ich die Zustände der beiden ausführlichen Geräte (die ich nicht für die Grafiken verwende) gelöscht habe, und es funktioniert. Ich denke, du kannst deine Optimierung in master lassen.
Ich werde wirklich in einen RPI4 und eine SSD investieren müssen :wink:

Vielen Dank auf jeden Fall für die Untersuchung und die Korrektur :+1:

Ich habe ein Issue erstellt, um die Option keep_history zu behalten Zigbee2Mqtt - Add option keep_history when adding device · Issue #1344 · GladysAssistant/Gladys · GitHub

Ach Mist, wenn du nur 1GB RAM hast und ein Teil bereits von anderen Dingen belegt ist, kann es sein, dass Gladys versucht, 130.000 Sensorwerte in den RAM zu laden und diese Daten stündlich zu aggregieren, was den RAM überlasten und somit nie zum Abschluss kommen kann…

Gibt es in der UI eine klare Fehlermeldung, wenn es ein RAM-Problem gibt?

Ok, gut! Ansonsten kannst du Gladys auch anweisen, in den Einstellungen nur die letzten drei Monate der Sensorwerte zu behalten :slight_smile:

Nein, es kommt nie zu einem Fehler.

Ich werde das so machen, bis die Entwicklung abgeschlossen ist, die es ermöglichen wird, die Werte für diese beiden Geräte nicht zu speichern.

Falls es zu blockierend ist, ändere den keep history in der Datenbank.

Ich habe Gladys neu gestartet, um zu sehen, und habe immer noch die gleichen Fehler:

2021-11-25T12:46:18+0100 <warn> device.calculateAggregate.js:95 (Socket.<anonymous>) device.calculateAggregate stderr: TypeError: Cannot read property '0' of undefined
    at calculateTriangleArea (/src/server/node_modules/downsample/index.js:69:26)
    at LTTBIndexesForBuckets (/src/server/node_modules/downsample/index.js:662:18)
    at /src/server/node_modules/downsample/index.js:690:34
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:119:27
    at Map.forEach (<anonymous>)
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:111:35

2021-11-25T12:46:18+0100 <warn> device.calculateAggregate.js:101 (ChildProcess.<anonymous>) device.calculateAggregate: Exiting child process with code 1
2021-11-25T12:46:18+0100 <error> device.onHourlyDeviceAggregateEvent.js:22 (DeviceManager.onHourlyDeviceAggregateEvent) Error: TypeError: Cannot read property '0' of undefined
    at calculateTriangleArea (/src/server/node_modules/downsample/index.js:69:26)
    at LTTBIndexesForBuckets (/src/server/node_modules/downsample/index.js:662:18)
    at /src/server/node_modules/downsample/index.js:690:34
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:119:27
    at Map.forEach (<anonymous>)
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:111:35

    at ChildProcess.<anonymous> (/src/server/lib/device/device.calculateAggregate.js:102:23)
    at ChildProcess.emit (events.js:400:28)
    at maybeClose (internal/child_process.js:1058:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:293:5)
2021-11-25T12:46:18+0100 <info> device.calculateAggregate.js:38 (DeviceManager.calculateAggregate) Calculating aggregates device feature state for interval daily
2021-11-25T12:46:58+0100 <warn> device.calculateAggregate.js:95 (Socket.<anonymous>) device.calculateAggregate stderr: TypeError: Cannot read property '0' of undefined
    at calculateTriangleArea (/src/server/node_modules/downsample/index.js:69:26)
    at LTTBIndexesForBuckets (/src/server/node_modules/downsample/index.js:662:18)
    at /src/server/node_modules/downsample/index.js:690:34
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:119:27
    at Map.forEach (<anonymous>)
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:111:35

2021-11-25T12:46:58+0100 <warn> device.calculateAggregate.js:101 (ChildProcess.<anonymous>) device.calculateAggregate: Exiting child process with code 1
2021-11-25T12:46:58+0100 <error> device.onHourlyDeviceAggregateEvent.js:27 (DeviceManager.onHourlyDeviceAggregateEvent) Error: TypeError: Cannot read property '0' of undefined
    at calculateTriangleArea (/src/server/node_modules/downsample/index.js:69:26)
    at LTTBIndexesForBuckets (/src/server/node_modules/downsample/index.js:662:18)
    at /src/server/node_modules/downsample/index.js:690:34
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:119:27
    at Map.forEach (<anonymous>)
    at /src/server/lib/device/device.calculcateAggregateChildProcess.js:111:35

    at ChildProcess.<anonymous> (/src/server/lib/device/device.calculateAggregate.js:102:23)
    at ChildProcess.emit (events.js:400:28)
    at maybeClose (internal/child_process.js:1058:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:293:5)
2021-11-25T12:46:58+0100 <info> device.calculateAggregate.js:38 (DeviceManager.calculateAggregate) Calculating aggregates device feature state for interval monthly

Falls das bei der Untersuchung hilft, kann ich dir meine Datenbank senden oder besondere Analysen durchführen.

@lmilcent Ich gebe zu, ich hatte diesen Bug komplett vergessen! Ich kann ihn bei mir nicht reproduzieren, aber nach deinen Logs sieht es nach einem bestimmten Datensatz aus, der die von uns verwendete Downsampling-Bibliothek (downsample auf npm) zum Absturz bringt.

Könntest du bitte ein GitHub-Issue im Gladys-Repo erstellen (sonst vergesse ich es in 10 Minuten wieder :p) und mir eine Datenbank schicken, in der das Problem tatsächlich auftritt (das wäre super zum Debuggen :slight_smile: )

Danke!

@lmilcent Danke! Ich habe den Titel des Issues bearbeitet. (Der Bug NaN ist ein anderer Bug, nichts damit zu tun :slight_smile: )

Ich habe denselben Fehler auf meiner Seite, was die Aggregation betrifft. Bei mir scheint das Problem von den Daten der Kryptowährungen (Shiba) zu kommen, die immer unter 0 liegen. Ich frage mich, ob das nicht an der Anzahl der Dezimalstellen liegt, die in der Berechnung berücksichtigt werden, die die Bibliothek für die Aggregation verwendet:

Es funktioniert in der letzten Stunde, weil ich die Informationen alle 5 Minuten abrufe (also wahrscheinlich keine Aggregation), aber nicht über den Tag oder den Monat.

Danke für deine Nachricht @Albenss, ich denke, dass einige Aggregationen aufgrund eines ähnlichen Falls schiefgelaufen sein könnten.
Zum Beispiel erhielt mein MQTT-Gerät zur Steuerung der Anwesenheit vorher « present » und jetzt « 1 ».

Aber ich habe die Änderung schon vor mehreren Monaten vorgenommen, und es gibt immer noch Fehler.

Generell sollte der Fehler genauer sein :innocent:

@lmilcent Ich habe gerade deine Datenbank angesehen, die du mir geschickt hast, und bin sehr überrascht von ihrem Inhalt :smiley:

Du hast device_feature_state-Werte, deren Wert « NaN » (Not a Number) ist. Es ist sehr seltsam, dass diese überhaupt eingefügt wurden, da das Feld ein « double precision » ist und « NaN » kein « double precision » ist…

Natürlich lässt das die Aggregation, die numerische Werte erwartet und keinen String, abstürzen.

Nach einer Untersuchung stammen diese Werte aus der Zigbee2mqtt-Integration.

Ich habe ein GitHub-Issue erstellt, damit wir das Problem beheben:

  • Eine Datenbankmigration hinzufügen, um diese Zeilen zu bereinigen, die dort nicht sein sollten
  • Untersuchen, warum die Validierung und die Datenbank diese Werte akzeptiert haben, die keine Zahlen sind.

In der Zwischenzeit, @lmilcent und @Albenss, ist hier der SQL-Query, um eure Datenbanken zu reparieren:

DELETE FROM t_device_feature_state WHERE value = 'NaN';

@lmilcent Allgemeiner gesagt, ich weiß nicht, ob du alle deine historischen Sensordaten behalten möchtest (du behältst alle), aber ich würde dir empfehlen, einige sehr ausführliche deviceFeatures zu bereinigen, da derzeit für die Aggregation auf meinem Mac einige Sensoren so viele Werte enthalten, dass mehr als 1,5 GB RAM für die vollständige Aggregation benötigt werden (da es sich um die erste Aggregation handelt, beginnt sie von vorne. Das wird später nicht der Fall sein).

Ansonsten funktioniert es bei mir auf deiner Datenbank, nachdem die NaN-Werte entfernt wurden, sehr gut:

Ich habe mit dem Löschen der falschen Werte begonnen. Ich werde mich auch um die anderen Geräte kümmern, die zu viele Daten liefern… Funktion geplant? :wink: