strips Skrevet 17. januar 2020 Skrevet 17. januar 2020 Akkurat ferdig testet et script for å styre vår Systemair SAVE VTR 300 via Modbus. Det er nok tråder om Modbus her at jeg gidder å snakke om det nå Scriptet leser to Netatmo innemoduler sin Co2, temp og relativ fuktighet. Ut i fra disse verdiene så settes aggregatet i auto som standard, crowded (party) eller refresh (boost) basert på noen grensetall. Takk til @Moskus og @Hillmar for formel for absolutt fuktighet Forenklede regler Brannalarm: TODO Hvis trykkvakt eller spesialmodus (kjøkkenhette, vedovn, sentralstøvsuger) er aktivert skal vi ikke endre noe. Hvis stue eller bad har for høy Co2 så øker luftmegden først til Crowded så Boost. Hvis bad har høyere absolutt fuktighet en stuen med en viss margin så økes luftmengden til Boost Hvis ingen av regelene over treffer eller Co2 er under en terskel så sett til Auto. For å bruke scriptet må du endre alle variablene i toppen som begynner med dev. Det er 3 regel-blokker lengre nede som dekker mitt behov og kan dupliseres for flere rom eller fjernes hvis man ikke har nok sensorer. Class VentilatorControl Public Sub Main(ByVal Parms As Object) Dim Debug As Boolean = True Dim logName As String = "VentilatorControl" Console.WriteLine("Started: " & logName) If Debug Then hs.WriteLog(logName, "Started") Dim fireAlarm As Boolean = False ' for the future when I get a fire alarm integrated Dim devBath1_RH As Integer = 820 ' netatmo bad innemodul Dim devBath1_T As Integer = 817 ' netatmo bad innemodul Dim devBath1_Co2 As Integer = 821 ' netatmo bad innemodul Dim devLivingRoom1_RH As Integer = 788 ' netatmo stue hovedmodul Dim devLivingRoom1_T As Integer = 783 ' netatmo stue hovedmodul Dim devLivingRoom1_Co2 As Integer = 787 ' netatmo stue hovedmodul Dim devVentModeGet As Integer = 774 ' systemair Modbus Dim devVentModeSet As Integer = 773 ' systemair Modbus Dim valueLivingRoom1_T As Double = hs.DeviceValueEx(devLivingRoom1_T) Dim valueLivingRoom1_Co2 As Integer = hs.DeviceValue(devLivingRoom1_Co2) Dim valueLivingRoom1_RH As Double = hs.DeviceValueEx(devLivingRoom1_RH) Dim valueLivingRoom1_AH As Double = AbsHumidity(valueLivingRoom1_RH, valueLivingRoom1_T) Dim valueBath1_T As Double = hs.DeviceValueEx(devBath1_T) Dim valueBath1_Co2 As Integer = hs.DeviceValue(devBath1_Co2) Dim valueBath1_RH As Double = hs.DeviceValueEx(devBath1_RH) Dim valueBath1_AH As Double = AbsHumidity(valueBath1_RH, valueBath1_T) Dim humidDeltaBath1 As Double = Math.Round(valueBath1_AH / valueLivingRoom1_AH, 2) Dim valueVentModeGet As Integer = hs.DeviceValue(devVentModeGet) Dim ventModeGetCodeArray(12) As String ventModeGetCodeArray(0) = "Auto" ventModeGetCodeArray(1) = "Manual" ventModeGetCodeArray(2) = "Crowded" ventModeGetCodeArray(3) = "Refresh" ventModeGetCodeArray(4) = "Fireplace" ventModeGetCodeArray(5) = "Away" ventModeGetCodeArray(6) = "Holiday" ventModeGetCodeArray(7) = "Cooker Hood" ventModeGetCodeArray(8) = "Vacuum Cleaner" ventModeGetCodeArray(9) = "CDI1" ventModeGetCodeArray(10) = "CDI2" ventModeGetCodeArray(11) = "CDI3" ventModeGetCodeArray(12) = "PressureGuard" Dim ventModeSetCodeArray(7) As String ventModeSetCodeArray(0) = "None" ventModeSetCodeArray(1) = "Auto" ventModeSetCodeArray(2) = "Manual" ventModeSetCodeArray(3) = "Crowded" ventModeSetCodeArray(4) = "Refresh" ventModeSetCodeArray(5) = "Fireplace" ventModeSetCodeArray(6) = "Away" ventModeSetCodeArray(7) = "Holiday" ' Co2 threshold levels have a severity of 3 levels Dim co2ThresholdNormal As Integer = 550 ' less than Dim co2ThresholdHigh As Integer = 700 ' higher than Dim co2ThresholdMax As Integer = 900 ' higher than ' relative humididy threshold levels have a severity of 2 levels Dim humidDeltaThresholdNormal As Double = 1.1 ' less than Dim humidDeltaThresholdHigh As Double = 1.4 ' hihger than If Debug Then hs.WriteLog(logName, "valueLivingRoom1_T: " & valueLivingRoom1_T) If Debug Then hs.WriteLog(logName, "valueLivingRoom1_Co2: " & valueLivingRoom1_Co2) If Debug Then hs.WriteLog(logName, "valueLivingRoom1_RH: " & valueLivingRoom1_RH) If Debug Then hs.WriteLog(logName, "valueLivingRoom1_AH: " & valueLivingRoom1_AH) If Debug Then hs.WriteLog(logName, "valueBath1_T: " & valueBath1_T) If Debug Then hs.WriteLog(logName, "valueBath1_Co2: " & valueBath1_Co2) If Debug Then hs.WriteLog(logName, "valueBath1_RH: " & valueBath1_RH) If Debug Then hs.WriteLog(logName, "valueBath1_AH: " & valueBath1_AH) If Debug Then hs.WriteLog(logName, "humidDeltaBath1: " & humidDeltaBath1) If Debug Then hs.WriteLog(logName, "Current Ventilator Mode: " & ventModeGetCodeArray(valueVentModeGet)) If Debug Then hs.WriteLog(logName, "co2ThresholdNormal: " & co2ThresholdNormal) If Debug Then hs.WriteLog(logName, "co2ThresholdHigh: " & co2ThresholdHigh) If Debug Then hs.WriteLog(logName, "co2ThresholdMax: " & co2ThresholdMax) ' assign index from ventModeSetCodeArray Dim normalVentilatorGetMode As Integer = Array.IndexOf(ventModeGetCodeArray, "Auto") Dim normalVentilatorSetMode As Integer = Array.IndexOf(ventModeSetCodeArray, "Auto") Dim highVentilatorGetMode As Integer = Array.IndexOf(ventModeGetCodeArray, "Crowded") Dim highVentilatorSetMode As Integer = Array.IndexOf(ventModeSetCodeArray, "Crowded") Dim maxVentilatorGetMode As Integer = Array.IndexOf(ventModeGetCodeArray, "Refresh") Dim maxVentilatorSetMode As Integer = Array.IndexOf(ventModeSetCodeArray, "Refresh") Dim ventilatorSetLevel As Integer Dim ventilatorSetModeArray(3) As String ventilatorSetModeArray(1) = "Auto" ventilatorSetModeArray(2) = "Crowded" ventilatorSetModeArray(3) = "Refresh" If (fireAlarm) Then ' If fire alarm is true we stop ventilator or set it to minimum ' TODO identify best setting to disable the ventilator ' set mode manual ' set manual fan level to hs.WriteLog(logName, "Firealarm not implemented. Ventilator is in " & ventModeGetCodeArray(valueVentModeGet) & " mode.") ElseIf (valueVentModeGet >= Array.IndexOf(ventModeGetCodeArray, "Cooker Hood")) Then ' If ventilator is in get mode 7 (Cooker Hood) or higher we do nothing because the system is not in balance hs.WriteLog(logName, "Ventilator is in " & ventModeGetCodeArray(valueVentModeGet) & " mode, we do nothing!") Else ' Always start with normal as default level ventilatorSetLevel = 1 ' Co2 in living room 1 If (valueLivingRoom1_Co2 > co2ThresholdMax) And (ventilatorSetLevel < 3) Then ventilatorSetLevel = 3 If Debug Then hs.WriteLog(logName, "If (valueLivingRoom1_Co2 > co2ThresholdMax) And (ventilatorSetLevel < 3) Then, setting ventilatorSetMode to " & ventilatorSetLevel) ElseIf (valueLivingRoom1_Co2 > co2ThresholdHigh) And (ventilatorSetLevel < 2) Then ventilatorSetLevel = 2 If Debug Then hs.WriteLog(logName, "ElseIf (valueLivingRoom1_Co2 > co2ThresholdHigh) And (ventilatorSetLevel < 2) Then, setting ventilatorSetMode to " & ventilatorSetLevel) ElseIf (valueLivingRoom1_Co2 <= co2ThresholdNormal) And (ventilatorSetLevel = 1) Then If Debug Then hs.WriteLog(logName, "ElseIf (valueLivingRoom1_Co2 <= co2ThresholdNormal) And (ventilatorSetLevel = 1) Then, ventilatorSetLevel = 1") End If ' Co2 in bath 1 If (valueBath1_Co2 > co2ThresholdMax) And (ventilatorSetLevel < 3) Then ventilatorSetLevel = 3 If Debug Then hs.WriteLog(logName, "If (valueBath1_Co2 > co2ThresholdMax) And (ventilatorSetLevel < 3) Then, setting ventilatorSetMode to " & ventilatorSetLevel) ElseIf (valueBath1_Co2 > co2ThresholdHigh) And (ventilatorSetLevel < 2) Then ventilatorSetLevel = 2 If Debug Then hs.WriteLog(logName, "ElseIf (valueBath1_Co2 > co2ThresholdHigh) And (ventilatorSetLevel < 2) Then, setting ventilatorSetMode to " & ventilatorSetLevel) ElseIf (valueBath1_Co2 <= co2ThresholdNormal) And (ventilatorSetLevel = 1) Then If Debug Then hs.WriteLog(logName, "ElseIf (valueBath1_Co2 <= co2ThresholdNormal) And (ventilatorSetLevel = 1) Then, ventilatorSetLevel = 1") End If ' humidity in bath 1 If (humidDeltaBath1 > humidDeltaThresholdHigh) And (ventilatorSetLevel < 3) Then ventilatorSetLevel = 3 If Debug Then hs.WriteLog(logName, "If (humidDeltaBath1 > humidDeltaThresholdHigh) And (ventilatorSetLevel < 3) Then, setting ventilatorSetMode to " & ventilatorSetLevel) ElseIf (humidDeltaBath1 <= humidDeltaThresholdNormal) And (ventilatorSetLevel = 1) Then If Debug Then hs.WriteLog(logName, "ElseIf (humidDeltaBath1 <= humidDeltaThresholdNormal) And (ventilatorSetLevel = 1) Then, ventilatorSetLevel = 1") End If ' If the current ventilator mode is at the same mode/level we want to set then we do not have to do anything If (ventModeGetCodeArray(valueVentModeGet) = ventilatorSetModeArray(ventilatorSetLevel)) Then If Debug Then hs.WriteLog(logName, "ventModeGetCodeArray(valueVentModeGet) = " & ventModeGetCodeArray(valueVentModeGet)) If Debug Then hs.WriteLog(logName, "ventilatorSetModeArray(ventilatorSetLevel) = " & ventilatorSetModeArray(ventilatorSetLevel)) If Debug Then hs.WriteLog(logName, "If (ventModeGetCodeArray(valueVentModeGet) [" & ventModeGetCodeArray(valueVentModeGet) & "] = ventilatorSetModeArray(ventilatorSetLevel)[" & ventilatorSetModeArray(ventilatorSetLevel) & "] ) Then, no changes in ventilatorSetMode") Else ' Set ventilator device devVentModeSet to index of ventModeSetCodeArray where value is ventilatorSetLevel translated thru ventModeSetCodeArray If Debug Then hs.WriteLog(logName, "If Not (ventModeGetCodeArray(valueVentModeGet) [" & ventModeGetCodeArray(valueVentModeGet) & "] = ventilatorSetModeArray(ventilatorSetLevel)[" & ventilatorSetModeArray(ventilatorSetLevel) & "] ) Then, set ventilator to " & ventilatorSetModeArray(ventilatorSetLevel)) If Debug Then hs.WriteLog(logName, "ventilatorSetLevel = " & ventilatorSetLevel) If Debug Then hs.WriteLog(logName, "ventilatorSetModeArray(ventilatorSetLevel) = " & ventilatorSetModeArray(ventilatorSetLevel)) If Debug Then hs.WriteLog(logName, "before set devVentModeSet to " & Array.IndexOf(ventModeSetCodeArray, ventilatorSetModeArray(ventilatorSetLevel))) If Debug Then hs.WriteLog(logName, "hs.CAPIControlHandler(hs.CAPIGetSingleControl(" & devVentModeSet & ", True, " & ventilatorSetModeArray(ventilatorSetLevel) & ", False, False))") hs.CAPIControlHandler(hs.CAPIGetSingleControl(devVentModeSet, True, ventilatorSetModeArray(ventilatorSetLevel), False, False)) hs.WriteLog(logName, "set devVentModeSet to " & Array.IndexOf(ventModeSetCodeArray, ventilatorSetModeArray(ventilatorSetLevel))) End If End If End Sub Function AbsHumidity(ByVal relHumidity As Double, ByVal temp As Double) As Double ' Formula found here: ' https://www.hjemmeautomasjon.no/forums/topic/5896-konvertere-fra-relativ-til-absolutt-luftfuktighet/?do=findComment&comment=68448 AbsHumidity = Math.Round(6.112 * Math.E ^ ((17.67 * temp) / (temp + 243.5)) * relHumidity * 2.1674 / (273.15 + temp), 2) End Function End Class Siter
Moskus Skrevet 17. januar 2020 Skrevet 17. januar 2020 Kan jeg komme med et forbedringsforslag? One-line IF er utmerket for kun én linje, men blir veldig uoversiktelig når den skal dekke flere (samt at det teknisk sett krever mer regnekraft, selv om det er ubetydelig nå om dagen). Jeg hadde mao. skrevet den siste IF-setningen slik: ' If the current ventilator mode is at the same mode/level we want to set then we do not have to do anything If (ventModeGetCodeArray(valueVentModeGet) = ventilatorSetModeArray(ventilatorSetLevel)) Then If Debug Then hs.WriteLog(logName, "ventModeGetCodeArray(valueVentModeGet) = " & ventModeGetCodeArray(valueVentModeGet)) hs.WriteLog(logName, "ventilatorSetModeArray(ventilatorSetLevel) = " & ventilatorSetModeArray(ventilatorSetLevel)) hs.WriteLog(logName, "If (ventModeGetCodeArray(valueVentModeGet) [" & ventModeGetCodeArray(valueVentModeGet) & "] = ventilatorSetModeArray(ventilatorSetLevel)[" & ventilatorSetModeArray(ventilatorSetLevel) & "] ) Then, no changes in ventilatorSetMode") End If Else ' Set ventilator device devVentModeSet to index of ventModeSetCodeArray where value is ventilatorSetLevel translated thru ventModeSetCodeArray If Debug Then hs.WriteLog(logName, "If Not (ventModeGetCodeArray(valueVentModeGet) [" & ventModeGetCodeArray(valueVentModeGet) & "] = ventilatorSetModeArray(ventilatorSetLevel)[" & ventilatorSetModeArray(ventilatorSetLevel) & "] ) Then, set ventilator to " & ventilatorSetModeArray(ventilatorSetLevel)) hs.WriteLog(logName, "ventilatorSetLevel = " & ventilatorSetLevel) hs.WriteLog(logName, "ventilatorSetModeArray(ventilatorSetLevel) = " & ventilatorSetModeArray(ventilatorSetLevel)) hs.WriteLog(logName, "before set devVentModeSet to " & Array.IndexOf(ventModeSetCodeArray, ventilatorSetModeArray(ventilatorSetLevel))) hs.WriteLog(logName, "hs.CAPIControlHandler(hs.CAPIGetSingleControl(" & devVentModeSet & ", True, " & ventilatorSetModeArray(ventilatorSetLevel) & ", False, False))") End If hs.CAPIControlHandler(hs.CAPIGetSingleControl(devVentModeSet, True, ventilatorSetModeArray(ventilatorSetLevel), False, False)) hs.WriteLog(logName, "set devVentModeSet to " & Array.IndexOf(ventModeSetCodeArray, ventilatorSetModeArray(ventilatorSetLevel))) End If Det samme med linjene over: If Debug Then hs.WriteLog(logName, "valueLivingRoom1_T: " & valueLivingRoom1_T) hs.WriteLog(logName, "valueLivingRoom1_Co2: " & valueLivingRoom1_Co2) hs.WriteLog(logName, "valueLivingRoom1_RH: " & valueLivingRoom1_RH) hs.WriteLog(logName, "valueLivingRoom1_AH: " & valueLivingRoom1_AH) hs.WriteLog(logName, "valueBath1_T: " & valueBath1_T) hs.WriteLog(logName, "valueBath1_Co2: " & valueBath1_Co2) hs.WriteLog(logName, "valueBath1_RH: " & valueBath1_RH) hs.WriteLog(logName, "valueBath1_AH: " & valueBath1_AH) hs.WriteLog(logName, "humidDeltaBath1: " & humidDeltaBath1) hs.WriteLog(logName, "Current Ventilator Mode: " & ventModeGetCodeArray(valueVentModeGet)) hs.WriteLog(logName, "co2ThresholdNormal: " & co2ThresholdNormal) hs.WriteLog(logName, "co2ThresholdHigh: " & co2ThresholdHigh) hs.WriteLog(logName, "co2ThresholdMax: " & co2ThresholdMax) End If Siter
Guahtdim Skrevet 17. januar 2020 Skrevet 17. januar 2020 Hvis du skal ha det enda mer oversiktlig så pakker du slike ting inn i sub rutiner med godt beskrivende navn If (ventModeGetCodeArray(valueVentModeGet) = ventilatorSetModeArray(ventilatorSetLevel)) Then WriteDebugForVentilatorSetModeArray(Debug) Else ' Set ventilator device devVentModeSet to index of ventModeSetCodeArray where value is ventilatorSetLevel translated thru ventModeSetCodeArray WriteDebugForTheOtherStuff(Debug) ' Det underliggende kunne også trekkes ut som en egen godt beskrevet sub hs.CAPIControlHandler(hs.CAPIGetSingleControl(devVentModeSet, True, ventilatorSetModeArray(ventilatorSetLevel), False, False)) hs.WriteLog(logName, "set devVentModeSet to " & Array.IndexOf(ventModeSetCodeArray, ventilatorSetModeArray(ventilatorSetLevel))) End If .. .. .. Sub WriteDebugForVentilatorSetModeArray(Debug as bool) If Debug Then hs.WriteLog(logName, "ventModeGetCodeArray(valueVentModeGet) = " & ventModeGetCodeArray(valueVentModeGet)) hs.WriteLog(logName, "ventilatorSetModeArray(ventilatorSetLevel) = " & ventilatorSetModeArray(ventilatorSetLevel)) hs.WriteLog(logName, "If (ventModeGetCodeArray(valueVentModeGet) [" & ventModeGetCodeArray(valueVentModeGet) & "] = ventilatorSetModeArray(ventilatorSetLevel)[" & ventilatorSetModeArray(ventilatorSetLevel) & "] ) Then, no changes in ventilatorSetMode") End If End Sub Sub WriteDebugForTheOtherStuff(Debug as bool) If Debug Then hs.WriteLog(logName, "If Not (ventModeGetCodeArray(valueVentModeGet) [" & ventModeGetCodeArray(valueVentModeGet) & "] = ventilatorSetModeArray(ventilatorSetLevel)[" & ventilatorSetModeArray(ventilatorSetLevel) & "] ) Then, set ventilator to " & ventilatorSetModeArray(ventilatorSetLevel)) hs.WriteLog(logName, "ventilatorSetLevel = " & ventilatorSetLevel) hs.WriteLog(logName, "ventilatorSetModeArray(ventilatorSetLevel) = " & ventilatorSetModeArray(ventilatorSetLevel)) hs.WriteLog(logName, "before set devVentModeSet to " & Array.IndexOf(ventModeSetCodeArray, ventilatorSetModeArray(ventilatorSetLevel))) hs.WriteLog(logName, "hs.CAPIControlHandler(hs.CAPIGetSingleControl(" & devVentModeSet & ", True, " & ventilatorSetModeArray(ventilatorSetLevel) & ", False, False))") End If End Sub Siter
strips Skrevet 17. januar 2020 Forfatter Skrevet 17. januar 2020 Takker for tips @Moskus og @Guahtdim Enig at det er penere og kjappere med en if (debug) men etter hvet som de vokste ble det sånn. Så er det veldig praktisk å bare lime inn en linje og endre teksten. Så det er med overlegg one-linere. Mulig det hadde blitt mer oversiktlig med sub-rutiner. Men for et så lite script er det lite vits. VB.Net er kun noe jeg tar i fordi jeg må. Skulle helst gjort dette i C# og øvd meg på det men er så få eksempler på C#-kode for Homeseer. Ellers hjelper det å bruke Visual Studio med tenScripting for debugging. Siter
Guahtdim Skrevet 17. januar 2020 Skrevet 17. januar 2020 (endret) C# script motoren i HomeSeer er så dårlig så det er lettere å gjøre ting i vbscript. Jeg prøvde lenge med C# script, men ga etterhvert opp. Etter å ha gravd litt så fant jeg ut at de hadde implementert en veldig gammel motor. Og siden de ikke bruker den selv så tviler jeg på at de stresser så mye over at det er kronglete. Det gjør litt vondt de gangene jeg må inn og scripte, men det gjør enda mer vondt å prøve å få det til i CS-Script (https://www.cs-script.net/) Endret 17. januar 2020 av Guahtdim 1 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.