HSv Skrevet 10. oktober 2022 Skrevet 10. oktober 2022 (endret) Her er et par script som henter data fra TibberSeer devicer, og estimerer strømstøtten MTD. Det første scriptet henter verdien fra TibberSeer devices “Price Today TextSummary” og “Price Tomorrow TextSummary” og skriver disse til filer (en fil for hver dag). Folder/directory hvor du vil lagre disse må du lage selv, og du må oppdatere variabelen “baseDir” i begge scriptene. Det andre scriptet bruker output fra det første til å regne ut estimert strømstøtte, og skrive verdier til flere devicer i HomeSeer. Scriptet er laget for å regne ut: Estimated Actual Price = Price Current Price + Nettleie - Estimated Strømstøtte (Nettleien er gjeldende for Lyse Lnett og må justeres om du har en annen nettleverandør) En ulempe er at dette scriptet må ha input fra hele måneden (dvs. fra den 1ste frem til i dag eller i morgen) for å fungere. Det finnes en workaround til dette, og det skal jeg beskrive i en senere post. En annen ulempe er at det er laget for å beregne nettleien fra Lyse og vil ikke fungere riktig med andre nettleverandører. Det finnes «sort of» workaround for dette oss - se en senere post. For å bruke det må du lage noen devicer manuelt: - Average Powerprice - Estimated Actual Price - Estimated Strømstøtte - Nettleie - energiledd - Today Estimated Actual Price TextSummary - Tomorrow Estimated Actual Price TextSummary (Jeg vet - dårlige navn - men de kan du endre som du vil. Det er Device Ref. scriptene forholder seg til. I tillegg brukes disse devicene fra TibberSeer: - Price Current Price - Price Today TextSummary - Price Tomorrow TextSummary Scriptene kjører for meg på Ubuntu 20.04, HomeSeer 4.2.16. Det er ikke testet på Windows. Kopier begge scriptene til ditt script-directory under HomeSeer, og sørg for at de er kjørbare. (chmod a+x i Linux) For å kjøre scriptene så lager du en event: IF TibberSeer TibberSeer Price Root Price Current Price just had its value set or changed. THEN Wait 1 Minute, 0 Seconds Run the script: Strompris_collect.vb and wait for the command to finish before continuing, and also only allow one instance of the script to run at a time. Run the script: Strompris_calculate.vb and wait for the command to finish before continuing, and also only allow one instance of the script to run at a time. (Grunnen til "wait 1 minute" er for å gi alle TibberSeer-devicene tid til å oppdateres- det greier seg sikkert med mye kortere tid uten at jeg har testet det) Strompris_collect.vb har to parameter, begge kommer fra TibberSeer, og adskilt med «:»: Device ref. Til «Price Today TextSummary» Device ref. Til «Price Tomorrow TextSummary» Strompris_calculate.vb har hele 7 parameter: Average Powerprice Estimated Strømstøtte Price Current Price (som next før - dette er en device fra TibberSeer) Estimated Actual Price Nettleie - energiledd Today Estimated Actual Price TextSummary Tomorrow Estimated Actual Price TextSummary Alle disse devicene (bortsett fra «Price Current Price») må du som sagt lage selv. Strompris_collect.vb Spoiler ' Strompris_collect.vb , v. 1.0 ' ' This script collects data from two of TibberSeer's devices and ' creates files to be used by Strompris_calculate.vb ' The scripts both relies heavily on TibberSeer and are designed to use ' with Lyse Lnett's nettleie ' ' HSv, Oct. 2022 ' ' Parameters (All are Device ref's): ' 0 - PricesTodayTSDev - to read the TextSummary of todays prices ' 1 - PricesTomorrowTSDev - to read the TextSummary of tomorrows prices Public Class 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 Class Public Sub Main(ByVal _params As Object) Imports System.Text.RegularExpressions Dim LogID As String = "EL Collect" ' Do we have the correct nubmer of parameters? Dim l As Integer = _params.Split(":").Length If l <> 2 Then Logging(LogID, "warn", "Wrong # of params- Is " & l & ", Should be 2. Aborting!") Exit Sub End If Dim PricesTodayTSDev As Integer = Integer.parse(_params.ToString.split(":")(0)) Dim PricesTomorrowTSDev As Integer = Integer.parse(_params.ToString.split(":")(1)) Dim Devices() As Integer = {PricesTodayTSDev, PricesTomorrowTSDev} ' Does the devices exist? For Each dev As Integer In {PricesTodayTSDev, PricesTomorrowTSDev} If Not hs.DeviceExistsRef(dev) Then Logging(LogID, "warn", "Device " & dev & " does not exist. Aborting!") Exit Sub End If Next Dim baseDir As String = "/backup/strompriser/" Dim today As Datetime = DateTime.Now Dim tomorrow As Datetime = DateAdd("d",1,today) Dim todaystr As String = today.ToString("yyyy-MM-dd") Dim tomorrowstr As String = tomorrow.ToString("yyyy-MM-dd") Dim currentDate As String = todaystr If Not System.IO.Directory.Exists(basedir) Then Logging(LogID, "warn", "Output directory " & baseDir & " does not exist. Aborting!") Exit Sub End If ' Loop over both input parameters For Each dev As Integer In {PricesTodayTSDev, PricesTomorrowTSDev} Dim deviceName = hs.GetDeviceByRef(dev).name(hs) If deviceName.Contains("Today") Then currentDate = todaystr Else currentDate = tomorrowstr End If Dim outFile As String = baseDir & currentDate ' Empty the ouputfile before trying to write to it If System.IO.File.Exists(outFile) Then System.IO.File.WriteAllText(outFile, "") End If ' Read the full HTML content from the input device Dim TextSummaryHTML As String = hs.DeviceString(dev) ' Has Tomorrows prices been updated yet ? If Not TextSummaryHTML.Contains("Tomorrows prices are usually") Then ' Remove HTML tags Dim TextSummary As String = StripTags(TextSummaryHTML) For i = 0 To 23 ' Read each element, using the string "øre" as delimiter Dim entry As String = TextSummary.split("øre")(i) ' Then split each element into a time- and price-tag Dim entrytime As String = entry.split(":")(0) Dim entryprice As Double = entry.split(":")(1) ' Put it all together in a formatted fashion, and write it to file Dim outstring As String = currentDate & "T" & entrytime & " " & entryprice & Environment.NewLine My.Computer.Filesystem.WriteAllText(outFile, outstring, True) Next ' Just some fancy info-logging Logging(LogID, "info", deviceName.Split(" ")(0) & " " & deviceName.Split(" ")(1) & " collected") Else Logging(LogID, "warn" , "Tomorrows prices not yet updated") End If Next Exit Sub End Sub Function StripTags(ByVal html As String) As String ' Remove HTML tags. html = Regex.Replace(html, "<.*?>", "") Return Regex.Replace(html, " ", "") End Function ' 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! Stromstotte_calculate.vb Spoiler ' Strompris_calculate.vb , v. 1.0 ' ' This script uses the output from Strompris_collect.vb, and calculates ' Month-to-date Strømstøtte. This is again used in company with ' TibberSeer's TextSummary devices to populate devices for the best estimate of ' today and tomorrow's "true" prices. (ie. Price + Nettleie - Assumed Stømstøtte) ' The scripts both relies heavily on TibberSeer and are designed to use ' with Lyse Lnett's nettleie ' ' HSv, Oct. 2022 ' ' Parameters (All are Device ref's): ' 0 - AverageDev - store average MTD price ' 1 - StotteDev - store estimated 'Stømstøtte' ' 2 - nowPriceDev - read current price (This is a device from TibberSeer) ' 3 - EstPriceDev - store current estimated (prcie + nettleie - strømstøtte) ' 4 - NettleieDev - store current nettleie ' 5 - EstTodayTSDev - store Todays estimated price TextSummary ' 6 - EstTomorrowTSDev - store Tomorrows estimated price TextSummary Public Class GlobalVars Public Shared infoLog As Boolean = True ' Log what's happening...? Public Shared warnLog As Boolean = True ' Log warnings...? (you really should!) Public Shared debugLog As Boolean = False ' Log a bit more...? End Class Public Sub Main(ByVal _params As Object) Imports System.IO Dim LogID As String = "EL Calculate" ' Do we have the correct nubmer of parameters? Dim l As Integer = _params.Split(":").Length If l <> 7 Then Logging(LogID, "warn", "Wrong # of params- Is " & l & ", Should be 7. Aborting!") Exit Sub End If Dim AverageDev As Integer = Integer.parse(_params.ToString.split(":")(0)) Dim StotteDev As Integer = Integer.parse(_params.ToString.split(":")(1)) Dim nowPriceDev As Integer = Integer.parse(_params.ToString.split(":")(2)) Dim EstPriceDev As Integer = Integer.parse(_params.ToString.split(":")(3)) Dim NettleieDev As Integer = Integer.parse(_params.ToString.split(":")(4)) Dim EstTodayTSDev As Integer = Integer.parse(_params.ToString.split(":")(5)) Dim EstTomorrowTSDev As Integer = Integer.parse(_params.ToString.split(":")(6)) ' We don't need to check all devices yet ' We can still do some calculations if the last two doesn't exist For Each dev As Integer In {AverageDev, StotteDev, nowPriceDev, EstPriceDev, NettleieDev} If Not hs.DeviceExistsRef(dev) Then Logging(LogID, "warn", "Device " & dev & " does not exist. Aborting!") Exit Sub End If Next ' Shall we calculate Støtte / Nettleie and write it back to 'StotteDev' / 'NettleieDev' (True) ' or just read a manually entered value from 'StotteDev' / 'NettleieDev' (False) Dim calcStøtte As Boolean = True Dim calcNettleie As Boolean = True ' Directory / folder where output files from Strompris_collect.vb are stored Dim baseDir As String = "/backup/strompriser/" Dim MVA As Double = 1.25 ' MVA / moms Dim fixedPart As Integer = 70 Dim prctPart As Double = 0.9 Dim nettleieHigh As Double = 48.6 Dim nettleieLow As Double = 40.6 ' These are Valid for Lyse Nett - Rewrite as needed Dim leieLowPeriods() As String = {"Saturday", "Sunday", "22", "23", "00", "01", "02", "03", "04", "05"} If Not System.IO.Directory.Exists(basedir) Then Logging(LogID, "warn", "Output directory " & baseDir & " does not exist. Aborting!") Exit Sub End If Dim thismonth As String = DateTime.Now.ToString("yyyy-MM") Dim numEntries As Integer = 0 Dim sumPrices As Double = 0 Dim nowPrice As Double = hs.DeviceValueEx(nowPriceDev) Dim redDot As String = "<img src='images/HomeSeer/status/red.png' width=12 height=12>" Dim yellowDot As String = "<img src='images/HomeSeer/status/yellow.png' width=12 height=12>" Dim greenDot As String = "<img src='images/HomeSeer/status/green.png' width=12 height=12>" Dim Average As Double = Nothing Dim Stotte As Double If Not calcStøtte Then ' You asked to read Strømstøtte instead of calculating it Stotte = hs.DeviceValueEx(StotteDev) Else ' Get a list of this month's files For Each fileName As String In Directory.GetFiles(basedir, thismonth+"*") Dim fileSize As Integer = System.IO.File.ReadAllText(fileName).Length Logging(LogID, "debug", fileName & " -> " & fileSize) ' Does the file contain any data? If fileSize > 0 Then Dim reader as StreamReader = My.Computer.FileSystem.OpenTextFileReader(fileName) Dim myline as String ' Assumption: If the file exist and contains data, ' it contains CORRECT data, and CORRECT formatted data! For i = 0 To 23 myline = reader.ReadLine If String.IsNullOrEmpty(myline) Then Exit For End If sumPrices = sumPrices + myline.split(" ")(1) numEntries = numEntries + 1 'Logging(LogID, "debug", myline) Next Logging(LogID, "debug", sumPrices & " - " & numEntries) reader.Close() End If Next ' Finally - done with the preparation and doing some math Average = Math.Round(sumPrices / numEntries, 2) Stotte = Math.Round((Average - (fixedPart * MVA)) * prctPart, 2) End If If Stotte < 0 Then ' We can never owe strømstøtte, right...? Stotte = 0 End If Dim nowNettleie as Double If Not calcNettleie Then ' You asked to read Nettleie instead of calculating it nowNettleie = hs.DeviceValueEx(NettleieDev) Else ' Calculate Nettleie for 'now' Dim TimeNow As Datetime = DateTime.Now Dim HourNow As String = TimeNow.Tostring("HH") Dim DayNow AS String = TimeNow.DayOfWeek.ToString ' High or Low nettleie ? If leieLowPeriods.Any(Function(s) DayNow.Contains(s)) Or leieLowPeriods.Any(Function(s) HourNow.Contains(s)) Then nowNettleie = nettleieLow Else nowNettleie = nettleieHigh End If End If ' And finally - Tadaaa... Dim nowEstPrice As Double = Math.Round(nowPrice + nowNettleie - Stotte, 2) ' Now write all these values to the correct HS Devices If calcStøtte Then hs.SetDeviceValueByRef(AverageDev, Average, True) hs.SetDeviceValueByRef(StotteDev, Stotte, True) End If If calcNettleie Then hs.SetDeviceValueByRef(NettleieDev, nowNettleie, True) End If hs.SetDeviceValueByRef(EstPriceDev, nowEstPrice, True) Logging(LogID, "info", "Average: " & Average & " | Est. Støtte: " & Stotte) Logging(LogID, "info", "Est. Price: " & nowEstPrice & " | Nettleie: " & nowNettleie) ' Ready for part Two ? ' OK - Now let's see if can make a TextSummary of the "true" powerprices. ' Now we need the last two devices For Each dev As Integer In {EstTodayTSDev, EstTomorrowTSDev} If Not hs.DeviceExistsRef(dev) Then Logging(LogID, "warn", "Device " & dev & " does not exist. Aborting!") Exit Sub End If Next Dim today As Datetime = DateTime.Now Dim tomorrow As Datetime = DateAdd("d",1,today) Dim todaystr As String = today.ToString("yyyy-MM-dd") Dim tomorrowstr As String = tomorrow.ToString("yyyy-MM-dd") Dim currentDate As String = todaystr ' Loop over Today's and Tomorrow's file For Each fileName As String in {todaystr, tomorrowstr} ' We need to find the Day of the week to apply the correct nettleie. Dim currentYear As Integer = fileName.Split("-")(0) Dim currentMonth As Integer = fileName.Split("-")(1) Dim currentDay As Integer = fileName.Split("-")(2) Dim DateString As String = currentYear & "/" & currentMonth & "/" & currentDay Dim d As DateTime = DateString Dim DOW As String = d.DayOfWeek.ToString Logging(LogID, "debug", DOW) ' Which device shall we write to in this iteration? Dim TextSumDev As Integer If fileName = todaystr Then TextSumDev = EstTodayTSDev Else TextSumDev = EstTomorrowTSDev End If ' Set the full path and filename Dim fullFilename As String = basedir & fileName If System.IO.File.Exists(fullFilename) Then Dim fileSize As Integer = System.IO.File.ReadAllText(fullFilename).Length Logging(LogID, "debug", fullFilename & " -> " & fileSize) ' Again we assume that if the file exist and contains data, ' it contains CORRECT data, and CORRECT formatted data! If fileSize > 0 Then Dim reader as StreamReader = My.Computer.FileSystem.OpenTextFileReader(fullFilename) Dim myline as String ' Prepare the string to write back to HomeSeer Dim OutString As String = "<table>" For i = 0 To 23 myline = reader.ReadLine If String.IsNullOrEmpty(myline) Then Exit For End If 'Logging(LogID, "debug", myline) Dim currentTime As String = myline.Split(" ")(0) Dim currentHour As String = currentTime.Split("T")(1) Dim currentPrice As Double = myline.Split(" ")(1) Dim currentNettleie As Double Dim NLS As String = Nothing If Not calcNettleie Then ' You asked to read Nettleie instead of calculating it currentNettleie = hs.DeviceValueEx(NettleieDev) Else ' High or Low nettleie ? If leieLowPeriods.Any(Function(s) DOW.Contains(s)) Or leieLowPeriods.Any(Function(s) currentHour.Contains(s)) Then currentNettleie = nettleieLow NLS = "(L)" Else currentNettleie = nettleieHigh NLS = "(H)" End If End If ' Finally - calculate the "assumed" true price Dim truePrice As Double = Math.Round(currentPrice - Stotte + currentNettleie, 2) ' Create the final fancy string - with HTML and bells and whistles :-) If i Mod 2 = 0 Then OutString = OutString & "<tr>" End If ' Add some fancy colored dots to the output Dim colorDot As String If truePrice > 20 Then colorDot = redDot Else If truePrice < 0 Then colorDot = greenDot Else colorDot = yellowdot End if OutString = OutString & "<td style='padding-right:15px'> " & colorDot & currentHour & ": " & truePrice & " øre" & NLS & "</td>" If i Mod 2 <> 0 Then OutString = OutString & "</tr>" End If Next OutString = OutString & "</table>" ' Write the finel HTML String to the correct device hs.SetDeviceString(TextSumDev, OutString, True) reader.Close() Else ' i.e. I haven't found the input file Logging(LogID, "warn", fullFilename & " is empty") hs.SetDeviceString(TextSumDev, "Tomorrows prices are usually updated around 12-13:00", True) End If Else ' i.e. I haven't found the input file Logging(LogID, "warn", fullFilename & " does not exist") hs.SetDeviceString(TextSumDev, "Tomorrows prices are usually updated around 12-13:00", True) End If Next Logging(LogID, "debug", "All done") 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! Endret 10. oktober 2022 av HSv 1 Siter
HSv Skrevet 10. oktober 2022 Forfatter Skrevet 10. oktober 2022 Merk at du bruker disse scriptene på eget ansvar. Det finnes ingen garanti at de virker, eller at de gir korrekt resultat. Strømstøtten kan uansett ikke beregnes nøyaktig før måneden er over - jeg prøver bare å regne den ut med de data som er tilgjengelig akkurat nå. Og det er ikke engang garantert at jeg gjør det riktig 🙂 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.