SK951 Skrevet 11. februar 2019 Skrevet 11. februar 2019 Hei, har diverse RF og Z-wave sensorer i leiligheten (bla. Fibaro, Multisensor 6 og en rekke Clas/biltema RF-sensorer). Problemet er at disse viser ulike temperaturer, og nå vet jeg egentlig ikke helt hvilke jeg skal stole på. Har prøvd å legge alle ved hverandre og valgte deretter en tilfeldig sensor som referanse (som da ble Multisensor). Differansen mellom dem øker dog nokså mye utover døgnet. Nå har jeg til eks. 18.4, 18.1 og 14.7 i samme rom (noe ulik høyde på disse, men ikke nok til å forsvare differansen på nesten 4 grader). Forslag til termometer jeg kan bruke til referanse? Hvordan har dere løst dette? Hva med posisjonen på sensoren? Siter
Armas Skrevet 12. februar 2019 Skrevet 12. februar 2019 Jeg styrte med det samme for en tid siden. Mitt inntrykk er at temperatursensorene er nokså unøyaktige. Jeg satte flere multisensorer, phillips hue sensorer og diverse 433mhz sensorer på samme sted i ett varmt rom. Store avvik (flere grader) Regnet ut gjennomsnitt og kalibrerte alle så de hadde lik temperatur. Deretter flyttet jeg alle til ett kladt rom. På nytt store avvik. Endte med å gi opp og godta ett visst avvik. De sensorene som skal være i varme rom, kalibrerte jeg på ca 22 grader, mens de som skal være i kjeller kalibrerte jeg på ca 15 grader. Siter
HSv Skrevet 12. februar 2019 Skrevet 12. februar 2019 Jeg sliter med det samme - jeg har åpen løsning med stue, gang og kjøkken og jeg mener jeg har 8 sensorer tilsammen som gir meg temperatur. Jeg endte med å skrive et script som gir meg en snitt-temperatur av disse, og som også tar hensyn til om noen av de går offline eller har for gamle verdier. Jeg bruker det samme scriptet for utetemperatur - der har jeg vel tre sensorer på forskjellige sider av huset. Scriptet skriver til to virtuelle devicer i HomeSeer, som igjen kan brukes som input til andre ting. Dersom det er noen interesse for det kan jeg se om jeg ikke får lagt ut scriptet her. 3 Siter
Armas Skrevet 12. februar 2019 Skrevet 12. februar 2019 16 minutter siden, HSv skrev: Jeg sliter med det samme - jeg har åpen løsning med stue, gang og kjøkken og jeg mener jeg har 8 sensorer tilsammen som gir meg temperatur. Jeg endte med å skrive et script som gir meg en snitt-temperatur av disse, og som også tar hensyn til om noen av de går offline eller har for gamle verdier. Jeg bruker det samme scriptet for utetemperatur - der har jeg vel tre sensorer på forskjellige sider av huset. Scriptet skriver til to virtuelle devicer i HomeSeer, som igjen kan brukes som input til andre ting. Dersom det er noen interesse for det kan jeg se om jeg ikke får lagt ut scriptet her. Det ville vært interessant. Blir i så fall mitt første script i HS, og det synes jeg det er på høy tid at jeg forsøker meg på. Siter
HSv Skrevet 12. februar 2019 Skrevet 12. februar 2019 (endret) Min versjon brukes til å beregne både innendørs og utendørs temperatur - derfor vil du finne variabler "Indoor...." og "Outdoor..." Du trenger ikke bruke begge, siden de blir kalt med forskjellige input parameter. Advarsel: dette er ikke helt plug&play, men jeg har forsøkt å gjøre det litt brukervennlig iallefall. Det kreves at du vet hvordan du legger inn et script, og litt om hvordan du editerer det for å tilpasses ditt bruk. Det er testet på Linux, og ikke forsøkt kjørt på Windows. Du kan først lage ett virtuelt device som du får gjennomsnittstemperaturen skrevet ut til. (Du kan gjerne lage to - ett for Standard avviket også, dersom du ønsker det - men det er ikke nødvendig) Det er forsåvidt ikke påkrevd å ha noe "out-device" - i så fall skrives det bare ut i loggen. Sett son "Status Only Device" (ikke påkrevd - bare for å unngå å få "kontroller-knapper") Noter deg "Reference ID" - dette skal du legge inn i scriptet Formatere output. Og slik startes scriptet - knock yourself out med andre triggere om du vil ? Spoiler ' TempAverager.vb, v. 1.2 ' Input param: location, as defined further down the script. ' In this example location can be "indoor" or "outdoor" ' HSv, Feb. 2019 Public module GlobalVars public shared infoLog as boolean = true ' Log whats happening...? public shared warnLog as boolean = true ' Log warnings...? (you really should!) public shared debugLog as boolean = false ' Log a bit more...? end module public sub Main(ByVal _params as Object) ' Enter the device ref. for the sensors you want to use, ' and enter a calibration value if needed: ' '0' means the thermometer is ~correct ' '-1' means it seems to show 1 deg more than the actual temperature ' '0.5' means it seems to show half a deg less than the actual temperature ' The script demands that you enter the parameters, one for each sensor, even if it is zero. ' On a general note - be careful to use calibrations, unless you are quite sure it is valid. ' After all - this script is meant to average out several un-certain values :-) dim location as string = _params.Tostring dim Sensor() as integer ' ref ID for temp. sensors, as found in HomeSeer dim Calibr() as integer ' Calibration for each sensor. dim devAvg as integer ' ref ID for Average tenp dev. (0 means don't save to any device) dim devStdev as integer ' ref ID for StDev (0 means don't save to any device) dim LogID as string ' Identifier for the log dim oldish as integer ' mins - how old before we only let it count half? (0 means use all data) dim tooOld as integer ' mins - how old before we scrap the data? (0 means use all data) ' When input parameter = "indoor"A (i.e. location is "indoor") dim IndoorSensor() as integer = { 85, 80, 739, 745, 742, 754, 704, 940} dim IndoorCalibr() as integer = {-0.7, -0.5, 0, 0, 0, 0, 0, 0} dim IndoordevAvg as integer = 951 dim IndoordevStdev as integer = 0 dim IndoorLogID as string = "Indoor Temp" dim Indooroldish as integer = 60 dim IndoortooOld as integer = 120 ' When input parameter = "outdoor" dim OutdoorSensor() as integer = { 874, 494, 748} dim OutdoorCalibr() as integer = { 0, 0, 0} dim OutdoordevAvg as integer = 978 dim OutdoordevStdev as integer = 0 dim OutdoorLogID as string = "Outdoor Temp" dim Outdooroldish as integer = 60 dim OutdoortooOld as integer = 120 select case location case "indoor" Sensor = IndoorSensor Calibr = IndoorCalibr devAvg = IndoordevAvg devStdev = IndoordevStdev LogID = IndoorLogID oldish = Indooroldish tooOld = IndoortooOld case "outdoor" Sensor = OutdoorSensor Calibr = OutdoorCalibr devAvg = OutdoordevAvg devStdev = OutdoordevStdev LogID = OutdoorLogID oldish = Outdooroldish tooOld = OutdoortooOld case else Logging("Temp. averager", "warn", "Location '" & location & "' does not exist") exit sub end select ' Info: 85 = Living room thermostat ' 80 = Hallway thermostat ' 739 = Sensor 433 Stue 1 Temp. ' 745 = Sensor 433 Stue 2 Temp. ' 742 = Sensor 433 Kjøkken Temp. ' 754 = Living room Couch/TV Sensor ' 704 = Kitchen sensor ' 940 = Bookshelf sensor ' 874 = Backyard sensor ' 494 = Entrance sensor ' 748 = Sensor 433 Back yard ' 1019 = WeatherXML, St. Johannes ' --------------------------------------------------- ' There should not be anything to change below here ' --------------------------------------------------- ' Negative time...? You ain't Cristopher Lloyd! ' ...or more than i year(ish)...? - I consider that "all sensors at all times" if (oldish < 0) orelse (oldish > 530000) then oldish = 0 if (tooOld < 0) orelse (tooOld > 530000) then tooOld = 0 if (oldish > tooOld) andalso (tooOld > 0) then oldish = tooOld ' A few declarations dim numSensors as integer = Sensor.GetLength(0) dim Temp(numSensors) as decimal dim LastUpd as DateTime dim deviceName as string dim averageTemp as decimal = -1 dim StandardDev as decimal = -1 dim sumTemp as decimal dim sumDeviation as decimal dim samples as decimal ' Collect data ' -------------------------------------------------------------- ' Loop through all the sensors for i as integer = 0 to (numSensors - 1) if hs.DeviceExistsRef(Sensor(i)) then Temp(i) = hs.DeviceValueEx(Sensor(i)) + Calibr(i) ' DeviceValueEx gives me the decimal value :-) dim currentTemp as string = Temp(i).ToString dim LastUpd as DateTime = hs.DeviceLastChangeRef(Sensor(i)) ' What time was the dev. last updated? dim timeDiff as TimeSpan = (Date.Now - LastUpd) ' ...how long ago is that? dim addonText as string ' Prettify the timediff - i.e. remove everything after the last ".", which are millisecs dim myts as string = timeDiff.ToString dim timestring as string = myts.Substring(0, myts.LastIndexOf(".")) ' Check if it is too long since the device-value was updated if (timeDiff.TotalSeconds > tooOld*60) andalso (tooOld > 0) then ' Too old? - junk it! addonText = "Age: " & timestring & " > " & tooOld & " min. - Disqualified" Temp(i) = -1000 else if (timeDiff.TotalSeconds > oldish*60) andalso (oldish > 0) then ' Almost too old? addonText = "Age: " & timestring & " > " & oldish & " min. - half weight" sumTemp += (Temp(i) / 2) samples += 0.5 else ' Not old at all :-) addonText = "Age: " & timestring sumTemp += Temp(i) samples += 1 end if ' Do we want detailed logging...? deviceName = hs.GetDeviceByRef(Sensor(i)).name(hs) Logging(LogID, "debug", "Device " & Sensor(i) & ", " & deviceName & ": " & currentTemp & "°C - " & addonText) else Logging(LogID, "warn", "Device " & Sensor(i) & " does not exist") end if next ' Data in 'da house - lets do the math and show what we got! ' -------------------------------------------------------------- ' Avearege - do we have any data to calculate it? if samples > 0 then ' Average temperature (with 2 decimals) ' but don't write it to the device yet, as we want to calculate StDev first averageTemp = Math.Round((sumTemp / samples), 2) ' Do some calculations for the StDev. dim counter as integer = 0 for i as integer = 0 to (numSensors - 1) if Temp(i) > -1000 then sumDeviation += (Temp(i) - averageTemp)^2 counter += 1 end if next ' Standard deviation - but only if there is any data if counter > 0 then ' Standard deviation (with two decimals) StandardDev = Math.Round(Math.Sqrt(sumDeviation / counter), 2) ' write the standard deviation to the StDev device - if we have one defined and it exists if devStdev = 0 then Logging(LogID, "debug", "No device defined for StDev") else if (not hs.DeviceExistsRef(devStdev)) then Logging(LogID, "warn", "StDev device " & devStdev & " does not exist") else hs.SetDeviceValueByRef(devStdev, CStr(StandardDev), True) end if end if else Logging(LogID, "warn", "Not enough valid data to calculate StDev") end if ' Write average to the device - if there is an existing device defined. ' (... now that we also have the StDev and can make a proper deviceString) dim devString as string = averageTemp & "°C (StDev: " & StandardDev & "°C - " & samples & " samples)" if devAvg = 0 then Logging(LogID, "warn", "No device defined for average temp") else if (not hs.DeviceExistsRef(devAvg)) then Logging(LogID, "warn", "Avg.temp device " & devAvg & " does not exist") else hs.SetDeviceValueByRef(devAvg, CStr(averageTemp), True) hs.SetDevicestring(devAvg, CStr(devString), True) end if end if ' Do we want any logging? Logging(LogID, "debug", "Sum: " & sumTemp & " - Samples: " & samples ) Logging(LogID, "info", devString) else Logging(LogID, "warn", "Not enough valid data to calculate average temp") end if end sub ' Routine for writing to the log Sub Logging(ByVal LogID as string, ByVal msgType as String, ByVal msg as string) dim msgComplete as string dim writetolog as boolean = false select case msgType case "info" if GlobalVars.infoLog then msgComplete = "Info: " & msg writetolog = true end if case "debug" if GlobalVars.debugLog then msgComplete = "Debug: " & msg writetolog = true end if case "warn" if GlobalVars.warnLog then msgComplete = "Warning: " & msg writetolog = true end if case else msgComplete = "Msgtype '" & msgType & "' undefined" writetolog = true end select if writetolog then hs.Writelog (LogID, msgComplete) end sub ' That's all folks! Til slutt må du editere scriptet, slik at du bruker de Ref. ID som gjelder for dine sensorer. Du kan bruke så mange eller så få du vil - du bare forlenger/forkorter array'ene som det passer. Du kan også legge inn andre verdier for når du vil tillegge sensoren halv vekt, og for når du vil forkaste verdien. Jeg håper dette kan være til hjelp for noen, og at beskrivelsen/forklaringen min ikke er helt på bærtur. Koden er helt sikkert ikke optimal, men det får stå sin prøve. Utregningen av standardavvik er heller ikke helt korrekt, men "riktig nok" for mitt bruk. For ordens skyld - jeg bruker ikke noe device for standardavvik, og derfor er refID der satt til null. Om du ønske, så lager du en device og legger inn refID i stedet for null. Endret 12. februar 2019 av HSv "Clearification" :-) 3 Siter
HSv Skrevet 12. februar 2019 Skrevet 12. februar 2019 All tilbakemelding blir satt veldig stor pris på - det er kun et par uker siden jeg begynte å kode i VB så jeg vet at koden ikke er optimal. Siter
Moskus Skrevet 12. februar 2019 Skrevet 12. februar 2019 Hvis du ikke har prøvd det enda, så anbefales tenScripting for Visual Studio. Full intellisense når man programmerer er veldig hendig. (Og så får man automatisk stor i i Integer, etc ) Siter
Anbefalte innlegg
Bli med i samtalen
Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.