NEWS
JS für Überwachung der Luftfeuchtigkeit in Räumen
-
@gismoh sagte in JS für Überwachung der Luftfeuchtigkeit in Räumen:
Momentan füge ich noch den Taupunkt hinzu, um zu warnen, wann es zu Schimmel kommen kann - so zumindest die Idee.
hast du den nicht schon in den Rechnungen drin?
für die Werkstatt hab ich noch zusätzlich den "Taupunkt" für 80% und 70% Feuchte, da dies eigentlich schon die Grenzwerte für Schimmelbildung sind
-
@homoran
Den möchte ich genauer Berechnen und ausgeben lassen.
Der ist nicht nur von der Temeratur oder der Luftfeuchtig abhängig, sondern koaliert mit beiden Werten
(so zumindest mein Gedanke).Edit: Ja, sehe ich gerade, hast du ja bereits drin
-
@gismoh sagte in JS für Überwachung der Luftfeuchtigkeit in Räumen:
@homoran
Den möchte ich genauer Berechnen und ausgeben lassen.
Der ist nicht nur von der Temeratur oder der Luftfeuchtig abhängig, sondern koaliert mit beiden Werten
(so zumindest mein Gedanke).Edit: Ja, sehe ich gerade, hast du ja bereits drin
Nur der View ist von mir, die Daten kommen alle aus dem verlinkten Script.
Da gibt es dann auch noch differenzierte Lüftungsempfehlung mit Auskühlschutz usw. -
@homoran
Die Lüftungsempfehlungen kommen auch noch, dies ist dafür die "Vorarbeit".
Wenn ich nun mal dransitze, ziehe ich es nun auch durchHatte ein altes Script in Benutzung, mit welchem ich nicht mehr zufrieden war, deswegen wollte ich einfach mal schauen, was nun dabei rauskommt
-
@gismoh
Habe nun noch eine Berechnung hinzugefügt, in welcher der Taupunkt der einzelnen Räume berechnet wird.
Dieser ist wichtig um Schimmel zu vermeiden, vor allem, für wenig genutzte Räume, welche auch nicht oder wenig beheizt werden.Da das Raumthermostat meist nicht an der kältesten Stelle des Raums misst wurde eine Temperaturkorrektur für die Taupunktberechnung hinzugefügt.
Wenn also in einem Raum das hier eingebundene Thermometer z.B. 19 Grad ermittelt und die kälteste Stelle im Raum mit 16 Grad gemessen wird, wird die Korrektur für diesen Raum mit "+3" eingegeben.
/** * Skript: Lüftungsempfehlung basierend auf Raumklima inkl. Speicherung von absoluter Luftfeuchte und Taupunkt (nur für Räume) * * Beschreibung: * Dieses Skript liest für mehrere Räume die aktuellen Sensorwerte (relative Luftfeuchte und Temperatur) * ein und berechnet daraus: * - Eine Lüftungsempfehlung basierend auf einem festen Schwellenwert (z. B. 57 % RH). * - Ob Lüften (Austausch mit Außenluft) die absolute Luftfeuchte senken kann. * - Die absolute Luftfeuchte (AH) mit der Formel: * AH = (6.112 * exp((17.67 * T)/(T + 243.5)) * RH * 2.1674) / (T + 273.15) * Für Außensensoren wird zusätzlich der Luftdruck als Korrekturfaktor einbezogen: * AH_out = AH * (P / 1013.25) * - Den Taupunkt (in °C) mittels: * γ = ln(RH/100) + (17.67 * (T_corr))/(243.5 + T_corr) * Taupunkt = (243.5 * γ)/(17.67 - γ) * Dabei wird T_corr = T + taupunktTempCorrection berechnet. * Die temperaturbezogene Korrektur (taupunktTempCorrection) kann für jeden Raum separat eingestellt werden. * Die Berechnung des Taupunkts erfolgt **nur für Räume**. * * Die Ergebnisse werden in definierte Datenpunkte geschrieben: * - fixedDP: Empfehlung basierend auf festem Schwellenwert (true/false). * - reduceDP: Empfehlung, ob Lüften die Luftfeuchte senken kann (true/false). * - absDP: Absolute Luftfeuchte (in g/m³). * - taupunktDP: Taupunkt (in °C) – **nur für Räume**. * * Zusätzlich: * - Optional wird geprüft, ob Sensoren erreichbar sind und ob sie zu alt sind. * - Die Speicherung der berechneten absoluten Luftfeuchte und des Taupunkts ist optional (saveAbsoluteHumidity, saveDewPoint). * * Zeitgesteuerte Ausführung: * - Zwischen 06:00 und 22:59 wird das Skript alle 10 Minuten ausgeführt. * - Zwischen 23:00 und 05:59 alle 30 Minuten. */ // ============================= // Konfiguration // ============================= var config = { // Berechnungen ein- bzw. ausschalten: enableFixedCalculation: true, // Empfehlung basierend auf festem RH-Schwellenwert. enableAbsoluteHumidityCalculation: true, // Empfehlung, ob Lüften die absolute Luftfeuchte senkt. globalRHThreshold: 40, // Globaler RH-Schwellenwert in %. absoluteHumidityOffset: 0, // Offset in g/m³ für den Vergleich der absoluten Luftfeuchte. debug: true, // Aktiviert ausführliche Debug-Ausgabe. // Optionale Speicherung der berechneten absoluten Luftfeuchte und des Taupunkts. saveAbsoluteHumidity: true, // Speicherung der absoluten Luftfeuchte. saveDewPoint: true, // Speicherung des Taupunkts (nur für Räume). // Global einstellbare Temperaturkorrektur für die Taupunktberechnung (wird verwendet, falls kein Raumwert definiert ist) taupunktTempCorrection: +3, // Optionale Prüfung der Sensorverfügbarkeit: enableSensorCheck: true, // Optionale Prüfung des Sensoralters: sensorAgeCheck: { enabled: true, maxAgeHours: 3 // Maximale Zeitspanne (in Stunden) ohne Aktualisierung. }, // Definition der Räume: // Für jeden Raum können zusätzlich eigene Einstellungen für die Temperaturkorrektur (taupunktTempCorrection) definiert werden. // Die "taupunktTempCorrection" ist der Wert, um wieviel Grad wärmer die Temperatur am Erfassungsgerät ist, im Verhältnis zur Kühlsten Stelle im Raum (minimierung des Schimmelrisiko) rooms: { "Wohnzimmer": { enabled: true, indoorRH: "alias.0.Wohnzimmer.Raumklima.Sonoff.Luftfeuchte", indoorTemp: "alias.0.Wohnzimmer.Raumklima.Sonoff.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Wohnzimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.GG-Wohnzimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Wohnzimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Wohnzimmer", threshold: null, taupunktTempCorrection: +3 // Korrektur für dieses Zimmer (kann individuell angepasst werden) }, "Arbeitszimmer": { enabled: true, indoorRH: "alias.0.Arbeitszimmer.Raumklima.Sonoff.Luftfeuchte", indoorTemp: "alias.0.Arbeitszimmer.Raumklima.Sonoff.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Arbeitszimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.Arbeitszimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Arbeitszimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Arbeitszimmer", threshold: null, taupunktTempCorrection: +3 }, "Badezimmer": { enabled: true, indoorRH: "alias.0.Badezimmer.Luftfeuchte", indoorTemp: "alias.0.Badezimmer.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Badezimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.Badezimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Badezimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Badezimmer", threshold: null, taupunktTempCorrection: +3 }, "Buegelzimmer": { enabled: true, indoorRH: "alias.0.Bügelzimmer.Luftfeuchte.Sonoff", indoorTemp: "alias.0.Bügelzimmer.Temperatur.Sonoff", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Buegelzimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.Buegelzimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Buegelzimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Buegelzimmer", threshold: null, taupunktTempCorrection: +3 }, "Essflur": { enabled: true, indoorRH: "alias.0.Essflur.Raumklima.Aqara-BLE.Luftfeuchte", indoorTemp: "alias.0.Essflur.Raumklima.Aqara-BLE.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Essflur", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.Essflur", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Essflur", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Essflur", threshold: null, taupunktTempCorrection: +3 }, "Schlafzimmer": { enabled: true, indoorRH: "alias.0.Schlafzimmer.Raumklima.Sonoff.Luftfeuchte", indoorTemp: "alias.0.Schlafzimmer.Raumklima.Sonoff.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Schlafzimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.Schlafzimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Schlafzimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Schlafzimmer", threshold: null, taupunktTempCorrection: +3 }, "Waschkueche": { enabled: true, indoorRH: "alias.0.Waschküche.Raumklima.Aqara.Luftfeuchte", indoorTemp: "alias.0.Waschküche.Raumklima.Aqara.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.Waschkueche", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.Waschkueche", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Waschkueche", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.Waschkueche", threshold: null, taupunktTempCorrection: +3 }, "GG-Kueche": { enabled: true, indoorRH: "alias.0.ELW-West.Küche.Raumklima.Aqara.Luftfeuchte", indoorTemp: "alias.0.ELW-West.Küche.Raumklima.Aqara.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.GG-Kueche", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.GG-Kueche", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.GG-Kueche", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.GG-Kueche", threshold: null, taupunktTempCorrection: +3 }, "GG-Schlafzimmer": { enabled: true, indoorRH: "alias.0.ELW-West.Schlafzimmer.Raumklima.Aqara.Luftfeuchte", indoorTemp: "alias.0.ELW-West.Schlafzimmer.Raumklima.Aqara.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.GG-Schlafzimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.GG-Schlafzimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.GG-Schlafzimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.GG-Schlafzimmer", threshold: null, taupunktTempCorrection: +3 }, "GG-Wohnzimmer": { enabled: true, indoorRH: "alias.0.ELW-West.Wohnzimmer.Raumklima.Sonoff.Luftfeuchte", indoorTemp: "alias.0.ELW-West.Wohnzimmer.Raumklima.Sonoff.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.GG-Wohnzimmer", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.GG-Wohnzimmer", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.GG-Wohnzimmer", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.GG-Wohnzimmer", threshold: null, taupunktTempCorrection: +3 }, "GG-Bad": { enabled: false, indoorRH: "alias.0.GG-Bad.Raumklima.Sonoff.Luftfeuchte", indoorTemp: "alias.0.GG-Bad.Raumklima.Sonoff.Temperatur", fixedDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.FesterWert-ueberschritten.GG-Bad", reduceDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.LF-Senken-moeglich.GG-Bad", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.GG-Bad", taupunktDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.GG-Bad", threshold: null, taupunktTempCorrection: +3 } }, // Definition der Außensensoren: outside: { rh: "alias.0.Außen-Nord.Raumklima.Aqara.Luftfeuchte", temp: "alias.0.Außen-Nord.Raumklima.Aqara.Temperatur", pressure: "alias.0.Außen-Nord.Raumklima.Aqara.Luftdruck", absDP: "0_userdata.0.EigeneDatenpunkte.Raumklima.Luefungsempfehlung.AbsoluteLuftfeuchtigkeit.Aussen-Nord" // Taupunkt für außen wird bewusst nicht berechnet. } }; // ============================= // Funktion: calcAbsoluteHumidity // ============================= /** * Berechnet die absolute Luftfeuchte (g/m³) basierend auf Temperatur, relativer Luftfeuchte * und optional dem Luftdruck. * * Formel: * AH = (6.112 * exp((17.67 * T) / (T + 243.5)) * RH * 2.1674) / (T + 273.15) * * Falls der optionale Parameter "pressure" (Luftdruck in hPa) übergeben wird, wird der Wert * als Korrekturfaktor (bezogen auf 1013.25 hPa) einbezogen: * AH = AH * (pressure / 1013.25) * * @param {number} T - Temperatur in °C. * @param {number} RH - Relative Luftfeuchte in %. * @param {number} [pressure] - (Optional) Luftdruck in hPa. * @returns {number} Berechnete absolute Luftfeuchte in g/m³. */ function calcAbsoluteHumidity(T, RH, pressure) { var AH = (6.112 * Math.exp((17.67 * T) / (T + 243.5)) * RH * 2.1674) / (T + 273.15); if (pressure !== undefined && pressure > 0) { AH = AH * (pressure / 1013.25); } return AH; } // ============================= // Funktion: calcDewPoint // ============================= /** * Berechnet den Taupunkt (in °C) basierend auf Temperatur (T) und relativer Luftfeuchte (RH). * * Für die Berechnung des Taupunkts wird eine temperaturbezogene Korrektur angewendet, * die für jeden Raum separat eingestellt werden kann. Falls für einen Raum keine Korrektur * definiert ist, wird der globale Standardwert (config.taupunktTempCorrection) verwendet. * * Formel: * T_corr = T + taupunktTempCorrection * γ = ln(RH/100) + (17.67 * T_corr) / (243.5 + T_corr) * Taupunkt = (243.5 * γ) / (17.67 - γ) * * @param {number} T - Gemessene Temperatur in °C. * @param {number} RH - Relative Luftfeuchte in %. * @param {number} tauCorrection - Temperaturkorrektur (in °C) für die Taupunktberechnung. * @returns {number} Berechneter Taupunkt in °C. */ function calcDewPoint(T, RH, tauCorrection) { var T_corr = T + tauCorrection; var gamma = Math.log(RH / 100) + (17.67 * T_corr) / (243.5 + T_corr); var dewPoint = (243.5 * gamma) / (17.67 - gamma); return dewPoint; } // ============================= // Funktion: checkSensorAge // ============================= /** * Prüft, ob ein Sensor seit mehr als der konfigurierten Zeit (in Stunden) keinen neuen Wert gesendet hat. * * Falls der Sensor zu alt ist, wird eine Warnung mit grafischer Kennzeichnung (⚠️) im Debug-Log ausgegeben. * * @param {object} sensorState - Der Zustand des Sensors, der u.a. den Zeitstempel (ts) enthalten sollte. * @param {string} sensorName - Bezeichner des Sensors, der in der Warnung angezeigt wird. */ function checkSensorAge(sensorState, sensorName) { if (config.sensorAgeCheck && config.sensorAgeCheck.enabled && sensorState && sensorState.ts) { var now = Date.now(); var age = (now - sensorState.ts) / 3600000; // Zeitdifferenz in Stunden if (age > config.sensorAgeCheck.maxAgeHours) { if (config.debug) { log("⚠️⚠️⚠️ Sensor " + sensorName + " hat seit " + age.toFixed(2) + " Stunden keinen neuen Wert gesendet!", "warn"); } } } } // ============================= // Funktion: runCalculation // ============================= /** * Führt die vollständige Berechnung der Lüftungsempfehlungen durch. * * Ablauf: * 1. Außensensoren auslesen, optional auf Verfügbarkeit und Sensoralter prüfen. * 2. Berechne die absolute Luftfeuchte für die Außenluft (AH_out). * Optional: Speichere AH_out in den entsprechenden Zieldatenpunkten. * 3. Für jeden aktivierten Raum: * a. Raum-Sensoren (Temperatur und RH) auslesen, optional auf Verfügbarkeit und Sensoralter prüfen. * b. Berechne die absolute Luftfeuchte im Raum (AH_in) und den Taupunkt (Raum). * Dabei wird für die Taupunktberechnung die temperaturbezogene Korrektur (raumbezogen oder global) angewendet. * c. Optional: Speichere AH_in und den Taupunkt in den entsprechenden Zieldatenpunkten. * d. Falls aktiviert: Vergleiche den gemessenen RH-Wert mit dem Schwellenwert und speichere das Ergebnis in fixedDP. * e. Falls aktiviert: Vergleiche AH_in mit AH_out (plus Offset) und speichere das Ergebnis in reduceDP. * * Bei fehlenden kritischen Sensoren wird die Berechnung (bzw. für den Raum) abgebrochen. */ function runCalculation() { // Außensensoren auslesen var outsideTempState = getState(config.outside.temp); var outsideRHState = getState(config.outside.rh); var outsidePressureState = getState(config.outside.pressure); // Optionale Prüfung der Außensensoren (Verfügbarkeit) if (config.enableSensorCheck) { var missingOutsideSensors = []; if (!outsideTempState) missingOutsideSensors.push("Außentemperatur (" + config.outside.temp + ")"); if (!outsideRHState) missingOutsideSensors.push("Außen RH (" + config.outside.rh + ")"); if (!outsidePressureState) missingOutsideSensors.push("Außen Druck (" + config.outside.pressure + ")"); if (missingOutsideSensors.length > 0) { log("Fehlende Außensensoren: " + missingOutsideSensors.join(", "), "warn"); } } // Sensor-Alter-Prüfung für Außensensoren if (config.sensorAgeCheck && config.sensorAgeCheck.enabled) { checkSensorAge(outsideTempState, config.outside.temp); checkSensorAge(outsideRHState, config.outside.rh); checkSensorAge(outsidePressureState, config.outside.pressure); } // Falls kritische Außensensoren fehlen, wird die Berechnung abgebrochen. if (!outsideTempState || !outsideRHState || !outsidePressureState) { log("Kritische Außensensoren nicht vollständig verfügbar! Berechnung wird abgebrochen.", "error"); return; } // Umwandlung der Außensensorwerte in Zahlen und Berechnung von AH_out var outsideTemp = parseFloat(outsideTempState.val); var outsideRH = parseFloat(outsideRHState.val); var outsidePressure = parseFloat(outsidePressureState.val); var AH_out = calcAbsoluteHumidity(outsideTemp, outsideRH, outsidePressure); // Debug-Ausgabe für Außensensoren if (config.debug) { log("Außenwerte: Temp=" + outsideTemp + "°C, RH=" + outsideRH + "%, Druck=" + outsidePressure + " hPa, AH_out=" + AH_out.toFixed(2) + " g/m³", "info"); } // Optionale Speicherung der absoluten Luftfeuchte für außen (Aussen-Nord) if (config.saveAbsoluteHumidity) { setState(config.outside.absDP, AH_out, true); if (config.debug) log("Absolute Luftfeuchte außen gespeichert in " + config.outside.absDP + ": " + AH_out.toFixed(2) + " g/m³", "info"); } // Hinweis: Der Taupunkt für außen wird bewusst nicht berechnet. // Iteration über alle Räume for (var roomName in config.rooms) { var room = config.rooms[roomName]; if (!room.enabled) { if (config.debug) log("Raum " + roomName + " ist deaktiviert.", "info"); continue; } // Raum-Sensoren auslesen var indoorTempState = getState(room.indoorTemp); var indoorRHState = getState(room.indoorRH); // Optionale Prüfung der Raum-Sensoren (Verfügbarkeit) if (config.enableSensorCheck) { var missingRoomSensors = []; if (!indoorTempState) missingRoomSensors.push("Temperatur (" + room.indoorTemp + ")"); if (!indoorRHState) missingRoomSensors.push("Luftfeuchte (" + room.indoorRH + ")"); if (missingRoomSensors.length > 0) { log("Fehlende Sensoren für " + roomName + ": " + missingRoomSensors.join(", "), "warn"); } } // Sensor-Alter-Prüfung für Raum-Sensoren if (config.sensorAgeCheck && config.sensorAgeCheck.enabled) { checkSensorAge(indoorTempState, room.indoorTemp + " in " + roomName); checkSensorAge(indoorRHState, room.indoorRH + " in " + roomName); } // Falls kritische Raum-Sensoren fehlen, wird der Raum übersprungen. if (!indoorTempState || !indoorRHState) { if (config.debug) log("Berechnung für " + roomName + " wird übersprungen, da Sensoren fehlen.", "warn"); continue; } // Umwandlung der Raumwerte in Zahlen und Berechnung von AH_in var indoorTemp = parseFloat(indoorTempState.val); var indoorRH = parseFloat(indoorRHState.val); var AH_in = calcAbsoluteHumidity(indoorTemp, indoorRH); // Optionale Speicherung der absoluten Luftfeuchte im Raum if (config.saveAbsoluteHumidity && room.absDP) { setState(room.absDP, AH_in, true); if (config.debug) log("Absolute Luftfeuchte in " + roomName + " gespeichert in " + room.absDP + ": " + AH_in.toFixed(2) + " g/m³", "info"); } // Berechnung des Taupunkts im Raum: // Für die Berechnung wird die temperaturbezogene Korrektur verwendet, die für den Raum separat definiert sein kann. var tauCorrection = (typeof room.taupunktTempCorrection !== 'undefined') ? room.taupunktTempCorrection : config.taupunktTempCorrection; var taupunkt = calcDewPoint(indoorTemp, indoorRH, tauCorrection); if (config.saveDewPoint && room.taupunktDP) { setState(room.taupunktDP, taupunkt, true); if (config.debug) log("Taupunkt in " + roomName + " gespeichert in " + room.taupunktDP + ": " + taupunkt.toFixed(2) + " °C", "info"); } // ----------------------------- // Feste Schwellenwert-Berechnung (Fixed Calculation) // ----------------------------- if (config.enableFixedCalculation) { var threshold = (room.threshold !== null) ? room.threshold : config.globalRHThreshold; var fixedRecommendation = (indoorRH >= threshold); setState(room.fixedDP, fixedRecommendation, true); if (config.debug) { log("[" + roomName + "] Fixed Calculation: RH_in=" + indoorRH + "%, Threshold=" + threshold + " -> Empfehlung Lüften: " + fixedRecommendation, "info"); } } // ----------------------------- // Berechnung, ob Lüften die absolute Luftfeuchte senken kann (Absolute Humidity Calculation) // ----------------------------- if (config.enableAbsoluteHumidityCalculation) { var reduceRec = (AH_in > (AH_out + config.absoluteHumidityOffset)); setState(room.reduceDP, reduceRec, true); if (config.debug) { log("[" + roomName + "] Absolute Humidity Calculation: AH_in=" + AH_in.toFixed(2) + " g/m³, AH_out=" + AH_out.toFixed(2) + " g/m³, Offset=" + config.absoluteHumidityOffset + " -> Lüften senkt Luftfeuchte: " + reduceRec, "info"); } } } } // ============================= // Zeitgesteuerte Ausführung (Scheduling) // ============================= // // Ausführung im Tag-/Nachtmodus: // - Zwischen 06:00 und 22:59 alle 10 Minuten // - Zwischen 23:00 und 05:59 alle 30 Minuten // Beim Laden des Skripts wird runCalculation() initial aufgerufen. // Von 06:00 bis 22:59 alle 10 Minuten: schedule("*/10 6-22 * * *", function() { runCalculation(); if (config.debug) log("runCalculation ausgelöst (10-Minuten-Intervall)", "info"); }); // Von 23:00 bis 05:59 alle 30 Minuten: schedule("*/30 23,0-5 * * *", function() { runCalculation(); if (config.debug) log("runCalculation ausgelöst (30-Minuten-Intervall)", "info"); }); // Initialer Aufruf beim Laden des Skripts: runCalculation();
Skript um die Datenpunkte für die Taupunkte hinzu zufügen:
/** * Skript: Anlage der Zieldatenpunkte für Taupunkte * * Beschreibung: * Dieses Skript erstellt automatisch alle Zieldatenpunkte für die Taupunkte in den einzelnen Räumen. * Der Datenpunktpfad entspricht dem Muster: * * 0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt.<Raumname> * * Die zugehörigen Optionen lauten: * - name: "<Raumname>-Taupunkt" * - type: "number" * - read: true * - write: true * - def: 0 * * Falls ein Datenpunkt bereits existiert, wird er nicht erneut erstellt. */ // Liste der Raumbezeichnungen, für die ein Taupunkt-Datenpunkt angelegt werden soll. var rooms = [ "Wohnzimmer", "Arbeitszimmer", "Badezimmer", "Buegelzimmer", "Essflur", "Schlafzimmer", "Waschkueche", "GG-Kueche", "GG-Schlafzimmer", "GG-Wohnzimmer", "GG-Bad" ]; // Optionale Debug-Ausgabe (true = ausführliche Logmeldungen) var debug = true; /** * Erstellt einen Datenpunkt, falls dieser noch nicht existiert. * * @param {string} dp - Der vollständige Datenpunktpfad. * @param {object} options - Optionen für den Datenpunkt, z.B.: * { name: "<Raumname>-Taupunkt", type: "number", read: true, write: true, def: 0, unit: °C } */ function createTargetState(dp, options) { if (!existsState(dp)) { // Datenpunkt anlegen und initial auf den Default-Wert setzen. createState(dp, options.def, { name: options.name, type: options.type, read: options.read, write: options.write }); if (debug) log("Datenpunkt erstellt: " + dp, "info"); } else { if (debug) log("Datenpunkt existiert bereits: " + dp, "info"); } } // Iteriere über alle Räume und erstelle die entsprechenden Taupunkt-Datenpunkte. rooms.forEach(function(roomName) { var dpPath = "0_userdata.0.EigeneDatenpunkte.Raumklima.Taupunkt." + roomName; var options = { name: roomName + "-Taupunkt", type: "number", read: true, write: true, def: 0 }; createTargetState(dpPath, options); }); log("Anlage der Zieldatenpunkte für Taupunkte abgeschlossen.", "info");
-
@homoran
Wie erkennst du das gekippte Fenster?
Arbeite selber mit den Aqara Sensoren, die können es so nicht, oder ich müsste ggf. einen zweiten je Fenster hinzufügen - dafür bin ich allerdings zu kniepig. -
@gismoh sagte in JS für Überwachung der Luftfeuchtigkeit in Räumen:
Wie erkennst du das gekippte Fenster?
Homematic Drehgriffsensoren!
-
-
Entweder mit einem Sensor direkt am Griff, dann kann man aber auch nicht sicher sein, ob das Fenster gekippt ist oder nur die Stellung des Griffs zutrifft.
-
Oder aber mit zwei Sensoren an einem kippbaren Fenster (sicherste Lösung).
-
Oder, da gekippte Fenster ohnehin sinnfrei sind, weil ein gekipptes Fenster immer im kriminalistischen Sinn offen ist, einfach die Kippfunktion deaktivieren und das Umfeld auf Stoßlüftung einschwören.
-
-
Der zweite Punkt ist mir aktuell nicht nur zu teuer, sondern auch zu unansehnlich (zwei Sensoren am Fenster).
Die Sensoren für den ersten Punkt muss ich mir noch ansehen.
Beim dritten Punkt musste ich gerade laut lachen....
Wo meine Schwiegereltern noch die alten Fenster hatten, wo es einen separaten Hebel für die Kippfunktion gab,
hatte ich denen diesen einfach an alle Fenster demontiert.
Diese waren zwar am schimpfen über mich, ABER, hatten seit dem keinen Schimmel mehr an den Fenster Laibungen XD -
@meister-mopper sagte in JS für Überwachung der Luftfeuchtigkeit in Räumen:
- Oder aber mit zwei Sensoren an einem kippbaren Fenster (sicherste Lösung).
Alternativ Shelly BLU Door/Window. Die haben Neigungswinkelmessung, über die Kipp erkannt wird und zusätzlich auch noch Helligkeit mit an Bord.
-
@samson71
Die Shelly´s würden mir ganz gut gefallen, wenn se nicht über Bluetooth gehen würden. Gerade die braune Version würde passen. Hoffentlich bringen se dies auch noch z.B. mit Zigbee raus. -
@gismoh
Du musst dafür im ioBroker direkt kein BT haben. Die kannst Du über BT z.B. an einen Shelly PM o.ä. koppeln. Darüber bekommst die dann zu fassen. Vorteil von den Dingern ist die günstige und langlebige CR2032 Batterie. Das hat mich bisher an den klassischen Batterie Aktoren von Shelly gestört. Die laufen meist nur mit den relativ teuren CR123 und direkt erhältlich sind sie auch nicht überall, wenn man mal akut eine braucht. -
@homoran sagte in JS für Überwachung der Luftfeuchtigkeit in Räumen:
@gismoh sagte in JS für Überwachung der Luftfeuchtigkeit in Räumen:
Momentan füge ich noch den Taupunkt hinzu, um zu warnen, wann es zu Schimmel kommen kann - so zumindest die Idee.
hast du den nicht schon in den Rechnungen drin?
für die Werkstatt hab ich noch zusätzlich den "Taupunkt" für 80% und 70% Feuchte, da dies eigentlich schon die Grenzwerte für Schimmelbildung sind
Hi, welches Widget hast Du für die Anzeige Ja/nein beim lüften genutzt.
Bekomme es einfach nicht hin mit dem Text bzw finde wohl nicht das Richtige.EDIT: hat sich erledigt, habe es hinbekommen